--- title: Decisions --- # Decisions ```js const decisions = await FileAttachment("data/decisions.json").json(); const data = Array.isArray(decisions) ? decisions : []; const pending = data.filter(d => d.decision_type === "pending"); const made = data.filter(d => d.decision_type === "made"); ``` ```js const tab = view(Inputs.select(["Pending", "Made"], { label: "View" })); ``` ```js const shown = tab === "Pending" ? pending : made; display(Inputs.table(shown.map(d => ({ Title: d.title, Status: d.status + (d.escalation_note ? " ⚠️" : ""), Decided_by: d.decided_by ?? "—", Deadline: d.deadline ? new Date(d.deadline).toLocaleDateString() : "—", Rationale: (d.rationale ?? "").slice(0, 80), Updated: new Date(d.updated_at).toLocaleDateString(), })), { rows: 30 })); ``` ## Resolution Velocity ```js import * as Plot from "npm:@observablehq/plot"; const resolved = made.filter(d => d.decided_at); const byMonth = resolved.reduce((acc, d) => { const m = d.decided_at.slice(0, 7); acc[m] = (acc[m] ?? 0) + 1; return acc; }, {}); display(Plot.plot({ title: "Decisions Resolved per Month", x: { label: "Month", tickRotate: -30 }, y: { label: "Count", grid: true }, marks: [ Plot.barY( Object.entries(byMonth).map(([month, count]) => ({ month, count })), { x: "month", y: "count", fill: "steelblue", tip: true } ), Plot.ruleY([0]), ], marginBottom: 60, width: 700, })); ``` ```js if (tab === "Pending" && pending.filter(d => d.escalation_note).length > 0) { display(html`