Convert the two TODO items into append-mode phases (Protocol B): 18_nav_hamburger (TODO L3) and 19_ups_events_expandable (TODO L4), numbered after the existing todo phases. TODO.md is cleared to an empty list; its items now live in .agents/phases/todo/. LLM-Generated: true
4.7 KiB
Phase 19 — Expandable UPS power-events list
Source: TODO.md L4 — "The UPS tab should have an expandable, clear list of last incidents with dates/times"
Story: n/a
Context: src/dashboards/web/pages/ups.html lines 72–76 (the Power events card: <header><h3> + a ul.events#events holding a loading… placeholder), src/dashboards/web/static/page-ups.js (refreshEvents() at line 430 — fetches /api/events?limit=200&source=ups and hands the rows to Dash.eventsPager with the date/time + severity-chip + host row shape; called unconditionally from refresh() at line 427, which the page's poll(refresh, state.pollMs) loop drives, state.pollMs from config.ups.poll_ms || 5000), src/dashboards/web/static/app.js (Dash.eventsPager — 50 rows a page, paging state in a WeakMap keyed by the <ul>, rows re-written only when their markup changed), src/dashboards/web/static/dash.css (details.charts-box at lines 714–727 — the summary marker ▸/▾, hidden webkit marker, hover; the .events bounded 320px scroll and .events-pager strip), and the pattern this phase mirrors — /system's per-host Charts disclosure (system.html line 81, page-system.js line 315: "a <details> renders nothing, so … nothing is built or drawn while the stack is shut") and its pin test_system_history_charts_are_collapsed_behind_a_toggle
Objective
The /ups power-events list becomes what the TODO asks for — expandable: the card is collapsed by default behind a <details> disclosure in the repo's own charts-box style, nothing is fetched or drawn while it is shut (the /system rule), the first expand fetches and builds, a re-expand paints from the data in hand unless it is stale, and the page's poll loop refreshes the list only while the disclosure is open. The "clear" half already ships and stays: every row carries its date/time, the severity chip, and the host, and the 50-per-page pager bounds the list. No new API surface — the existing /api/events?source=ups is the whole backend.
Dependencies
18_nav_hamburger(todo) — both phases touchups.html(the masthead, the events card); landing 18 first keeps this phase's diff confined to the events section. No shared code between them.
Tasks
01_events_disclosure.md— theups.htmlmarkup: the card body becomes a collapsed-by-default<details class="events-box">02_events_lazy_loading.md—page-ups.js: no fetch while closed, first-expand fetch, re-expand stale rule, poll-while-open03_disclosure_css.md—dash.css: thedetails.events-boxsummary styling in thecharts-boxshape, pager and bounded list inside04_tests_and_verification.md— the served-page pins (disclosure present and unopened, the lazy rule, the unchanged row shape) and the closed/open browser verification
Testing & Quality
- Unit/integration:
tests/test_api.py— the served-page pins (see task 04), alongside the untouchedDash.eventsPagerbehaviour (a re-paint with the same data keeps the reader's page — theWeakMaprule, pinned by the existing event-feed tests) - Coverage: >90% on new/modified code (the phase is markup + JS + CSS; the gate applies to the changed Python test files)
- The phase is "Complete" only when the entire project test suite passes 100% (every test in the project, not just this phase's)
Documentation & Consistency
- The final pass reviews
README.mdandAGENTS.mdin full against the project as it stands after this phase — fixing every inconsistency found, including pre-existing ones not caused by this phase. - AGENTS.md's
UI conventionssection already documents the event pager ("An event feed is a window, not a printout") and the/systemCharts disclosure; it gains the/upsdisclosure's sentence (collapsed by default, lazy-built, poll-while-open, the stale rule) in the section's voice. The README's/upstable row ("power events") stays true — the list is on the page, now behind a summary.
Completion Criteria
/upsloads with the Power events card collapsed (a summary line, no list visible, no/api/eventsrequest in the page's first poll) and the expand shows the bounded, paged list with date/time rows- closing and re-opening within one poll interval paints the cached rows without a refetch; a stale cache refetches on open; while open, the poll loop keeps the list current
uv run pytestgreen, coverage not down,ruff+pyrightcleanbash .agents/validate.shgreen (includingnode --checkof the modifiedpage-ups.js)- closed- and open-state screenshots in
data/logs/against the running dev server (invariant 10) - no behavior change in completed work: every other element on
/ups(cards, charts, dialog, pager behaviour) is unchanged