feat(web): unify Knowledge Base filtering into one type multiselect

Replace the Fleet/Network/Identity/Knowledge category tabs (which
scoped entity fetches server-side) with a single "Types" multiselect
shared by both the table and graph views — both now fetch the whole
entity set (paginated via the new fetchAllEntities) and filter
client-side, defaulting to fleet's types. Table and graph also share
one search/highlight field instead of two separately-labeled ones.

Along the way, fixed a real bug the wider entity set exposed: the
treegrid's parent/child grouping fired one fetchGraph call per
candidate root entity, fine for the old ~50-entity fleet scope but an
ERR_INSUFFICIENT_RESOURCES flood once scoped to the full ~1700-entity
set. Replaced with a single whole-graph fetch, deriving parent/child
pairs from its edges client-side.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-19 17:00:13 +02:00
parent 6051fb4845
commit e28e0e9ea3
4 changed files with 191 additions and 263 deletions

View File

@@ -213,6 +213,24 @@ export async function fetchEntities(filters: EntityFilters = {}): Promise<Entity
return data.items ?? []
}
// The entities endpoint caps at 200/page — the Knowledge Base wants the
// whole set (it filters by type/search client-side now instead of scoping
// the fetch server-side), so page through via cursor until exhausted.
export async function fetchAllEntities(): Promise<Entity[]> {
const all: Entity[] = []
let cursor: string | undefined
do {
const params = new URLSearchParams({ limit: '200' })
if (cursor) params.set('cursor', cursor)
const res = await fetchWithAuth(`${API}/entities?${params}`)
if (!res.ok) break
const data = await res.json()
all.push(...(data.items ?? []))
cursor = data.next_cursor ?? undefined
} while (cursor)
return all
}
export type OntologyLayer = 'meta' | 'infrastructure' | 'governance' | 'cognition'
export interface EntityType {