fix(canvas): 提示词优化器 - 隔离多实例浮层定位并修复路由预加载测试
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
"dev": "vite --host 0.0.0.0 --port 3000",
|
||||
"build": "tsc --noEmit && vite build",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"test": "bun test test/api-request.test.ts test/video-api-contracts.test.ts test/image-api-contracts.test.ts test/channel-model-catalog.test.ts test/model-protocols.test.ts test/agent-prompt-cache.test.ts test/canvas-agent-context.test.ts test/canvas-batch-connection.test.ts test/canvas-character-reference.test.ts test/canvas-document.test.ts test/canvas-drawing-engine.test.ts test/canvas-emotion-edit-plan.test.ts test/canvas-extension-nodes.test.ts test/canvas-folder.test.ts test/canvas-generation-layout.test.ts test/canvas-image-batch-retry.test.ts test/canvas-leafer-viewport.test.ts test/canvas-local-runtime.test.ts test/canvas-model-policy.test.ts test/canvas-resource-mention-editor.test.ts test/canvas-resource-references.test.ts test/canvas-storyboard-assets.test.ts test/canvas-storyboard-references.test.ts test/canvas-node-config-reset.test.ts test/canvas-node-registry.test.ts test/canvas-video-regeneration.test.ts test/canvas-video-timeline-segments.test.ts test/create-canvas-handoff.test.ts test/create-library-button.test.ts test/creation-references.test.ts test/generation-asset-repository.node.test.ts test/generation-storage-consistency.test.ts test/generation-task-durability.node.test.ts test/generation-task-local.test.ts test/generation-task-materializer.test.ts test/task-media-fallback.test.ts test/user-scoped-generation-persistence.test.ts test/local-channel-permission.test.ts test/local-channel-runtime-projection.node.test.mjs test/local-channel-task-center.node.test.mjs test/local-channel-ui.node.test.mjs test/local-cli-settings.test.ts test/local-dreamina-cli.test.ts test/local-dreamina-generation.test.ts test/local-dreamina-model-catalog.test.ts test/local-runtime-bootstrap.test.ts test/local-runtime-connection.test.ts test/local-runtime.test.ts test/client-id.test.ts test/grok-image-prompt-limit.test.ts test/image-resolution-tiers.test.ts test/gemini-image.test.ts test/libtv-import.test.ts test/timeline-to-ffmpeg.test.ts test/canvas-video-segment-args.test.ts test/tapnow-import.test.ts && bun test test/local-dreamina-cross-runtime.test.ts",
|
||||
"test": "bun test test/api-request.test.ts test/video-api-contracts.test.ts test/image-api-contracts.test.ts test/channel-model-catalog.test.ts test/model-protocols.test.ts test/agent-prompt-cache.test.ts test/canvas-agent-context.test.ts test/canvas-batch-connection.test.ts test/canvas-character-reference.test.ts test/canvas-document.test.ts test/canvas-drawing-engine.test.ts test/canvas-emotion-edit-plan.test.ts test/canvas-extension-nodes.test.ts test/canvas-folder.test.ts test/canvas-generation-layout.test.ts test/canvas-image-batch-retry.test.ts test/canvas-leafer-viewport.test.ts test/canvas-local-runtime.test.ts test/canvas-model-policy.test.ts test/canvas-resource-mention-editor.test.ts test/canvas-resource-references.test.ts test/canvas-storyboard-assets.test.ts test/canvas-storyboard-references.test.ts test/canvas-node-config-reset.test.ts test/canvas-node-registry.test.ts test/canvas-video-regeneration.test.ts test/canvas-video-timeline-segments.test.ts test/create-canvas-handoff.test.ts test/create-library-button.test.ts test/creation-references.test.ts test/generation-asset-repository.node.test.ts test/generation-storage-consistency.test.ts test/generation-task-durability.node.test.ts test/generation-task-local.test.ts test/generation-task-materializer.test.ts test/task-media-fallback.test.ts test/user-scoped-generation-persistence.test.ts test/local-channel-permission.test.ts test/local-channel-runtime-projection.node.test.mjs test/local-channel-task-center.node.test.mjs test/local-channel-ui.node.test.mjs test/local-cli-settings.test.ts test/local-dreamina-cli.test.ts test/local-dreamina-generation.test.ts test/local-dreamina-model-catalog.test.ts test/local-runtime-bootstrap.test.ts test/local-runtime-connection.test.ts test/local-runtime.test.ts test/client-id.test.ts test/grok-image-prompt-limit.test.ts test/image-resolution-tiers.test.ts test/gemini-image.test.ts test/libtv-import.test.ts test/timeline-to-ffmpeg.test.ts test/canvas-video-segment-args.test.ts test/tapnow-import.test.ts test/prompt-optimizer-drawer.test.ts && bun test test/local-dreamina-cross-runtime.test.ts",
|
||||
"start": "vite preview --host 0.0.0.0 --port 3000",
|
||||
"format": "prettier --write .",
|
||||
"format:check": "prettier --check ."
|
||||
|
||||
@@ -101,6 +101,7 @@ export function CanvasPromptOptimizerDrawer({ open, children, prompt, generation
|
||||
const { message } = App.useApp();
|
||||
const abortRef = useRef<AbortController | null>(null);
|
||||
const chatRef = useRef<HTMLDivElement | null>(null);
|
||||
const contentRef = useRef<HTMLDivElement | null>(null);
|
||||
const [mode, setMode] = useState<PromptOptimizationMode>("expand");
|
||||
const [activeOptimizerModel, setActiveOptimizerModel] = useState("");
|
||||
const [draftPrompt, setDraftPrompt] = useState(prompt);
|
||||
@@ -176,7 +177,7 @@ export function CanvasPromptOptimizerDrawer({ open, children, prompt, generation
|
||||
}, [open]);
|
||||
|
||||
const syncPanelPositionToViewport = useCallback(() => {
|
||||
const popoverRoot = document.querySelector<HTMLElement>(".canvas-prompt-optimizer-popover");
|
||||
const popoverRoot = contentRef.current?.closest<HTMLElement>(".canvas-prompt-optimizer-popover");
|
||||
if (!popoverRoot) return;
|
||||
|
||||
const rect = popoverRoot.getBoundingClientRect();
|
||||
@@ -381,7 +382,7 @@ export function CanvasPromptOptimizerDrawer({ open, children, prompt, generation
|
||||
};
|
||||
|
||||
const nudgePanel = (deltaX: number, deltaY: number) => {
|
||||
const popoverRoot = document.querySelector<HTMLElement>(".canvas-prompt-optimizer-popover");
|
||||
const popoverRoot = contentRef.current?.closest<HTMLElement>(".canvas-prompt-optimizer-popover");
|
||||
if (!popoverRoot) {
|
||||
setPanelOffset((current) => ({ x: current.x + deltaX, y: current.y + deltaY }));
|
||||
return;
|
||||
@@ -622,7 +623,7 @@ export function CanvasPromptOptimizerDrawer({ open, children, prompt, generation
|
||||
} as CSSProperties;
|
||||
|
||||
const content = (
|
||||
<div className={`canvas-prompt-optimizer-panel${panelInteracting ? " is-interacting" : ""}`} data-canvas-no-zoom>
|
||||
<div ref={contentRef} className={`canvas-prompt-optimizer-panel${panelInteracting ? " is-interacting" : ""}`} data-canvas-no-zoom>
|
||||
<div
|
||||
className="canvas-prompt-optimizer-header"
|
||||
onPointerDown={(event) => {
|
||||
|
||||
14
web/test/prompt-optimizer-drawer.test.ts
Normal file
14
web/test/prompt-optimizer-drawer.test.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import { readFileSync } from "node:fs";
|
||||
import { resolve } from "node:path";
|
||||
|
||||
const source = readFileSync(resolve(import.meta.dir, "../src/components/canvas/canvas-prompt-optimizer-drawer.tsx"), "utf8");
|
||||
|
||||
describe("prompt optimizer drawer instance isolation", () => {
|
||||
test("resolves the popover from the current drawer content instead of the first global match", () => {
|
||||
expect(source).toContain("const contentRef = useRef<HTMLDivElement | null>(null);");
|
||||
expect(source).toContain('contentRef.current?.closest<HTMLElement>(".canvas-prompt-optimizer-popover")');
|
||||
expect(source).toContain('<div ref={contentRef} className={`canvas-prompt-optimizer-panel');
|
||||
expect(source).not.toContain('document.querySelector<HTMLElement>(".canvas-prompt-optimizer-popover")');
|
||||
});
|
||||
});
|
||||
@@ -19,13 +19,14 @@ describe("workspace route loading", () => {
|
||||
|
||||
test("preloads the reported workspace routes before navigation", () => {
|
||||
const modules = source("../src/lib/workspace-route-modules.ts");
|
||||
const navigation = source("../src/components/layout/app-top-nav.tsx");
|
||||
const navigation = source("../src/components/layout/workspace-sidebar-nav.tsx");
|
||||
|
||||
for (const route of ["projects", "canvas", "assets", "wallet", "create"]) {
|
||||
expect(modules).toContain(`${route}: () => import`);
|
||||
}
|
||||
expect(navigation).toContain("onPointerEnter={() => preloadWorkspaceRoute(tool.slug)}");
|
||||
expect(navigation).toContain("onFocus={() => preloadWorkspaceRoute(tool.slug)}");
|
||||
expect(navigation).toContain("onPointerEnter={() => preloadWorkspaceRoute(linkTo)}");
|
||||
expect(navigation).toContain("onPointerDown={() => preloadWorkspaceRoute(linkTo)}");
|
||||
expect(navigation).toContain("onFocus={() => preloadWorkspaceRoute(linkTo)}");
|
||||
});
|
||||
|
||||
test("uses a quiet workspace skeleton for initial hydration", () => {
|
||||
|
||||
Reference in New Issue
Block a user