// ======================================== // Graph Sidebar Component // ======================================== // Sidebar with legend and node details for Graph Explorer import { useIntl } from 'react-intl'; import { X, Info, Network, FileText, GitBranch, Zap } from 'lucide-react'; import { cn } from '@/lib/utils'; import { Button } from '@/components/ui/Button'; import { Badge } from '@/components/ui/Badge'; import type { GraphNode, NodeType, EdgeType } from '@/types/graph-explorer'; export interface GraphSidebarProps { /** Selected node */ selectedNode: GraphNode | null; /** Legend visibility */ showLegend?: boolean; /** On close callback */ onClose: () => void; } /** * Node type legend item */ interface LegendItem { type: NodeType; label: string; color: string; icon: React.ElementType; } /** * Graph sidebar component */ export function GraphSidebar({ selectedNode, showLegend = true, onClose }: GraphSidebarProps) { const { formatMessage } = useIntl(); const legendItems: LegendItem[] = [ { type: 'component', label: formatMessage({ id: 'graph.legend.component' }), color: 'bg-blue-500', icon: Network, }, { type: 'module', label: formatMessage({ id: 'graph.legend.module' }), color: 'bg-blue-500', icon: FileText, }, { type: 'class', label: formatMessage({ id: 'graph.legend.class' }), color: 'bg-green-500', icon: GitBranch, }, { type: 'function', label: formatMessage({ id: 'graph.legend.function' }), color: 'bg-orange-500', icon: Zap, }, { type: 'variable', label: formatMessage({ id: 'graph.legend.variable' }), color: 'bg-cyan-500', icon: Info, }, ]; const edgeLegendItems = [ { type: 'imports' as EdgeType, label: formatMessage({ id: 'graph.legend.imports' }), color: 'stroke-gray-500', dashArray: '', }, { type: 'calls' as EdgeType, label: formatMessage({ id: 'graph.legend.calls' }), color: 'stroke-green-500', dashArray: '', }, { type: 'extends' as EdgeType, label: formatMessage({ id: 'graph.legend.extends' }), color: 'stroke-purple-500', dashArray: 'stroke-dasharray', }, ]; return (
{/* Header */}

{selectedNode ? formatMessage({ id: 'graph.sidebar.nodeDetails' }) : formatMessage({ id: 'graph.sidebar.title' })}

{/* Content */}
{/* Node details */} {selectedNode ? (
{/* Node header */}
{selectedNode.type} {selectedNode.data.hasIssues && ( {formatMessage({ id: 'graph.sidebar.hasIssues' })} )}

{selectedNode.data.label}

{/* File path */} {selectedNode.data.filePath && (

{selectedNode.data.filePath}

)} {/* Line number */} {selectedNode.data.lineNumber && (

{selectedNode.data.lineNumber}

)} {/* Category */} {selectedNode.data.category && (

{selectedNode.data.category}

)} {/* Line count */} {selectedNode.data.lineCount && (

{selectedNode.data.lineCount} lines

)} {/* Documentation */} {selectedNode.data.documentation && (

{selectedNode.data.documentation}

)} {/* Tags */} {selectedNode.data.tags && selectedNode.data.tags.length > 0 && (
{selectedNode.data.tags.map(tag => ( {tag} ))}
)} {/* Issues */} {selectedNode.data.issues && selectedNode.data.issues.length > 0 && (
    {selectedNode.data.issues.map((issue, idx) => (
  • • {issue}
  • ))}
)}
) : (
{/* Node types legend */} {showLegend && (

{formatMessage({ id: 'graph.legend.nodeTypes' })}

{legendItems.map(item => { const Icon = item.icon; return (
{item.label}
); })}
)} {/* Edge types legend */} {showLegend && (

{formatMessage({ id: 'graph.legend.edgeTypes' })}

{edgeLegendItems.map(item => (
{item.label}
))}
)} {/* Instructions */}

{formatMessage({ id: 'graph.sidebar.instructions' })}

)}
); }