Files
dashboards/.agents/phases/complete/25_masthead_control_placement/00_phase.md
T
ducoterra 2bf236fd92 phase: 25_masthead_control_placement
**Phase 25 final verification pass** (all 3 tasks were already in `complete/`, so this was the phase-level verify + docs pass)

**Verified**
- `#nav-status` first child of `.masthead-right` on all 7 signed-in templates (incl. `/certs`, `/settings`); `app.js`/`charts.js` untouched
- `#nav-status` + `.masthead-right` both `justify-content: flex-end`, `margin-inline-start` still absent, row-break (`flex-wrap` + two `flex-basis: 100%`), non-sticky bar, dropdown slide + 4 close paths, `setInterval(refreshStatus, 15000)` all intact (dash.css diff = comments + the two alignment values)
- Clock is the last control on all 7 templates; no `order:` anywhere in the bar

**Fixed (defects found in this pass)**
- `tests/test_api.py::test_every_page_links_to_both_admin_pages` — duplicated `tabs = html[...]` statement (task 03 edit artifact)
- `certs.html` / `settings.html` comments said "all **eight** signed-in pages"; the signed-in set is seven (`/login` is the eighth, anonymous, and has no links/clock)
- `AGENTS.md` — suite tally `1542 → 1543 passed`; "the three phase-20 tests" re-worded, since task 02 renamed one to `test_the_masthead_is_three_rows_right_justified_at_every_width`

**Results**
- `uv run pytest` → **1543 passed, 15 skipped**, 0 failed
- `bash .agents/validate.sh` → **exit 0**: coverage **98.94 %** (floor 94 %), `ruff` All checks passed, `pyright` 0 errors, `node --check` clean, hygiene clean
- `uv run pytest -m live --live` (`.env.dev` sourced) → **11 passed**; `./scripts/dev-server.sh status` → 9/9 sources `ok`
- Browser: `node data/logs/25-task03-verify.cjs` → **235 checks, 0 FAIL**, exit 0 (`data/logs/25-task03-verify.out`, 16 `masthead-25-*.png`)

**Completion criteria**: badges pinned+measured (green `system/disks/llm/ups` on both admin pages, 1280 px and 360 px) ✅ · both rows flush right, three rows + dropdown unchanged (pinned + measured) ✅ · clock farthest-right (pinned markup; measured right edge 1260.0 at 1280 px, ≤900 px hidden by the long-standing readout rule with source order asserted) ✅ · pytest/coverage/ruff/pyright ✅ · validate.sh ✅ · no behaviour change in completed work ✅

**Docs**: README reviewed end-to-end against the code (served-route audit vs documented routes, env table vs `config.py`, commands vs `scripts/`, public-path table, `web/` masthead bullet) — consistent, no changes needed beyond the phase's own edits. AGENTS.md — two fixes above; spot-checked every doc-named test, function, script, threshold, `install-agent.sh` sha256 (`ffbcd91f…` matches) and agent version (1.1.0).

**Deviations**: left the pre-existing `fastapi 0.153.0 → 0.159.0` advisory (validate prints it as advisory; no dependency work in scope, AGENTS rule 8 triggers on touching deps). No live-infra changes. Overview's "all eight signed-in pages" for the clock is verified against seven templates + `/login` (which has no clock, pinned).

**Next pending phase**: `.agents/phases/todo/26_ups_event_split/` (3 tasks).
2026-10-21 16:42:14 -04:00

5.4 KiB
Raw Blame History

Phase 25 — Masthead control placement: badges everywhere, right-justified, clock rightmost

