From 774a33431f7ae8a54082f5bca5db0019d6459a60 Mon Sep 17 00:00:00 2001 From: Peter Stone Date: Fri, 3 Apr 2026 23:18:45 +0000 Subject: feat: fold completed tab into ready panel; stories tab first - Remove the standalone "All" tab; completed tasks (last 24h) now appear at the bottom of the Ready tab under a "Completed (24h)" section header - Move Stories tab to the first position in the nav bar - Drop 'all' from badge count computation Co-Authored-By: Claude Sonnet 4.6 --- web/app.js | 35 +++++++++++++++++------------------ web/index.html | 7 ++----- web/style.css | 15 +++++++++++++++ 3 files changed, 34 insertions(+), 23 deletions(-) diff --git a/web/app.js b/web/app.js index dfe6d4e..21c825a 100644 --- a/web/app.js +++ b/web/app.js @@ -435,21 +435,13 @@ export function computeTabBadgeCounts(tasks) { let interrupted = 0; let ready = 0; let running = 0; - let all = 0; - const now = Date.now(); - const twentyFourHoursAgo = now - 24 * 60 * 60 * 1000; for (const t of tasks) { if (INTERRUPTED_STATES.has(t.state)) interrupted++; if (t.state === 'READY') ready++; if (t.state === 'RUNNING') running++; - if (DONE_STATES.has(t.state)) { - if (!t.created_at || new Date(t.created_at).getTime() > twentyFourHoursAgo) { - all++; - } - } } - return { interrupted, ready, running, all }; + return { interrupted, ready, running }; } /** @@ -682,13 +674,23 @@ function renderReadyPanel(tasks) { if (!container) return; const visible = sortTasksByDate(filterReadyTasks(tasks)); renderTasksIntoContainer(visible, container, 'No tasks awaiting review.'); -} -function renderAllPanel(tasks) { - const container = document.querySelector('[data-panel="all"] .all-history'); - if (!container) return; - const visible = sortTasksByDate(filterAllDoneTasks(tasks), true); - renderTasksIntoContainer(visible, container, 'No completed tasks in the last 24h.'); + const completedContainer = document.querySelector('[data-panel="ready"] .ready-completed-history'); + if (!completedContainer) return; + const done = sortTasksByDate(filterAllDoneTasks(tasks), true); + if (!completedContainer.querySelector('.ready-completed-label')) { + const label = document.createElement('h2'); + label.className = 'ready-completed-label'; + label.textContent = 'Completed (24h)'; + completedContainer.prepend(label); + } + const list = completedContainer.querySelector('.ready-completed-list') || (() => { + const el = document.createElement('div'); + el.className = 'ready-completed-list'; + completedContainer.appendChild(el); + return el; + })(); + renderTasksIntoContainer(done, list, 'No completed tasks in the last 24h.'); } // ── Run action ──────────────────────────────────────────────────────────────── @@ -1238,9 +1240,6 @@ function renderActiveTab(allTasks) { }); } break; - case 'all': - renderAllPanel(allTasks); - break; case 'stats': Promise.all([ fetchRecentExecutions(BASE_PATH, fetch), diff --git a/web/index.html b/web/index.html index 484bbfb..f212ca6 100644 --- a/web/index.html +++ b/web/index.html @@ -39,13 +39,12 @@ @@ -60,14 +59,12 @@ - diff --git a/web/style.css b/web/style.css index 34395a4..5766b6f 100644 --- a/web/style.css +++ b/web/style.css @@ -1205,6 +1205,21 @@ dialog label select:focus { word-break: break-word; } +.ready-completed-history { + margin-top: 2rem; + border-top: 1px solid var(--border); + padding-top: 1rem; +} + +.ready-completed-label { + font-size: 0.75rem; + font-weight: 600; + color: var(--text-muted); + text-transform: uppercase; + letter-spacing: 0.05em; + margin-bottom: 0.75rem; +} + .running-history { margin-top: 1.5rem; overflow-x: auto; -- cgit v1.2.3