import { useState } from 'react'; import { Link, useLocation } from 'react-router-dom'; import { Layout, Grid3X3, FilePlus, Home, Keyboard, Server, LayoutGrid, Compass, HelpCircle, ChevronRight, ArrowDownToLine, ArrowUpFromLine, Link2, Search, Filter, Tag, } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'; import ThemeToggle from '@/components/ThemeToggle'; import NotificationCenter from '@/components/NotificationCenter'; import ExportMenu from '@/components/ExportMenu'; import AlertRulesManager from '@/components/AlertRulesManager'; import { InstallButton } from '@/components/InstallButton'; import { useKeyboardShortcuts, shortcutsList } from '@/hooks/useKeyboardShortcuts'; import { useTheme } from '@/contexts/ThemeContext'; import { cn } from '@/lib/utils'; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger, } from '@/components/ui/dialog'; import { ScrollArea } from '@/components/ui/scroll-area'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; import { helpContent, navItems } from '@/config/navHelpData'; const iconMap = { Home, Layout, LayoutGrid, Compass, Grid3X3, FilePlus, Server, }; // Help content for each page // This is a legacy fallback - primary source is config/navHelpData const _legacyHelpContent: Record = { discover: { title: 'Widget Discovery', icon: Compass, diagram: `┌─────────────────────────────────────────────────────────────┐ │ Widget Discovery │ ├─────────────────────────────────────────────────────────────┤ │ ┌──────────────┐ ┌────────────────────────────────┐ │ │ │widgetRegistry│ ───▶ │ WidgetMetadata[] (alle widgets)│ │ │ └──────────────┘ └────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌───────────────────────────────────────────────────────┐ │ │ │ Filtrering (useMemo) │ │ │ │ • searchQuery • selectedDataType • filterMode │ │ │ │ • selectedPriority • selectedTags │ │ │ └───────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌───────────────────────────────────────────────────────┐ │ │ │ findCompatible(widgetId) → kompatible widgets │ │ │ └───────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘`, purpose: 'Widget Discovery er et avanceret søge- og opdagelsesværktøj der hjælper brugere med at finde relevante widgets baseret på datatyper, tags og prioritet, forstå widget-afhængigheder (hvad en widget kræver og leverer), opdage kompatible widgets der kan kobles sammen, og visualisere widget-økosystemets dataflow.', features: [ { name: 'Fritekst-søgning', desc: 'Søg i navn, beskrivelse, tags og widget-ID' }, { name: 'Data Type Filter', desc: 'Filtrer efter 12 datatyper: security_event, threat_intel, network_traffic, metric, ip_address, geolocation, cve, mitre_technique, domain, file_hash, object, array', }, { name: 'Filter Mode', desc: 'Vælg om datatype-filter skal matche "Leverer" (output), "Kræver" (input) eller "Begge"', }, { name: 'Prioritetsfilter', desc: 'Filtrer efter prioritet: critical / high / medium / low' }, { name: 'Tag-filtrering', desc: 'Multi-select af alle tilgængelige tags fra widget-økosystemet', }, { name: 'Widget-udvælgelse', desc: 'Vælg en widget for at se kompatible widgets i sidebar' }, { name: 'Expand/Collapse', desc: 'Vis detaljeret info om requirements (inputs), capabilities (outputs) og relationer', }, { name: 'Kompatibilitetsvisning', desc: 'Se hvilke widgets der kan levere data til / modtage data fra den valgte widget', }, ], dataModel: [ { name: 'WidgetMetadata', desc: 'id, name, description, version, priority, tags' }, { name: 'Requirement (input)', desc: 'id, name, type (DataType), description, required (bool)', }, { name: 'Capability (output)', desc: 'id, name, outputType (DataType), description, triggers[]', }, { name: 'Relation', desc: 'type (depends_on, provides_to, synchronizes, triggers, aggregates), targetWidgetId, description', }, ], integration: [ { name: 'widgetRegistry', desc: 'Singleton fra /lib/widgetRegistry.ts - central widget-database', }, { name: 'securityWidgetSchemas', desc: 'Sikkerhedswidgets defineret i /types/WidgetSchema.ts', }, { name: 'calendarScheduleWidgetSchemas', desc: 'Kalender/schedule widgets' }, { name: 'findCompatible(widgetId)', desc: 'Finder widgets der kan kobles sammen baseret på input/output typer', }, ], useCases: [ { case: 'Find threat intel widgets', action: 'Filtrer Data Type → "Threat Intelligence"' }, { case: 'Se hvad ThreatMap kræver', action: 'Søg "ThreatMap" → Expand → Se KRÆVER sektion' }, { case: 'Find kompatible widgets', action: 'Klik øje-ikon på widget → Se "Kompatible widgets" i sidebar', }, { case: 'Build et dashboard', action: 'Filtrer efter tags → Find widgets med samme domæne' }, { case: 'Debug dataflow', action: 'Expand widget → Se relationer (depends_on, triggers, etc.)', }, ], uiComponents: [ { name: 'WidgetDiscovery', file: 'pages/WidgetDiscovery.tsx', role: 'Side-container med layout, state og filtrering', }, { name: 'WidgetCard', file: 'Inline komponent', role: 'Viser enkelt widget med expand/select', }, { name: 'MatrixRain', file: 'components/MatrixRain.tsx', role: 'Æstetisk matrix baggrund' }, ], relatedPages: [ { path: '/widgets', relation: '"Tilbage" link - Widget catalog med alle widgets' }, { path: '/gallery', relation: 'Visual gallery - Samme data, anden præsentation' }, { path: '/dashboard', relation: 'Bruger widgets fundet her' }, ], summary: '/discover er widget-søgemaskinen - stedet hvor du finder og forstår widgets før du bruger dem på dit dashboard.', }, dashboard: { title: 'Dashboard', icon: Layout, diagram: `┌─────────────────────────────────────────────────────────────┐ │ Dashboard │ ├─────────────────────────────────────────────────────────────┤ │ ┌──────────────┐ ┌────────────────────────────────┐ │ │ │ WebSocket │ ───▶ │ Real-time events & data stream │ │ │ │ws://...:3001 │ └────────────────────────────────┘ │ │ └──────────────┘ │ │ │ │ ▼ │ │ │ ┌────────────────────────────────┐ │ │ │ │ MCPContext (React Context) │ │ │ │ │ • tools[] • invoke() • status │ │ │ │ └────────────────────────────────┘ │ │ ▼ │ │ │ ┌───────────────────────────────────────────────────────┐ │ │ │ DashboardLayout (react-grid-layout) │ │ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ │ │ Widget │ │ Widget │ │ Widget │ │ Widget │ │ │ │ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │ │ └───────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌───────────────────────────────────────────────────────┐ │ │ │ localStorage → dashboard-layout (persistens) │ │ │ └───────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘`, purpose: 'Dashboard er din personlige kommandocentral hvor du kan overvåge sikkerhedsstatus, se aktive trusler og få overblik over systemets helbred.', features: [ { name: 'Real-time data', desc: 'Live opdateringer fra backend via WebSocket' }, { name: 'Widget-layout', desc: 'Tilpas dit dashboard med drag-and-drop' }, { name: 'Alerts', desc: 'Se kritiske advarsler øverst' }, { name: 'Persistens', desc: 'Layout gemmes automatisk i localStorage' }, { name: 'Responsive grid', desc: 'Tilpasser sig skærmstørrelse' }, ], dataModel: [ { name: 'DashboardLayout', desc: 'widgets[], columns, rows, breakpoints' }, { name: 'WidgetInstance', desc: 'id, widgetType, position {x, y, w, h}, config' }, { name: 'WidgetState', desc: 'data, loading, error, lastUpdated' }, ], integration: [ { name: 'WebSocket', desc: 'ws://localhost:3001/mcp/ws - real-time data stream' }, { name: 'MCPContext', desc: 'React context der håndterer MCP-forbindelse' }, { name: 'NotificationContext', desc: 'Push notifications fra backend events' }, { name: 'localStorage', desc: 'dashboard-layout key til persistens' }, ], useCases: [ { case: 'Overvåg trusler', action: 'Se Threat Feed widget' }, { case: 'Check system health', action: 'Se System Status widget' }, ], uiComponents: [ { name: 'Dashboard', file: 'pages/Dashboard.tsx', role: 'Hovedside med widget grid' }, { name: 'ConfigurableWidget', file: 'components/ConfigurableWidget.tsx', role: 'HOC der wrapper widgets med config', }, { name: 'WidgetGrid', file: 'react-grid-layout', role: 'Drag-and-drop grid system' }, ], relatedPages: [ { path: '/widgets', relation: 'Tilføj nye widgets til dashboard' }, { path: '/discover', relation: 'Find kompatible widgets' }, { path: '/pages', relation: 'Gem dashboard som custom side' }, ], summary: '/dashboard er kommandocentralen - dit personlige overblik over systemets tilstand med live data.', }, widgets: { title: 'Widgets Katalog', icon: LayoutGrid, diagram: `┌─────────────────────────────────────────────────────────────┐ │ Widgets Katalog │ ├─────────────────────────────────────────────────────────────┤ │ ┌──────────────┐ ┌────────────────────────────────┐ │ │ │widgetRegistry│ ───▶ │ WidgetDefinition[] (alle typer)│ │ │ └──────────────┘ └────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌───────────────────────────────────────────────────────┐ │ │ │ Kategorisering │ │ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ │ │ Security │ │ Data │ │ System │ │ OSINT │ │ │ │ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │ │ └───────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌───────────────────────────────────────────────────────┐ │ │ │ ConfigurableWidget (HOC) → Dashboard integration │ │ │ └───────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘`, purpose: 'Widget-kataloget viser alle tilgængelige widgets organiseret efter kategori. Herfra kan du tilføje widgets til dit dashboard.', features: [ { name: 'Kategorier', desc: 'Security, Data, System, Monitoring, OSINT, AI' }, { name: 'Preview', desc: 'Se widget før du tilføjer den' }, { name: 'Quick add', desc: 'Tilføj direkte til dashboard' }, { name: 'Søgning', desc: 'Filtrer widgets efter navn eller beskrivelse' }, ], dataModel: [ { name: 'WidgetDefinition', desc: 'id, name, description, category, icon, component' }, { name: 'WidgetCategory', desc: 'Security | Data | System | Monitoring | OSINT | AI' }, { name: 'WidgetConfig', desc: 'refreshInterval, dataSource, displayOptions' }, ], integration: [ { name: 'widgetRegistry', desc: 'Central registry med alle widget-definitioner' }, { name: '/api/mcp/tools', desc: 'Backend endpoint for MCP tool-liste' }, { name: 'ConfigurableWidget', desc: 'HOC der wrapper alle widgets med config UI' }, ], useCases: [ { case: 'Find ny widget', action: 'Gennemse kategorier eller søg' }, { case: 'Se widget detaljer', action: 'Klik på widget for preview' }, ], uiComponents: [ { name: 'Widgets', file: 'pages/Widgets.tsx', role: 'Hovedside med kategori-tabs' }, { name: 'WidgetCard', file: 'components/WidgetCard.tsx', role: 'Preview card for hver widget', }, { name: 'CategoryTabs', file: 'Inline', role: 'Tab-navigation mellem kategorier' }, ], relatedPages: [ { path: '/discover', relation: 'Avanceret søgning og filtrering' }, { path: '/dashboard', relation: 'Tilføj valgte widgets' }, { path: '/gallery', relation: 'Se alle widgets visuelt' }, ], summary: '/widgets er kataloget - browse og vælg widgets efter kategori før du tilføjer dem.', }, gallery: { title: 'Gallery', icon: Grid3X3, diagram: `┌─────────────────────────────────────────────────────────────┐ │ Gallery │ ├─────────────────────────────────────────────────────────────┤ │ ┌──────────────┐ ┌────────────────────────────────┐ │ │ │widgetRegistry│ ───▶ │ Alle widgets med live data │ │ │ └──────────────┘ └────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌───────────────────────────────────────────────────────┐ │ │ │ MCPContext → Hent preview data for hver widget │ │ │ └───────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌───────────────────────────────────────────────────────┐ │ │ │ Masonry Grid Layout │ │ │ │ ┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐ │ │ │ │ │Preview│ │Preview│ │Preview│ │Preview│ │Preview│ │ │ │ │ │ + │ │ + │ │ + │ │ + │ │ + │ │ │ │ │ │ Data │ │ Data │ │ Data │ │ Data │ │ Data │ │ │ │ │ └───────┘ └───────┘ └───────┘ └───────┘ └───────┘ │ │ │ └───────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘`, purpose: 'Gallery viser en visuel oversigt over alle widgets med deres aktuelle tilstand og data.', features: [ { name: 'Grid view', desc: 'Se alle widgets i et grid' }, { name: 'Live preview', desc: 'Widgets viser live data' }, { name: 'Kategorivisning', desc: 'Grupperet efter widget-kategori' }, { name: 'Responsive layout', desc: 'Tilpasser sig vinduesstørrelse' }, ], dataModel: [ { name: 'GalleryItem', desc: 'widget, previewData, thumbnail, status' }, { name: 'PreviewState', desc: 'loading, error, data, refreshTimer' }, ], integration: [ { name: 'widgetRegistry', desc: 'Henter alle tilgængelige widgets' }, { name: 'MCPContext', desc: 'Henter live data til previews' }, { name: 'Masonry layout', desc: 'CSS grid til dynamisk placering' }, ], useCases: [{ case: 'Overblik', action: 'Se alle widgets på én gang' }], uiComponents: [ { name: 'WidgetGallery', file: 'pages/WidgetGallery.tsx', role: 'Hovedside med masonry grid', }, { name: 'GalleryCard', file: 'Inline', role: 'Widget preview med live data' }, { name: 'FilterBar', file: 'Inline', role: 'Filtrer efter kategori' }, ], relatedPages: [ { path: '/widgets', relation: 'Liste-visning af samme widgets' }, { path: '/discover', relation: 'Søg og filtrer widgets' }, { path: '/dashboard', relation: 'Tilføj widget til dashboard' }, ], summary: '/gallery er showroom - se alle widgets visuelt med live data før du vælger.', }, pages: { title: 'Mine Sider', icon: FilePlus, diagram: `┌─────────────────────────────────────────────────────────────┐ │ Mine Sider │ ├─────────────────────────────────────────────────────────────┤ │ ┌──────────────┐ ┌────────────────────────────────┐ │ │ │ localStorage │ ◀──▶ │ CustomPage[] (alle sider) │ │ │ │ custom-pages │ └────────────────────────────────┘ │ │ └──────────────┘ │ │ │ ▼ │ │ ┌───────────────────────────────────────────────────────┐ │ │ │ PageBuilder (drag-and-drop) │ │ │ │ • Tilføj widgets • Arranger layout • Gem side │ │ │ └───────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌───────────────────────────────────────────────────────┐ │ │ │ Templates │ │ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌───────────┐ │ │ │ │ │ SOC │ │ OSINT │ │Executive│ │ Custom │ │ │ │ │ └─────────┘ └─────────┘ └─────────┘ └───────────┘ │ │ │ └───────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌───────────────────────────────────────────────────────┐ │ │ │ /page/:slug → react-router dynamic routing │ │ │ └───────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘`, purpose: 'Opret og administrer dine egne custom sider med widgets arrangeret efter dit behov.', features: [ { name: 'Page builder', desc: 'Drag-and-drop side-builder' }, { name: 'Templates', desc: 'Brug foruddefinerede templates (SOC, OSINT, Executive)' }, { name: 'Share', desc: 'Del sider med kolleger via URL' }, { name: 'Export/Import', desc: 'Eksporter sider som JSON' }, ], dataModel: [ { name: 'CustomPage', desc: 'id, slug, title, description, layout, widgets[], createdAt' }, { name: 'PageLayout', desc: 'type (grid | freeform), columns, spacing' }, { name: 'PageTemplate', desc: 'id, name, description, defaultWidgets[], thumbnail' }, ], integration: [ { name: 'localStorage', desc: 'custom-pages key til persistens' }, { name: '/page/:slug', desc: 'Dynamic routing til custom pages' }, { name: 'ExportMenu', desc: 'Eksporter side som JSON eller PDF' }, { name: 'react-router', desc: 'Navigation mellem sider' }, ], useCases: [ { case: 'Opret rapport-side', action: 'Ny side → Tilføj relevante widgets' }, { case: 'SOC dashboard', action: 'Brug SOC template' }, ], uiComponents: [ { name: 'PageBuilder', file: 'pages/PageBuilder.tsx', role: 'Drag-and-drop side-editor' }, { name: 'CustomPage', file: 'pages/CustomPage.tsx', role: 'Renderer for gemte sider' }, { name: 'TemplateSelector', file: 'Inline', role: 'Vælg mellem foruddefinerede templates' }, ], relatedPages: [ { path: '/page/:slug', relation: 'Vis oprettet side' }, { path: '/widgets', relation: 'Vælg widgets til siden' }, { path: '/dashboard', relation: 'Standard dashboard som inspiration' }, ], summary: '/pages er dit værksted - byg og gem custom dashboards med præcis de widgets du har brug for.', }, backend: { title: 'Backend', icon: Server, diagram: `┌─────────────────────────────────────────────────────────────┐ │ Backend │ ├─────────────────────────────────────────────────────────────┤ │ ┌───────────────────────────────────────────────────────┐ │ │ │ Express Server (port 3001) │ │ │ │ • /api/mcp/tools • /api/health • /api/sys │ │ │ └───────────────────────────────────────────────────────┘ │ │ │ │ │ │ ▼ ▼ │ │ ┌──────────────┐ ┌──────────────┐ │ │ │ Neo4j │ │ PostgreSQL │ │ │ │bolt://neo4j │ │ (Prisma) │ │ │ │ :7687 │ │ │ │ │ └──────────────┘ └──────────────┘ │ │ │ │ │ │ ▼ ▼ │ │ ┌───────────────────────────────────────────────────────┐ │ │ │ MCP Tools (59 registrerede) │ │ │ │ • vidensarkiv.* • autonomous.* • widgets.* • pal.* │ │ │ └───────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌───────────────────────────────────────────────────────┐ │ │ │ WebSocket ws://localhost:3001/mcp/ws │ │ │ │ → Real-time events til frontend │ │ │ └───────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘`, purpose: 'Backend-siden giver indsigt i systemets infrastruktur, MCP-tools, database-status og API-endpoints.', features: [ { name: 'MCP Tools', desc: 'Se alle 59 registrerede MCP tools med beskrivelser' }, { name: 'Database status', desc: 'Neo4j og PostgreSQL connection health' }, { name: 'API explorer', desc: 'Test API endpoints direkte i browseren' }, { name: 'System metrics', desc: 'CPU, memory, uptime for backend' }, { name: 'Log viewer', desc: 'Se seneste system logs' }, ], dataModel: [ { name: 'MCPTool', desc: 'name, description, inputSchema, handler' }, { name: 'SystemHealth', desc: 'neo4j, postgres, redis, uptime, memory' }, { name: 'APIEndpoint', desc: 'path, method, description, parameters' }, ], integration: [ { name: '/api/mcp/tools', desc: 'Liste over alle MCP tools' }, { name: '/api/health', desc: 'System health check endpoint' }, { name: '/api/sys', desc: 'System info og metrics' }, { name: 'Neo4j bolt://neo4j:7687', desc: 'Graph database connection' }, { name: 'PostgreSQL', desc: 'Prisma ORM til structured data' }, ], useCases: [ { case: 'Debug integration', action: 'Check MCP tool status' }, { case: 'Se system health', action: 'Check database connections' }, ], uiComponents: [ { name: 'Backend', file: 'pages/Backend.tsx', role: 'Hovedside med system-info tabs' }, { name: 'MCPToolList', file: 'Inline', role: 'Liste over alle MCP tools' }, { name: 'HealthIndicator', file: 'Inline', role: 'Viser database connection status' }, { name: 'APIExplorer', file: 'Inline', role: 'Test endpoints direkte' }, ], relatedPages: [ { path: '/dashboard', relation: 'Se data fra backend i widgets' }, { path: '/widgets', relation: 'Widgets bruger MCP tools' }, { path: '/', relation: 'System status på forsiden' }, ], summary: '/backend er kontrolrummet - se og test hele systemets infrastruktur, APIs og database-forbindelser.', }, }; const GlobalHeader = () => { const location = useLocation(); const { currentSkin } = useTheme(); const [helpTab, setHelpTab] = useState('discover'); useKeyboardShortcuts(); return (
{/* Logo & Nav */}
{currentSkin.logo || 'CT'}
{/* Actions - kompakt layout */}
Keyboard Shortcuts
{shortcutsList.map(shortcut => (
{shortcut.description} {shortcut.keys}
))}
{/* Help Dialog */} Hjælp & Dokumentation Hjælp & Dokumentation {Object.entries(helpContent).map(([key, content]) => { const Icon = iconMap[content.icon]; return ( {content.title.split(' ')[0]} ); })} {Object.entries(helpContent).map(([key, content]) => { const Icon = content.icon; return ( {/* Header */}

{content.title}

/{key === 'pages' ? 'pages' : key}

{/* Architecture Diagram */} {'diagram' in content && content.diagram && (

ARKITEKTUR

                              {content.diagram}
                            
)} {/* Purpose */}

FORMÅL

{content.purpose}

{/* Features */}

FUNKTIONER

{content.features.map((f, idx) => (
{f.name}

{f.desc}

))}
{/* Data Model - only for discover */} {'dataModel' in content && content.dataModel && (

DATA MODEL

{content.dataModel.map( (dm: { name: string; desc: string }, idx: number) => (
{dm.name}

{dm.desc}

) )}
)} {/* Integration - only for discover */} {'integration' in content && content.integration && (

INTEGRATION

{content.integration.map( (int: { name: string; desc: string }, idx: number) => (
{int.name}

{int.desc}

) )}
)} {/* Use Cases */}

ANVENDELSE

{content.useCases.map((uc, idx) => (
{uc.case}: {uc.action}
))}
{/* UI Components */} {'uiComponents' in content && content.uiComponents && (

🎨 UI KOMPONENTER

{content.uiComponents.map( ( ui: { component: string; file: string; responsibility: string; }, idx: number ) => ( ) )}
Komponent Fil Ansvar
{ui.component} {ui.file} {ui.responsibility}
)} {/* Related Pages */} {'relatedPages' in content && content.relatedPages && (

📁 RELATEREDE SIDER

{content.relatedPages.map( (rp: { page: string; relation: string }, idx: number) => ( ) )}
Side Relation
{rp.page} {rp.relation}
)} {/* Summary */} {'summary' in content && content.summary && (

💡 Kort sagt: {content.summary}

)} ); })}
); }; export default GlobalHeader;