// Outline / Model / Requirements sections, each independently collapsible. // The whole rail can also collapse to a 36px vertical strip. // Ported from docs/design-source/socrata/project/editor-shell.jsx (LeftRail). "use client"; import { useState } from "react"; import type { FixtureData } from "../../lib/fixtures/aristotle"; import type { ValidationIssue, Severity } from "../../lib/sysml/validate"; interface LeftRailProps { data: FixtureData; focusBlockId: string | null; setFocusBlockId: (id: string | null) => void; /** Map keyed by element key (block id, `req:`, `assoc:`, …) → issues. */ issuesByElement?: Map; } function maxSeverityForKey(map: Map | undefined, key: string): Severity | null { const items = map?.get(key); if (!items || items.length === 0) return null; if (items.some(i => i.severity === "error")) return "error"; if (items.some(i => i.severity === "warning")) return "warning"; return "soft"; } function IssueDot({ severity, title }: { severity: Severity | null; title?: string }) { if (!severity) return null; return ; } export function LeftRail({ data, focusBlockId, setFocusBlockId, issuesByElement }: LeftRailProps) { const [collapsed, setCollapsed] = useState(false); const [open, setOpen] = useState({ outline: true, model: true, requirements: true }); const toggle = (k: keyof typeof open) => setOpen(s => ({ ...s, [k]: !s[k] })); if (collapsed) { return ( ); } return ( ); }