import { ChevronDown, ChevronRight, Eraser, Search, X } from "lucide-react"; import { useState } from "react"; import type { GraphBlacklistItem } from "@/core/knowledge/api"; import type { GraphNode, GraphStats, NodeKind } from "./graphTypes"; import { getEdgeInfo, getNodeTitle, NODE_KIND_META, NODE_KIND_ORDER, } from "./graphUtils"; interface GraphSidebarProps { searchKeyword: string; searchMatchCount: number | null; nodeKindCounts: Map; edgeLabelCounts: Map; disabledNodeKinds: Set; disabledEdgeLabels: Set; stats: GraphStats; topNodes: Array<{ node: GraphNode; degree: number }>; hiddenCount: number; blacklistItems: GraphBlacklistItem[]; blacklistPending: boolean; junkCandidateCount: number; onSearchChange: (keyword: string) => void; onSearchEnter: () => void; onToggleNodeKind: (kind: NodeKind) => void; onToggleEdgeLabel: (label: string) => void; onRestoreHidden: () => void; onRemoveBlacklist: (entryId: string) => void; onCleanJunk: () => void; onPickNode: (id: string) => void; onClose: () => void; } type SectionKey = | "nodeTypes" | "edgeTypes" | "graphStats" | "coreNodes" | "blacklist"; interface FilterSectionProps { title: string; extra?: string; collapsed: boolean; onToggle: () => void; children: React.ReactNode; } function FilterSection(props: FilterSectionProps) { return (
{!props.collapsed ? (
{props.children}
) : null}
); } export function GraphSidebar(props: GraphSidebarProps) { // 节点类型 / 关系类型默认收起,统计与核心节点默认展开。 const [collapsedSections, setCollapsedSections] = useState< Record >({ nodeTypes: true, edgeTypes: true, graphStats: false, coreNodes: false, blacklist: true, }); const toggleFilterSection = (key: SectionKey) => { setCollapsedSections((prev) => ({ ...prev, [key]: !prev[key] })); }; const kinds = NODE_KIND_ORDER.filter((k) => (props.nodeKindCounts.get(k) ?? 0) > 0); const edgeLabels = [...props.edgeLabelCounts.entries()].sort((a, b) => b[1] - a[1]); return ( ); }