import { useMemo, useState } from "react"; import { Input, Modal } from "antd"; import { BookOpenText, FileText, Image, Pencil, Search, Video } from "lucide-react"; import { WorkspaceState } from "@/components/layout/workspace-state"; import { CanvasNodeType, type CanvasNodeData } from "@/types/canvas"; export function CanvasNodeSearchModal({ open, nodes, onClose, onFocus }: { open: boolean; nodes: CanvasNodeData[]; onClose: () => void; onFocus: (nodeId: string) => void }) { const [query, setQuery] = useState(""); const results = useMemo(() => { const keyword = query.trim().toLocaleLowerCase(); if (!keyword) return nodes.slice(0, 40); return nodes.filter((node) => [node.title, node.type, nodeTypeLabel(node.type), node.metadata?.prompt, node.metadata?.composerContent, node.metadata?.model, node.metadata?.chapterTitle, node.metadata?.workflowTitle, node.metadata?.workflowDescription, typeof node.metadata?.shotIndex === "number" ? `镜头 ${node.metadata.shotIndex + 1}` : "", ...(node.metadata?.assetTags || [])] .some((value) => typeof value === "string" && value.toLocaleLowerCase().includes(keyword))).slice(0, 80); }, [nodes, query]); return ( setQuery("")} centered> setQuery(event.target.value)} prefix={} placeholder="搜索节点、章节、镜头、模型或标签" /> {results.length ? results.map((node) => ( { onFocus(node.id); onClose(); }} > {node.type === CanvasNodeType.Image ? : node.type === CanvasNodeType.Video ? : node.type === CanvasNodeType.Drawing ? : } {node.title} {node.metadata?.chapterTitle ? : null} {nodeContextLabel(node)} )) : } ); } function nodeContextLabel(node: CanvasNodeData) { const location = [node.metadata?.chapterTitle, typeof node.metadata?.shotIndex === "number" ? `镜头 ${node.metadata.shotIndex + 1}` : ""].filter(Boolean).join(" · "); return location || node.metadata?.prompt || node.metadata?.composerContent || node.metadata?.workflowDescription || nodeTypeLabel(node.type); } function nodeTypeLabel(type: CanvasNodeType) { return ({ [CanvasNodeType.Image]: "图片节点", [CanvasNodeType.Text]: "文本节点", [CanvasNodeType.Drawing]: "绘图节点", [CanvasNodeType.Script]: "分镜脚本节点", [CanvasNodeType.Skill]: "技能节点", [CanvasNodeType.Config]: "生成配置节点", [CanvasNodeType.Video]: "视频节点", [CanvasNodeType.Audio]: "音频节点", [CanvasNodeType.Frame]: "背板", } as Record)[type] || "未知节点"; }