diff --git a/src/components/layout/search-results-panel.tsx b/src/components/layout/search-results-panel.tsx index fdcd6f5..dc42cf2 100644 --- a/src/components/layout/search-results-panel.tsx +++ b/src/components/layout/search-results-panel.tsx @@ -1,6 +1,6 @@ "use client" -import { useState } from "react" +import { useState, useMemo } from "react" import { X, CircleDot } from "lucide-react" import { ScrollArea } from "@/components/ui/scroll-area" import { Separator } from "@/components/ui/separator" @@ -15,6 +15,21 @@ import type { SchemaNode } from "@/app/ontology/page" const DISPLAY_KEY_FALLBACKS = ["name", "title", "label", "text", "content", "body"] as const +function buildDepthMap(schemas: SchemaNode[]): Map { + const parentMap = new Map(schemas.map((s) => [s.type, s.parent])) + const cache = new Map() + + function getDepth(type: string): number { + if (cache.has(type)) return cache.get(type)! + const parent = parentMap.get(type) + const depth = !parent || parent === "" ? 0 : getDepth(parent) + 1 + cache.set(type, depth) + return depth + } + schemas.forEach((s) => getDepth(s.type)) + return cache +} + function pickString(props: Record | undefined, key: string | undefined): string | undefined { if (!props || !key) return undefined const v = props[key] @@ -68,6 +83,23 @@ export function SearchResultsPanel({ onClose }: { onClose: () => void }) { const schemas = useSchemaStore((s) => s.schemas) const [selectedNode, setSelectedNode] = useState(null) + const depthMap = useMemo(() => buildDepthMap(schemas), [schemas]) + + const groups = useMemo(() => { + const map = new Map() + for (const node of nodes) { + const t = node.node_type ?? "Unknown" + if (!map.has(t)) map.set(t, []) + map.get(t)!.push(node) + } + for (const group of map.values()) { + group.sort((a, b) => (b.score ?? 0) - (a.score ?? 0)) + } + return [...map.entries()].sort( + ([a], [b]) => (depthMap.get(a) ?? 99) - (depthMap.get(b) ?? 99) + ) + }, [nodes, depthMap]) + if (!searchTerm) return null return ( @@ -117,11 +149,23 @@ export function SearchResultsPanel({ onClose }: { onClose: () => void }) { ) : (
- {nodes.map((node, i) => ( -
- setSelectedNode(node)} /> - {i < nodes.length - 1 && ( - + {groups.map(([type, groupNodes], gi) => ( +
+
+ + {type} + +
+ {groupNodes.map((node, i) => ( +
+ setSelectedNode(node)} /> + {i < groupNodes.length - 1 && ( + + )} +
+ ))} + {gi < groups.length - 1 && ( + )}
))}