fix: normalize overview mode after view input

This commit is contained in:
2026-06-07 15:38:29 +02:00
parent 04366c64bc
commit 0e9a4ea93b
2 changed files with 22 additions and 12 deletions

View File

@@ -239,6 +239,16 @@ function _workstreamsForMode(mode, rows) {
const _savedChartMode = _MODE_VALUES.has(globalThis.__stateHubOverviewChartMode)
? globalThis.__stateHubOverviewChartMode
: "active";
const _chartModeState = Mutable(_savedChartMode);
function _setChartMode(value) {
const mode = _modeValue(value);
globalThis.__stateHubOverviewChartMode = mode;
_chartModeState.value = mode;
}
```
```js
const _modeSelect = html`<select
class="ws-mode-select"
aria-label="Workstream chart mode with matching workstream counts"
@@ -248,23 +258,21 @@ const _modeSelect = html`<select
${group.options.map(([value, label]) => html`<option value=${value}>${label} (${_workstreamsForMode(value, wsAll).length})</option>`)}
</optgroup>`)}
</select>`;
_modeSelect.value = _savedChartMode;
_modeSelect.value = _modeValue(_chartModeState);
_modeSelect.addEventListener("input", () => {
globalThis.__stateHubOverviewChartMode = _modeSelect.value;
_setChartMode(_modeSelect.value);
});
_modeSelect.addEventListener("change", () => {
globalThis.__stateHubOverviewChartMode = _modeSelect.value;
_setChartMode(_modeSelect.value);
});
// view() is the idiomatic Observable Framework reactive input:
// it displays the element AND returns a reactive value that re-runs dependent blocks.
const _chartMode = _modeValue(view(_modeSelect));
display(_modeSelect);
```
```js
import * as Plot from "npm:@observablehq/plot";
const _chartWsFiltered = _workstreamsForMode(_chartMode, wsAll);
const _chartModeValue = _modeValue(_chartModeState);
const _chartWsFiltered = _workstreamsForMode(_chartModeValue, wsAll);
// Sort by domain, then repository, then most recently updated workstream.
// The axis labels show each domain/repo group once.
@@ -278,7 +286,7 @@ const chartWs = [..._chartWsFiltered].sort((a, b) => {
// ── Status weight: bold for notable statuses in mixed-status modes ─────────────
// Color is NOT used for status — avoids green-on-green when finished bars fill the row.
const _isTimeBased = !_STATUS_MODES.has(_chartMode) && !_HEALTH_MODES.has(_chartMode);
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 ────────
@@ -330,7 +338,7 @@ if (chartWs.length === 0) {
week: "No workstreams changed this week.",
month: "No workstreams changed this month.",
};
display(html`<p style="color:gray">${_emptyMsg[_chartMode] ?? "No workstreams."}</p>`);
display(html`<p style="color:gray">${_emptyMsg[_chartModeValue] ?? "No workstreams."}</p>`);
} else {
display(Plot.plot({
y: {

View File

@@ -243,8 +243,10 @@ accurate workstream counts for all mode groups.
`_chartWsFiltered` was computed in the same cell as `view(_modeSelect)`.
Moving `_chartWsFiltered = _workstreamsForMode(_chartMode, wsAll)` into the
downstream chart cell restored filtering when operators choose a mode other
than `active`. Added a `change` listener alongside `input` for persisted mode
selection. `npm run test` and `npm run build` both passed after the fix.
than `active`. A second pass kept `_chartMode` as the raw reactive view value
and normalizes it inside the downstream chart cell before filtering and empty
state selection. Added a `change` listener alongside `input` for persisted
mode selection. `npm run test` and `npm run build` both passed after the fix.
- Browser click-through remains pending because the Codex in-app browser bridge
failed to start in this session with a Windows sandbox setup failure, and no
local Playwright/Puppeteer package is installed for a headless fallback.