diff --git a/packages/dashboard/app/components/KnowledgeGraphPanel.tsx b/packages/dashboard/app/components/KnowledgeGraphPanel.tsx index 956467c832..51447be341 100644 --- a/packages/dashboard/app/components/KnowledgeGraphPanel.tsx +++ b/packages/dashboard/app/components/KnowledgeGraphPanel.tsx @@ -42,7 +42,8 @@ export function KnowledgeGraphPanel({ projectId, addToast }: { projectId?: strin const selected = graph.selectedId; const limits = graph.status.pathLimits; const foundPath = graph.pathResult?.outcome === "found" ? graph.pathResult.path : null; - const foundHops = graph.pathResult?.outcome === "found" ? graph.pathResult.hops : null; + /* FNXC:KnowledgeGraphDashboard 2026-08-18-22:31: The typed i18n interpolation treats absent hop counts as optional; keep successful zero-hop paths numeric while normalizing non-found results to undefined. */ + const foundHops = graph.pathResult?.outcome === "found" ? graph.pathResult.hops : undefined; return
{graph.status.nodeCount} {t("memory.graphNodes", "nodes")} · {graph.status.edgeCount} {t("memory.graphEdges", "edges")}{graph.status.graphDir}
{t("knowledgeGraph.nodeKinds", "Node kinds")}
{Object.entries(graph.status.nodeKindCounts ?? {}).map(([kind, count]) => `${kind}: ${count}`).join(" · ") || "—"}
{t("knowledgeGraph.edgeKinds", "Edge kinds")}
{Object.entries(graph.status.edgeKindCounts ?? {}).map(([kind, count]) => `${kind}: ${count}`).join(" · ") || "—"}
{t("knowledgeGraph.provenance", "Provenance")}
{Object.entries(graph.status.provenanceCounts ?? {}).map(([kind, count]) => `${kind}: ${count}`).join(" · ") || "—"}
diff --git a/packages/dashboard/app/components/__tests__/KnowledgeGraphPanel.test.tsx b/packages/dashboard/app/components/__tests__/KnowledgeGraphPanel.test.tsx index da45d2b434..b176e23e1b 100644 --- a/packages/dashboard/app/components/__tests__/KnowledgeGraphPanel.test.tsx +++ b/packages/dashboard/app/components/__tests__/KnowledgeGraphPanel.test.tsx @@ -42,7 +42,10 @@ describe("KnowledgeGraphPanel", () => { rerender(); expect(screen.getByTestId("knowledge-graph-no-results")).toBeInTheDocument(); for (const [result, id] of [[{ outcome: "found", path: { nodes: [node], edges: [] }, hops: 0, maxHops: 2, expansions: 1, truncated: false }, "knowledge-graph-path-found"], [{ outcome: "not-found", path: null, maxHops: 2, expansions: 2, truncated: false }, "knowledge-graph-path-not-found"], [{ outcome: "limit-reached", path: null, maxHops: 2, expansions: 2, truncated: true, limit: "max-hops" }, "knowledge-graph-path-limit-reached"]] as const) { - useKnowledgeGraph.mockReturnValue(graph({ pathResult: result })); rerender(); expect(screen.getByTestId(id)).toBeInTheDocument(); + useKnowledgeGraph.mockReturnValue(graph({ pathResult: result })); + rerender(); + expect(screen.getByTestId(id)).toBeInTheDocument(); + if (id === "knowledge-graph-path-found") expect(screen.getByTestId(id)).toHaveTextContent("0 hops"); } useKnowledgeGraph.mockReturnValue(graph({ error: "Unknown graph node" })); rerender(); expect(screen.getByTestId("knowledge-graph-path-error")).toHaveTextContent("Unknown graph node"); });