From 6d2c8c898b82114ff61e5b37c9dab5aceec2a504 Mon Sep 17 00:00:00 2001 From: Rassl Date: Fri, 10 Apr 2026 15:44:30 +0200 Subject: [PATCH 1/2] feat: dolly to cursor --- src/app/ontology/ontology-graph-3d.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/app/ontology/ontology-graph-3d.tsx b/src/app/ontology/ontology-graph-3d.tsx index 28719ae..295cae8 100644 --- a/src/app/ontology/ontology-graph-3d.tsx +++ b/src/app/ontology/ontology-graph-3d.tsx @@ -382,8 +382,8 @@ export function OntologyGraph3D({ schemas, edges, selectedId, onSelect }: Props) strokeLinecap="round" strokeLinejoin="round" > - - + + @@ -394,6 +394,7 @@ export function OntologyGraph3D({ schemas, edges, selectedId, onSelect }: Props) makeDefault dollySpeed={0.5} truckSpeed={1} + dollyToCursor /> Date: Fri, 10 Apr 2026 16:23:51 +0200 Subject: [PATCH 2/2] feat: update list --- src/app/ontology/page.tsx | 5 +++ src/components/layout/app-layout.tsx | 12 +++++++ .../layout/search-results-panel.tsx | 32 +++++++++++++++---- src/stores/schema-store.ts | 10 ++++++ 4 files changed, 53 insertions(+), 6 deletions(-) diff --git a/src/app/ontology/page.tsx b/src/app/ontology/page.tsx index dc2703f..67c8b14 100644 --- a/src/app/ontology/page.tsx +++ b/src/app/ontology/page.tsx @@ -29,6 +29,11 @@ export interface SchemaNode { color: string node_key: string attributes: SchemaAttribute[] + title_key?: string + index?: string + description_key?: string + icon?: string + secondary_color?: string } export interface SchemaEdge { diff --git a/src/components/layout/app-layout.tsx b/src/components/layout/app-layout.tsx index 1fa5f0d..61088ea 100644 --- a/src/components/layout/app-layout.tsx +++ b/src/components/layout/app-layout.tsx @@ -11,14 +11,26 @@ import { AddContentModal } from "@/components/modals/add-content-modal" import { BudgetModal } from "@/components/modals/budget-modal" import { useAppStore } from "@/stores/app-store" import { useGraphStore } from "@/stores/graph-store" +import { useSchemaStore } from "@/stores/schema-store" +import { useMocks } from "@/lib/mock-data" export function AppLayout() { const [sourcesOpen, setSourcesOpen] = useState(false) const searchTerm = useAppStore((s) => s.searchTerm) const hasResults = useGraphStore((s) => s.nodes.length > 0) + const schemas = useSchemaStore((s) => s.schemas) + const fetchSchemas = useSchemaStore((s) => s.fetchAll) const searchPanelOpen = !!searchTerm && hasResults + // Schemas power display-name resolution (title_key / index) for search + // results and any other node chrome — load once on mount if not already + // populated (e.g. by the ontology page). + useEffect(() => { + if (useMocks() || schemas.length > 0) return + fetchSchemas() + }, [schemas.length, fetchSchemas]) + // Auto-close sources when search results appear useEffect(() => { if (searchPanelOpen) setSourcesOpen(false) diff --git a/src/components/layout/search-results-panel.tsx b/src/components/layout/search-results-panel.tsx index 7add0ff..513aee5 100644 --- a/src/components/layout/search-results-panel.tsx +++ b/src/components/layout/search-results-panel.tsx @@ -6,14 +6,33 @@ import { Separator } from "@/components/ui/separator" import { Badge } from "@/components/ui/badge" import { useGraphStore } from "@/stores/graph-store" import { useAppStore } from "@/stores/app-store" +import { useSchemaStore } from "@/stores/schema-store" import type { GraphNode } from "@/lib/graph-api" +import type { SchemaNode } from "@/app/ontology/page" -function NodeRow({ node }: { node: GraphNode }) { - const name = - (node.properties?.name as string) ?? - node.ref_id +const DISPLAY_KEY_FALLBACKS = ["name", "title", "label", "text", "content", "body"] as const +function pickString(props: Record | undefined, key: string | undefined): string | undefined { + if (!props || !key) return undefined + const v = props[key] + return typeof v === "string" && v.length > 0 ? v : undefined +} + +function NodeRow({ node, schemas }: { node: GraphNode; schemas: SchemaNode[] }) { const nodeType = node.node_type ?? "Unknown" + const schema = schemas.find((s) => s.type === nodeType) + // Priority: title_key → index (sphinx convention) → common display-ish + // property names → ref_id. The last step catches nodes whose schema key + // isn't populated on this particular row. + const props = node.properties + let name = pickString(props, schema?.title_key) ?? pickString(props, schema?.index) + if (!name) { + for (const key of DISPLAY_KEY_FALLBACKS) { + name = pickString(props, key) + if (name) break + } + } + if (!name) name = node.ref_id return (