feat(web): merge Entities + Graph into a single Knowledge Base page
Replaces the separate Entities/Graph nav items with one Knowledge Base page that browses all entities as either a table or a force-graph, scoped by ontology layer (Infrastructure/Governance/Cognition), with a resizable browse/detail split instead of a slide-over sheet. - New KnowledgeBase.svelte: layer tabs, view toggle, resizable browse/detail split (pattern from Chat.svelte's rail). - EntityTable/EntityGraph extracted as presentational sub-components; their search/filter/root/depth toolbars live in the shared page toolbar (not the resizable pane) so they don't truncate when the divider is dragged narrow, and both views start flush with the detail pane for consistent height. - EntityTable columns are sortable (slug/type/name/state/health). - EntityDetailContent redesigned as a single-column list of collapsible sections (DetailSection.svelte), collapsed by default when empty; relation entries are clickable and select the entity in the browse pane + detail pane (and drill in-place in EntitySheet wherever it's used elsewhere in the app). - api.ts: add layer filter to fetchEntities, add fetchEntityTypes for client-side graph layer scoping (the graph endpoint has no layer param). Old hash routes (#/entities, #/graph) redirect to #/kb. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -190,6 +190,8 @@ export interface Entity {
|
||||
export interface EntityFilters {
|
||||
type?: string
|
||||
state?: string
|
||||
domain?: string
|
||||
layer?: string
|
||||
q?: string
|
||||
}
|
||||
|
||||
@@ -197,6 +199,8 @@ export async function fetchEntities(filters: EntityFilters = {}): Promise<Entity
|
||||
const params = new URLSearchParams()
|
||||
if (filters.type) params.set('type', filters.type)
|
||||
if (filters.state) params.set('state', filters.state)
|
||||
if (filters.domain) params.set('domain', filters.domain)
|
||||
if (filters.layer) params.set('layer', filters.layer)
|
||||
if (filters.q) params.set('q', filters.q)
|
||||
params.set('limit', '200')
|
||||
const res = await fetchWithAuth(`${API}/entities?${params}`)
|
||||
@@ -205,6 +209,26 @@ export async function fetchEntities(filters: EntityFilters = {}): Promise<Entity
|
||||
return data.items ?? []
|
||||
}
|
||||
|
||||
export type OntologyLayer = 'meta' | 'infrastructure' | 'governance' | 'cognition'
|
||||
|
||||
export interface EntityType {
|
||||
name: string
|
||||
parent_type?: string | null
|
||||
is_abstract: boolean
|
||||
domain: string
|
||||
layer: OntologyLayer
|
||||
description?: string | null
|
||||
}
|
||||
|
||||
// The graph endpoint has no layer param, so callers build a type→layer map from
|
||||
// this to scope the graph client-side (the entities table filters server-side).
|
||||
export async function fetchEntityTypes(): Promise<EntityType[]> {
|
||||
const res = await fetchWithAuth(`${API}/ontology`)
|
||||
if (!res.ok) return []
|
||||
const data = await res.json()
|
||||
return data.entity_types ?? []
|
||||
}
|
||||
|
||||
export interface EventFilters {
|
||||
type?: string
|
||||
severity?: string
|
||||
|
||||
Reference in New Issue
Block a user