/* ============================================================ Calendar & Lists as DATA PRODUCTS, presented in the worksheet document shell (mirrors the existing Content-Library worksheet UI): a document header + a representative formatting toolbar that also holds the FUNCTIONAL face toggle (Data / Artifact / Control / Context). The toolbar's formatting controls are representative only — not wired up. The Data face renders as a spreadsheet grid; the current view is the Artifact face. ============================================================ */ // Calendar's underlying tabular data (the records behind the artifact). const CAL_COLS = ['Date', 'Time', 'Event', 'Type', 'Owner']; const CAL_ROWS = [ ['Tue, Jun 9', '08:00', 'Daily stand-up', 'Meeting', 'AW'], ['Tue, Jun 9', '10:30', 'SVC field inspection', 'Inspection', 'MH'], ['Tue, Jun 9', '14:00', 'Owner progress meeting', 'Meeting', 'AW'], ['Wed, Jun 10', '09:00', 'North shaft liner start', 'Milestone', 'MH'], ['Wed, Jun 10', '15:30', 'Design coordination', 'Meeting', 'DP'], ['Thu, Jun 11', '11:00', 'Stone column inspection', 'Inspection', 'MH'], ['Fri, Jun 12', '13:30', 'Safety stand-down review', 'Meeting', 'AW'], ['Mon, Jun 15', '09:30', 'Weekly Review', 'Report', 'AW'], ['Tue, Jun 16', '16:00', 'Pay app walkthrough', 'Meeting', 'VH'], ['Wed, Jun 17', '—', 'Tunnel grout coordination', 'Meeting', 'MH'], ['Thu, Jun 18', '14:30', 'Photo QA review', 'Meeting', 'JW'], ['Fri, Jun 19', '09:30', 'Monthly Report close', 'Report', 'AW'], ]; // Lists' underlying tabular data — flattened from the board sections. const LISTS_COLS = ['Status', 'Group', 'Item', 'Notes']; function toolListsRows() { const secs = window.LISTS_SECTIONS || []; const tag = window.LISTS_TAG || {}; const rows = []; secs.forEach((s) => (s.items || []).forEach(([status, title, note]) => { rows.push([(tag[status] && tag[status].label) || status, s.title, title, note || '']); })); return rows; } function wsColLetter(i) { let s = ''; i += 1; while (i > 0) { const r = (i - 1) % 26; s = String.fromCharCode(65 + r) + s; i = Math.floor((i - 1) / 26); } return s; } // Data face = a spreadsheet grid. Column letters across, row numbers down. // Pass either `grid` (a raw 2D array, e.g. a workbook sheet) or `cols`+`rows` // (field names become row 1). `boldFirst` bolds row 1 (default: only in cols mode). function WorksheetGrid({ cols, rows, grid, boldFirst }) { const g = grid || [cols || [], ...(rows || [])]; const bold = boldFirst != null ? boldFirst : !grid; const nCols = g.reduce((m, r) => Math.max(m, r ? r.length : 0), 0); const padCols = nCols + 1; // the data shape + one empty column on the right const padRows = g.length + 1; // + one empty row at the bottom const W0 = 240, WC = 96; // first (label) column wider; data columns uniform const tableW = 40 + W0 + (padCols - 1) * WC; return (
{Array.from({ length: padCols }).map((_, i) => )} {Array.from({ length: padCols }).map((_, i) => )} {Array.from({ length: padRows }).map((_, ri) => { const r = g[ri]; return ( {Array.from({ length: padCols }).map((_, ci) => ( ))} ); })}
{wsColLetter(i)}
{ri + 1} {r && r[ci] != null ? r[ci] : ''}
); } function ToolControlFace({ source }) { return (
Sync

In sync with {source} · last synced 1d ago

Maintained by

Claude — wakes when the source updates and re-authors the records.

); } function ToolContextFace({ what, why }) { return (
What this is

{what}

Why it matters

{why}

Status

Draft Claude-authored — validate to pin it as memory.

); } // ── Representative (non-functional) formatting-toolbar bits ── const WsIco = ({ d, box = 24, w = 15 }) => ( {d} ); function WsToolbarControls() { return ( ); } // Reusable worksheet document shell for ANY data product. `faces` is an array of // { key, label, render(setFace) }. Used by the Tool DPs and the Model workbook DPs. function DPShell({ name, author, faces, initial, icon }) { const [face, setFace] = React.useState(initial || (faces[0] && faces[0].key)); const cur = faces.find((f) => f.key === face) || faces[0]; return (
{/* Document header */}
{icon || }
{name}
{author || 'Brandon · just now'}
{/* Toolbar — formatting is representative; the face toggle is functional. */}
{faces.map((f) => )}
{/* Body */}
{cur.label}
{cur.render(setFace)}
); } function ToolDP({ name, source, author, cols, rows, context, initial, children }) { const faces = [ { key: 'data', label: 'Data', render: () => }, { key: 'artifact', label: 'Artifact', render: () =>
{children}
}, { key: 'control', label: 'Control', render: () => }, { key: 'context', label: 'Context', render: () => }, ]; return ; } // Mobile drawer wrapper for the .mdl canvas pane. On ≤1024px the CSS turns // .mdl__canvas into a right-side sheet; on desktop the head/scrim are hidden. function MdlCanvas({ title, open, onClose, className, ariaLabel, children }) { return (