feat(#72): implement interactive graph visualization component
- Create KnowledgeGraphViewer component with @xyflow/react - Implement three layout types: force-directed, hierarchical (ELK), circular - Add node sizing based on connection count (40px-120px range) - Apply PDA-friendly status colors (green=published, blue=draft, gray=archived) - Highlight orphan nodes with distinct color - Add interactive features: zoom, pan, click-to-navigate - Implement filters: status, tags, show/hide orphans - Add statistics display and legend panel - Create comprehensive test suite (16 tests, all passing) - Add fetchKnowledgeGraph API function - Create /knowledge/graph page - Performance tested with 500+ nodes - All quality gates passed (tests, typecheck, lint) Refs #72 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -318,6 +318,59 @@ export async function fetchEntryGraph(
|
||||
return apiGet(`/api/knowledge/entries/${slug}/graph?${params.toString()}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch full knowledge graph
|
||||
*/
|
||||
export async function fetchKnowledgeGraph(filters?: {
|
||||
tags?: string[];
|
||||
status?: string;
|
||||
limit?: number;
|
||||
}): Promise<{
|
||||
nodes: {
|
||||
id: string;
|
||||
slug: string;
|
||||
title: string;
|
||||
summary: string | null;
|
||||
status?: string;
|
||||
tags: {
|
||||
id: string;
|
||||
name: string;
|
||||
slug: string;
|
||||
color: string | null;
|
||||
}[];
|
||||
depth: number;
|
||||
isOrphan?: boolean;
|
||||
}[];
|
||||
edges: {
|
||||
id: string;
|
||||
sourceId: string;
|
||||
targetId: string;
|
||||
linkText: string;
|
||||
}[];
|
||||
stats: {
|
||||
totalNodes: number;
|
||||
totalEdges: number;
|
||||
orphanCount: number;
|
||||
};
|
||||
}> {
|
||||
const params = new URLSearchParams();
|
||||
if (filters?.tags && filters.tags.length > 0) {
|
||||
filters.tags.forEach((tag) => {
|
||||
params.append("tags", tag);
|
||||
});
|
||||
}
|
||||
if (filters?.status) {
|
||||
params.append("status", filters.status);
|
||||
}
|
||||
if (filters?.limit !== undefined) {
|
||||
params.append("limit", filters.limit.toString());
|
||||
}
|
||||
|
||||
const queryString = params.toString();
|
||||
const endpoint = queryString ? `/api/knowledge/graph?${queryString}` : "/api/knowledge/graph";
|
||||
return apiGet(endpoint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mock entries for development (until backend endpoints are ready)
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user