diff --git a/dashboard/src/components/improvement-modal.js b/dashboard/src/components/improvement-modal.js index 591e45e..8b58c44 100644 --- a/dashboard/src/components/improvement-modal.js +++ b/dashboard/src/components/improvement-modal.js @@ -1,5 +1,5 @@ /** - * improvement-modal — right-click any dashboard widget to suggest an improvement. + * improvement-modal — Shift+click any dashboard widget to suggest an improvement. * * Usage (once per page, usually via _footer.md): * import {initImprovementModal} from "./components/improvement-modal.js"; @@ -10,6 +10,10 @@ * * Otherwise the component walks the DOM to infer the nearest section heading. * Submissions are stored as technical-debt items with debt_type="dashboard-improvement". + * + * Interaction: + * - Hold Shift → cursor changes to crosshair across the entire page + * - Shift+click any element (except form controls) → opens suggestion modal */ const _STYLE_ID = "improvement-modal-styles"; @@ -136,8 +140,9 @@ function _ensureStyles() { @keyframes _im-tin { from { opacity:0; transform:translateX(-50%) translateY(6px) } to { opacity:1; transform:translateX(-50%) translateY(0) } } @keyframes _im-tout { from { opacity:1 } to { opacity:0 } } -/* ── Right-click hint cursor on interactive elements ────────────────────── */ -.impr-hint-cursor { cursor: context-menu; } +/* ── Shift-held cursor override (applied to
) ─────────────────────── */ +.impr-shift-mode, +.impr-shift-mode * { cursor: crosshair !important; } `; document.head.append(s); } @@ -204,8 +209,19 @@ export function initImprovementModal({ apiBase = "http://127.0.0.1:8000", domain _initialized = true; _ensureStyles(); - document.addEventListener("contextmenu", (e) => { - // Don't intercept native right-clicks on form controls or links + // Shift-held cursor indicator + document.addEventListener("keydown", (e) => { + if (e.key === "Shift") document.body.classList.add("impr-shift-mode"); + }); + document.addEventListener("keyup", (e) => { + if (e.key === "Shift") document.body.classList.remove("impr-shift-mode"); + }); + // Remove shift-mode if window loses focus while Shift is held + window.addEventListener("blur", () => document.body.classList.remove("impr-shift-mode")); + + document.addEventListener("click", (e) => { + if (!e.shiftKey) return; + // Don't intercept shift-clicks on form controls or links if (e.target.matches("input, textarea, select, a, button")) return; e.preventDefault(); @@ -255,7 +271,7 @@ export function initImprovementModal({ apiBase = "http://127.0.0.1:8000", domain const hint = Object.assign(document.createElement("div"), { className: "impr-hint", - textContent: "Ctrl + Enter to submit", + textContent: "Ctrl + Enter to submit · Escape to cancel", }); body.append(ctxLabel, chip, sugLabel, textarea, hint); diff --git a/dashboard/src/todo.md b/dashboard/src/todo.md index b02e13c..ee2ea88 100644 --- a/dashboard/src/todo.md +++ b/dashboard/src/todo.md @@ -11,14 +11,15 @@ const THIS_REPO = "the-custodian"; // Live poll: tasks + workstreams + topics + contributions const todoState = (async function*() { while (true) { - let tasks = [], contribs = [], wsMap = {}, ok = false; + let tasks = [], contribs = [], improvements = [], wsMap = {}, ok = false; try { - const [rt, rw, rto, rr, rc] = await Promise.all([ + const [rt, rw, rto, rr, rc, ri] = await Promise.all([ fetch(`${API}/tasks/?limit=500`), fetch(`${API}/workstreams/`), fetch(`${API}/topics/`), fetch(`${API}/repos/`), fetch(`${API}/contributions/`), + fetch(`${API}/technical-debt/?debt_type=dashboard-improvement`), ]); ok = rt.ok && rw.ok && rto.ok && rr.ok && rc.ok; if (ok) { @@ -37,19 +38,21 @@ const todoState = (async function*() { domain: wsMap[t.workstream_id]?.domain ?? "unknown", })); contribs = contribList; + improvements = ri.ok ? (await ri.json()).filter(t => t.debt_type === "dashboard-improvement" && t.status === "open") : []; } } catch {} - yield {tasks, contribs, ok, ts: new Date()}; + yield {tasks, contribs, improvements, ok, ts: new Date()}; await new Promise(res => setTimeout(res, POLL)); } })(); ``` ```js -const tasks = todoState.tasks ?? []; -const contribs = todoState.contribs ?? []; -const _ok = todoState.ok ?? false; -const _ts = todoState.ts; +const tasks = todoState.tasks ?? []; +const contribs = todoState.contribs ?? []; +const improvements = todoState.improvements ?? []; +const _ok = todoState.ok ?? false; +const _ts = todoState.ts; ``` ```js @@ -102,6 +105,12 @@ const _kpiBox = html`No open improvement suggestions. Shift+click any widget to submit one.
`); +} else { + display(html`