Source: TODO.md L3–L5 — "hosts disks engines UPS disappear when in the certs/account page" · "I made a mistake earlier, I did want hosts disks engines UPS badges and certs/account/dark right justified don the navbar" · "The time should show up as the farthest right item on the navbar" Story: n/a Context: phase 20 (complete) — the masthead is three rows at every width (row 1 brand + #nav-toggle + the five tabs, row 2 the #nav-status per-source dots, row 3 the .masthead-right controls), not sticky (position: relative, z-index: 40), with the ≤640px dropdown sliding on nav.tabs.is-open; phase 18 — the hamburger reveal through --nav-toggle-display. The dots are built by Dash.initChrome() in src/dashboards/web/static/app.js (the if (nav) block on #nav-status, one chip per system/disks/llm/ups dashboard from /api/health, refreshed every 15 s), and exist in the markup only of the five dashboard pages — certs.html and settings.html ship no #nav-status (the comment in settings.html says a session page "has no fleet reachability to report"), which is what L3 names. The served-CSS pins for the bar are in tests/test_api.py: test_the_masthead_is_three_left_justified_rows_at_every_width (the two justify-content: flex-start declarations, the two flex-basis: 100% row breaks, the min-height/gap), test_the_mobile_masthead_block_declares_no_second_bar_height, test_the_masthead_scrolls_away_and_stays_the_dropdown_anchor; the one-loop control-order audit is test_every_page_links_to_both_admin_pages (clock → ⚷ Certs → ⚙ Account → theme toggle on all eight signed-in pages), and the two pins that assert the admin pages have no dots are in test_the_settings_page_is_not_one_of_the_dashboards and test_the_certs_page_is_a_page_and_not_a_sixth_dashboard. tests/test_auth_api.py asserts /login carries no #nav-status — unchanged by this phase.

Objective

The four per-source badges (hosts · disks · engines · UPS) render on every page that renders the masthead — including /certs and /settings — and the two right-hand rows (the dots, the controls) are right-justified, with the clock the farthest-right item on the bar. The three-row shape at every width is preserved; only the alignment and the control order move, and the clock's position is what L5 asks for.

Dependencies

  • — (none) — the phase builds on complete phase 20 and phase 18; it is scheduled first of the three appended phases on purpose, because the mobile audit phase (27) measures the masthead in the shape this phase leaves it in.

Tasks

  1. 01_status_dots_on_admin_pages.md — #nav-status on /certs and /settings (markup only — initChrome already builds the dots when the container exists); the two no-dots pins flip to dots-present
  2. 02_right_justify_masthead_rows.md — justify-content: flex-end on #nav-status and .masthead-right, the comment block re-worded, the three-rows pin re-pinned to the new alignment
  3. 03_clock_rightmost.md — the clock moves to the end of the control row on all eight signed-in pages; the one-loop order pin updated; the phase's real-browser verification (badges on the admin pages, both rows right-justified, clock rightmost, at 1280 px and 360 px)

Testing & Quality

  • Unit/integration: the served-byte pins in tests/test_api.py — the flipped admin-page pins (task 01), the re-pinned row-alignment pin (task 02), the updated control-order pin (task 03); tests/test_auth_api.py's /login-has-no-dots pin must stay green untouched
  • Coverage: >90% on new/modified code (the new code is the pins themselves; the change is CSS and template markup)
  • Real-browser check (invariant 10): a data/logs/25-task03-*.cjs script in the 20-task01-rows.cjs convention, run against the restarted dev server at 1280 px and 360 px on all seven tabbed pages plus /login (unsigned), with screenshots in data/logs/

Documentation & Consistency

  • The final pass updates the now-stale sentences in AGENTS.md: "The masthead is three left-justified rows at every width" (alignment), "A page with no dots (/certs, /settings) renders two rows" (gone — all masthead pages carry the dots), "the two links therefore sit on all eight signed-in pages in one order (clock → ⚷ Certs → ⚙ Account → theme toggle)" (new order: ⚷ Certs → ⚙ Account → theme toggle → clock), and the "left-justified" wording in the dash.css header comment. README.md is checked for the same sentences; none is expected.

Completion Criteria

  • /certs and /settings render the four badges, populated from /api/health (pinned + verified in a browser against the live dev fleet)
  • the dots row and the controls row are right-justified at every width; the three-row shape and the ≤640px dropdown are unchanged (pinned + measured in a browser)
  • the clock is the farthest-right item on the bar on all eight signed-in pages (pinned + measured)
  • uv run pytest green, coverage not down, ruff + pyright clean
  • bash .agents/validate.sh green
  • no behavior change in completed work: the row-break mechanism (flex-wrap + the two flex-basis: 100%), the non-sticky bar, the dropdown's slide and its four close paths, and the dots' refresh semantics are all untouched