generated from coulomb/repo-seed
feat(tasks): adopt canonical task statuses
This commit is contained in:
@@ -57,12 +57,12 @@ const pageState = (async function*() {
|
||||
const counts = {};
|
||||
for (const t of taskList) {
|
||||
const wid = t.workstream_id;
|
||||
if (!counts[wid]) counts[wid] = {done: 0, in_progress: 0, blocked: 0, todo: 0, total: 0};
|
||||
if (!counts[wid]) counts[wid] = {done: 0, progress: 0, wait: 0, todo: 0, total: 0};
|
||||
counts[wid].total++;
|
||||
if (t.status === "done") counts[wid].done++;
|
||||
else if (t.status === "in_progress") counts[wid].in_progress++;
|
||||
else if (t.status === "blocked") counts[wid].blocked++;
|
||||
else if (t.status === "todo") counts[wid].todo++;
|
||||
if (t.status === "done") counts[wid].done++;
|
||||
else if (t.status === "progress") counts[wid].progress++;
|
||||
else if (t.status === "wait") counts[wid].wait++;
|
||||
else if (t.status === "todo") counts[wid].todo++;
|
||||
}
|
||||
wsAll = wsList.map(w => {
|
||||
const repo = repoMap[w.repo_id];
|
||||
@@ -78,7 +78,7 @@ const pageState = (async function*() {
|
||||
workplan_archived: workplan.archived ?? false,
|
||||
health_labels: workplan.health_labels ?? [],
|
||||
href: `./workstreams/${w.id}`,
|
||||
...(counts[w.id] ?? {done: 0, in_progress: 0, blocked: 0, todo: 0, total: 0}),
|
||||
...(counts[w.id] ?? {done: 0, progress: 0, wait: 0, todo: 0, total: 0}),
|
||||
};
|
||||
});
|
||||
} catch (e) {
|
||||
@@ -233,13 +233,13 @@ for (const w of chartWs) {
|
||||
_seen.add(group);
|
||||
}
|
||||
|
||||
const statusOrder = ["done", "in progress", "blocked", "todo"];
|
||||
const statusColors = ["#4caf50", "steelblue", "#ff7043", "#e0e0e0"];
|
||||
const statusOrder = ["done", "progress", "wait", "todo"];
|
||||
const statusColors = ["#4caf50", "#8b5cf6", "#f59e0b", "#e0e0e0"];
|
||||
|
||||
const _taskRows = chartWs.flatMap(w => [
|
||||
{id: w.id, title: w.title, status: "done", count: w.done ?? 0, domain: w.domain, repo: w.repo_label, workplan: w.workplan_filename, href: w.href},
|
||||
{id: w.id, title: w.title, status: "in progress", count: w.in_progress ?? 0, domain: w.domain, repo: w.repo_label, workplan: w.workplan_filename, href: w.href},
|
||||
{id: w.id, title: w.title, status: "blocked", count: w.blocked ?? 0, domain: w.domain, repo: w.repo_label, workplan: w.workplan_filename, href: w.href},
|
||||
{id: w.id, title: w.title, status: "progress", count: w.progress ?? 0, domain: w.domain, repo: w.repo_label, workplan: w.workplan_filename, href: w.href},
|
||||
{id: w.id, title: w.title, status: "wait", count: w.wait ?? 0, domain: w.domain, repo: w.repo_label, workplan: w.workplan_filename, href: w.href},
|
||||
{id: w.id, title: w.title, status: "todo", count: w.todo ?? 0, domain: w.domain, repo: w.repo_label, workplan: w.workplan_filename, href: w.href},
|
||||
]).filter(d => d.count > 0);
|
||||
|
||||
@@ -370,7 +370,7 @@ display(html`<div class="grid grid-cols-3" style="gap:1rem;margin-bottom:1.5rem"
|
||||
## Status
|
||||
|
||||
```js
|
||||
const blockedTasks = summary.blocked_tasks ?? [];
|
||||
const waitingTasks = summary.waiting_tasks ?? summary.blocked_tasks ?? [];
|
||||
const wsById = Object.fromEntries((summary.open_workstreams ?? []).map(w => [w.id, w]));
|
||||
const todayCount = (summary.recent_progress ?? []).filter(e =>
|
||||
e.created_at?.startsWith(new Date().toISOString().slice(0, 10))).length;
|
||||
@@ -388,9 +388,9 @@ const statusEl = html`<div>
|
||||
<p class="big-num">${decCount}</p>
|
||||
<small>${decisions.escalated ?? 0} escalated</small>
|
||||
</a>
|
||||
<div class="card card-link ${blockedTasks.length > 0 ? 'warn' : ''}" data-toggle="blocked-panel">
|
||||
<h3>Blocked Tasks</h3>
|
||||
<p class="big-num">${blockedTasks.length}</p>
|
||||
<div class="card card-link ${waitingTasks.length > 0 ? 'warn' : ''}" data-toggle="waiting-panel">
|
||||
<h3>Waiting Tasks</h3>
|
||||
<p class="big-num">${waitingTasks.length}</p>
|
||||
<small>of ${tasks.total ?? 0} total · click to expand</small>
|
||||
</div>
|
||||
<a class="card card-link" href="#recent-activity">
|
||||
@@ -400,10 +400,10 @@ const statusEl = html`<div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div id="blocked-panel" style="display:none;margin-bottom:1rem">
|
||||
${blockedTasks.length === 0
|
||||
? html`<p class="dim" style="padding:0.5rem 0">No tasks currently blocked.</p>`
|
||||
: html`<div class="bt-list">${blockedTasks.map(t => {
|
||||
<div id="waiting-panel" style="display:none;margin-bottom:1rem">
|
||||
${waitingTasks.length === 0
|
||||
? html`<p class="dim" style="padding:0.5rem 0">No tasks currently waiting.</p>`
|
||||
: html`<div class="bt-list">${waitingTasks.map(t => {
|
||||
const wsName = wsById[t.workstream_id]?.title ?? t.workstream_id?.slice(0,8) ?? "—";
|
||||
return html`<div class="bt-row">
|
||||
<div class="bt-meta">${wsName}</div>
|
||||
@@ -415,11 +415,11 @@ const statusEl = html`<div>
|
||||
</div>
|
||||
</div>`;
|
||||
|
||||
statusEl.querySelector('[data-toggle="blocked-panel"]').addEventListener('click', () => {
|
||||
const panel = statusEl.querySelector('#blocked-panel');
|
||||
statusEl.querySelector('[data-toggle="waiting-panel"]').addEventListener('click', () => {
|
||||
const panel = statusEl.querySelector('#waiting-panel');
|
||||
const isOpen = panel.style.display !== 'none';
|
||||
panel.style.display = isOpen ? 'none' : 'block';
|
||||
statusEl.querySelector('[data-toggle="blocked-panel"] small').textContent =
|
||||
statusEl.querySelector('[data-toggle="waiting-panel"] small').textContent =
|
||||
isOpen ? `of ${tasks.total ?? 0} total · click to expand` : `of ${tasks.total ?? 0} total · click to collapse`;
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user