import { useEffect } from "react"; import { useDashboardStore } from "../store"; import { useI18n } from "../contexts/I18nContext"; import PersonaSelector from "./PersonaSelector"; import DiffToggle from "./DiffToggle"; import LayerLegend from "./LayerLegend"; import FilterPanel from "./FilterPanel"; import ExportMenu from "./ExportMenu"; import { ThemePicker } from "./ThemePicker"; interface Props { open: boolean; onClose: () => void; onTogglePathFinder: () => void; onShowKeyboardHelp: () => void; } interface NodeTypeFilterDef { key: "code" | "config" | "docs" | "infra" | "data" | "domain" | "knowledge"; label: string; color: string; } function SectionLabel({ children }: { children: React.ReactNode }) { return (

{children}

); } export default function MobileDrawer({ open, onClose, onTogglePathFinder, onShowKeyboardHelp, }: Props) { const graph = useDashboardStore((s) => s.graph); const isKnowledgeGraph = useDashboardStore((s) => s.isKnowledgeGraph); const domainGraph = useDashboardStore((s) => s.domainGraph); const viewMode = useDashboardStore((s) => s.viewMode); const setViewMode = useDashboardStore((s) => s.setViewMode); const nodeTypeFilters = useDashboardStore((s) => s.nodeTypeFilters); const toggleNodeTypeFilter = useDashboardStore((s) => s.toggleNodeTypeFilter); const { t } = useI18n(); const structuralFilters: NodeTypeFilterDef[] = [ { key: "code", label: t.nodeTypeLabels.code, color: "var(--color-node-file)" }, { key: "config", label: t.nodeTypeLabels.config, color: "var(--color-node-config)" }, { key: "docs", label: t.nodeTypeLabels.docs, color: "var(--color-node-document)" }, { key: "infra", label: t.nodeTypeLabels.infra, color: "var(--color-node-service)" }, { key: "data", label: t.nodeTypeLabels.data, color: "var(--color-node-table)" }, { key: "domain", label: t.nodeTypeLabels.domain, color: "var(--color-node-concept)" }, { key: "knowledge", label: t.nodeTypeLabels.knowledge, color: "var(--color-node-article)" }, ]; const knowledgeFilters: NodeTypeFilterDef[] = [ { key: "knowledge", label: t.nodeTypeLabels.all, color: "var(--color-node-article)" }, ]; useEffect(() => { if (!open) return; const handler = (e: KeyboardEvent) => { if (e.key === "Escape") onClose(); }; document.addEventListener("keydown", handler); return () => document.removeEventListener("keydown", handler); }, [open, onClose]); // Lock body scroll while open so the page behind doesn't drift useEffect(() => { if (!open) return; const original = document.body.style.overflow; document.body.style.overflow = "hidden"; return () => { document.body.style.overflow = original; }; }, [open]); const filterDefs = isKnowledgeGraph ? knowledgeFilters : structuralFilters; const showViewToggle = Boolean(graph && !isKnowledgeGraph && domainGraph); return (
{/* Backdrop */} {/* Body */}
{t.drawer.role}
{showViewToggle && (
{t.drawer.view}
)}
{t.drawer.diffOverlay}
{t.drawer.nodeTypes}
{filterDefs.map((cat) => { const active = nodeTypeFilters[cat.key] !== false; return ( ); })}
{graph && (graph.layers?.length ?? 0) > 0 && (
{t.drawer.layers}
)}
{t.drawer.tools}
); }