feat(terminology): workplan-first dashboard and retirement backlog (STATE-WP-0069)
Add the ranked legacy-interface backlog (T01), rename dashboard navigation and user-facing copy to workplan while preserving wire-compat API keys (T02), and activate the retirement workplan with T01/T02 marked done.
This commit is contained in:
parent
4dc69bb8f5
commit
b2264d1f06
44 changed files with 382 additions and 253 deletions
|
|
@ -148,10 +148,10 @@ if (_h1) { _h1.style.position = "relative"; withDocHelp(_h1, "/docs/overview");
|
|||
display(html`<div class="warning" style="display:${summary.error ? '' : 'none'}">⚠️ ${summary.error ?? ''}</div>`);
|
||||
```
|
||||
|
||||
## Workstreams by Repository
|
||||
## Workplans by Repository
|
||||
|
||||
```js
|
||||
// ── Filter workstreams by selected mode ───────────────────────────────────────
|
||||
// ── Filter workplans by selected mode ───────────────────────────────────────
|
||||
// Lifecycle modes match stored canonical status values.
|
||||
// Health modes are derived labels; they are not stored lifecycle states.
|
||||
// Time modes filter by updated_at / created_at.
|
||||
|
|
@ -251,8 +251,8 @@ function _setChartMode(value) {
|
|||
```js
|
||||
const _modeSelect = html`<select
|
||||
class="ws-mode-select"
|
||||
aria-label="Workstream chart mode with matching workstream counts"
|
||||
title="Choose which workstreams to show; counts are matching workstreams"
|
||||
aria-label="Workplan chart mode with matching workplan counts"
|
||||
title="Choose which workplans to show; counts are matching workplans"
|
||||
>
|
||||
${_MODE_GROUPS.map(group => html`<optgroup label=${group.label}>
|
||||
${group.options.map(([value, label]) => html`<option value=${value}>${label} (${_workstreamsForMode(value, wsAll).length})</option>`)}
|
||||
|
|
@ -274,7 +274,7 @@ import * as Plot from "npm:@observablehq/plot";
|
|||
const _chartModeValue = _modeValue(_chartModeState);
|
||||
const _chartWsFiltered = _workstreamsForMode(_chartModeValue, wsAll);
|
||||
|
||||
// Sort by domain, then repository, then most recently updated workstream.
|
||||
// Sort by domain, then repository, then most recently updated workplan.
|
||||
// The axis labels show each domain/repo group once.
|
||||
const chartWs = [..._chartWsFiltered].sort((a, b) => {
|
||||
const domainCompare = (a.domain ?? "").localeCompare(b.domain ?? "");
|
||||
|
|
@ -289,7 +289,7 @@ const chartWs = [..._chartWsFiltered].sort((a, b) => {
|
|||
const _isTimeBased = !_STATUS_MODES.has(_chartModeValue) && !_HEALTH_MODES.has(_chartModeValue);
|
||||
function _wsWeight(s) { return (isClosedWorkstream(s) || normalizeWorkstreamStatus(s) === "blocked") ? "bold" : "normal"; }
|
||||
|
||||
// ── y-axis: domain/repo label for first workstream per repository only ────────
|
||||
// ── y-axis: domain/repo label for first workplan per repository only ────────
|
||||
const _yLabels = {};
|
||||
const _seen = new Set();
|
||||
for (const w of chartWs) {
|
||||
|
|
@ -321,24 +321,24 @@ function _wsTitle(d) {
|
|||
// ── Render ────────────────────────────────────────────────────────────────────
|
||||
if (chartWs.length === 0) {
|
||||
const _emptyMsg = {
|
||||
proposed: "No proposed workstreams.",
|
||||
ready: "No ready workstreams.",
|
||||
active: "No active workstreams.",
|
||||
blocked: "No blocked workstreams.",
|
||||
backlog: "No backlog workstreams.",
|
||||
finished: "No finished workstreams.",
|
||||
archived: "No archived workstreams.",
|
||||
needs_review: "No ready workstreams need review.",
|
||||
stalled: "No stalled workstreams — everything is moving.",
|
||||
"1h": "No workstreams changed in the last hour.",
|
||||
"1d": "No workstreams changed in the last 24 hours.",
|
||||
"7d": "No workstreams changed in the last 7 days.",
|
||||
"30d": "No workstreams changed in the last 30 days.",
|
||||
today: "No workstreams changed today.",
|
||||
week: "No workstreams changed this week.",
|
||||
month: "No workstreams changed this month.",
|
||||
proposed: "No proposed workplans.",
|
||||
ready: "No ready workplans.",
|
||||
active: "No active workplans.",
|
||||
blocked: "No blocked workplans.",
|
||||
backlog: "No backlog workplans.",
|
||||
finished: "No finished workplans.",
|
||||
archived: "No archived workplans.",
|
||||
needs_review: "No ready workplans need review.",
|
||||
stalled: "No stalled workplans — everything is moving.",
|
||||
"1h": "No workplans changed in the last hour.",
|
||||
"1d": "No workplans changed in the last 24 hours.",
|
||||
"7d": "No workplans changed in the last 7 days.",
|
||||
"30d": "No workplans changed in the last 30 days.",
|
||||
today: "No workplans changed today.",
|
||||
week: "No workplans changed this week.",
|
||||
month: "No workplans changed this month.",
|
||||
};
|
||||
display(html`<p style="color:gray">${_emptyMsg[_chartModeValue] ?? "No workstreams."}</p>`);
|
||||
display(html`<p style="color:gray">${_emptyMsg[_chartModeValue] ?? "No workplans."}</p>`);
|
||||
} else {
|
||||
display(Plot.plot({
|
||||
y: {
|
||||
|
|
@ -445,7 +445,7 @@ const decCount = (decisions.open ?? 0) + (decisions.escalated ?? 0);
|
|||
const statusEl = html`<div>
|
||||
<div class="grid grid-cols-4" style="gap:1rem;margin-bottom:0.75rem">
|
||||
<a class="card card-link" href="./workstreams">
|
||||
<h3>Active Workstreams</h3>
|
||||
<h3>Active Workplans</h3>
|
||||
<p class="big-num">${ws.active ?? 0}</p>
|
||||
<small>${ws.blocked ?? 0} blocked</small>
|
||||
</a>
|
||||
|
|
@ -510,7 +510,7 @@ const typeBadgeClass = {
|
|||
};
|
||||
|
||||
if (nextSteps.length === 0) {
|
||||
display(html`<p class="ns-empty">No actionable suggestions right now — all open workstreams are making progress or waiting on decisions.</p>`);
|
||||
display(html`<p class="ns-empty">No actionable suggestions right now — all open workplans are making progress or waiting on decisions.</p>`);
|
||||
} else {
|
||||
display(html`<div class="ns-grid">${nextSteps.map(s => html`
|
||||
<div class="ns-card">
|
||||
|
|
@ -543,7 +543,7 @@ if (regs.length === 0) {
|
|||
```
|
||||
|
||||
```js
|
||||
// Registered domains with no workstreams yet — show a getting-started hint
|
||||
// Registered domains with no workplans yet — show a getting-started hint
|
||||
const regs = pageState.milestones ?? [];
|
||||
const registeredDomains = new Set(regs.map(e => e.detail?.domain).filter(Boolean));
|
||||
const emptyRegistered = (summary.topics ?? []).filter(t =>
|
||||
|
|
@ -553,9 +553,9 @@ const emptyRegistered = (summary.topics ?? []).filter(t =>
|
|||
if (emptyRegistered.length > 0) {
|
||||
display(html`<div class="hint-box">
|
||||
<strong>💡 Getting started</strong>
|
||||
<p>These registered projects have no workstreams yet:</p>
|
||||
<p>These registered projects have no workplans yet:</p>
|
||||
<ul>${emptyRegistered.map(t => html`<li>
|
||||
<strong>${t.domain_slug}</strong> — open repo in Claude Code and say <em>"Hi!"</em> to kick off first session, or run <code>custodian create-workstream --domain ${t.domain_slug} --title "My first workstream"</code> manually
|
||||
<strong>${t.domain_slug}</strong> — open repo in Claude Code and say <em>"Hi!"</em> to kick off first session, or create a workplan file under <code>workplans/</code> and run <code>statehub fix-consistency</code>
|
||||
</li>`)}</ul>
|
||||
</div>`);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue