diff --git a/web_src/src/components/node-search.tsx b/web_src/src/components/node-search.tsx index 2a5a51e02..b054a7298 100644 --- a/web_src/src/components/node-search.tsx +++ b/web_src/src/components/node-search.tsx @@ -6,6 +6,7 @@ import { BuiltInEdge, useReactFlow, type Node, type PanelProps } from "@xyflow/r import { CommandDialog, CommandGroup, CommandInput, CommandItem, CommandList } from "@/components/ui/command"; import { Button } from "@/components/ui/button"; import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; +import { resolveIcon } from "@/lib/utils"; export interface NodeSearchProps extends Omit { // The function to search for nodes, should return an array of nodes that match the search string @@ -18,6 +19,32 @@ export interface NodeSearchProps extends Omit { onOpenChange?: (open: boolean) => void; } +// Helper function to extract icon slug from node data +function getNodeIconSlug(node: Node): string { + const nodeType = node.data?.type as string | undefined; + const isAnnotationNode = nodeType === "annotation"; + + if (isAnnotationNode) { + return "sticky-note"; + } + + // Try to get icon from component/trigger/composite data + if (nodeType === "component" && node.data.component) { + return (node.data.component as { iconSlug?: string }).iconSlug || "box"; + } + + if (nodeType === "trigger" && node.data.trigger) { + return (node.data.trigger as { iconSlug?: string }).iconSlug || "play"; + } + + if (nodeType === "composite" && node.data.composite) { + return (node.data.composite as { iconSlug?: string }).iconSlug || "boxes"; + } + + // Default fallback + return "box"; +} + export function NodeSearchInternal({ onSearch, onSelectNode, open, onOpenChange }: NodeSearchProps) { const [searchResults, setSearchResults] = useState([]); const [searchString, setSearchString] = useState(""); @@ -81,11 +108,27 @@ export function NodeSearchInternal({ onSearch, onSelectNode, open, onOpenChange const fallbackLabel = (node.data as { nodeName?: string })?.nodeName || (node.data as { label?: string })?.label; const displayLabel = isAnnotationNode ? "Note" : fallbackLabel || node.id; + const iconSlug = getNodeIconSlug(node); + const IconComponent = resolveIcon(iconSlug); + return ( onSelect(node)}> -
- {displayLabel} - {node.id} +
+ + + + {displayLabel} + + {displayLabel.length > 40 && {displayLabel}} + + + + + {node.id} + + + {node.id.length > 25 && {node.id}} +
); @@ -123,7 +166,7 @@ export function NodeSearch({ onSearch, onSelectNode }: NodeSearchProps) { Search components (Ctrl/Cmd + K) - + @@ -136,7 +179,7 @@ export interface NodeSearchDialogProps extends NodeSearchProps { export function NodeSearchDialog({ onSearch, onSelectNode, open, onOpenChange }: NodeSearchDialogProps) { return ( - + );