diff --git a/docs/notes/endpoint-telemetry-and-ui-phases.md b/docs/notes/endpoint-telemetry-and-ui-phases.md index 5537f957..699d48a9 100644 --- a/docs/notes/endpoint-telemetry-and-ui-phases.md +++ b/docs/notes/endpoint-telemetry-and-ui-phases.md @@ -242,24 +242,25 @@ Depends on Phase 2 data existing. until the collection question is settled. - Boot type placement to be decided when the data is visible. - **Storage + Disk health into one card with two collapsible sections** - - AGREED, deferred to its own phase. VISUAL GROUPING ONLY. These two tables - cannot be merged into shared rows: Storage is per volume, Disk health is per - physical device, and one drive can back several volumes or none the operator - sees. This is emphatically NOT the Phase 1 mapped-drive treatment, where two - sources described the same drive and the worse status won. Nothing here gets - reconciled. - Cost, measured rather than guessed: the `tabs` render type is the only - existing sections-in-one-card mechanism and it emits label/value fields only - (PluginAssetPanels.vue), with no table path. Both cards here are `table` - renders with different columns AND different keys, so nothing existing - carries them. Preferred approach is extending `tabs` to support table - sections (~40 lines in the shared renderer plus a helper), then collapsing - the two routes into one returning `sections`. A new `sections` render type is - the alternative but is a larger addition to that fixed set. - Deferred deliberately: this modifies the renderer EVERY plugin uses, so it - needs its own regression tests and must not be bundled with the Phase 2 - telemetry commits - otherwise a UI regression and a telemetry regression - become one commit to bisect. + DONE. VISUAL GROUPING ONLY. These two tables are not merged into shared rows: + Storage is per volume, Disk health is per physical device, and one drive can + back several volumes or none the operator sees. This is emphatically NOT the + Phase 1 mapped-drive treatment, where two sources described the same drive and + the worse status won. Nothing here is reconciled. + Built as predicted: `tabs` was extended to support table sections (columns/ + rows/empty per section) in the shared renderer, and the two routes collapsed + into one `/storage` returning `sections`. `/diskhealth` is kept as a route - + it is a stable read for non-panel callers, and removing it for a UI-only + change would break them. + Two things only found by building it: + - The empty-section filter had to grow a table branch. A table section + declares its columns up front and so must survive having no rows; dropping + it takes its TAB with it, and a missing tab reads as "this machine has no + disks" rather than "nothing was reported". + - Full-width span was keyed off `render === 'table'`. A `tabs` panel holding a + six-column table needs the same span, and whether it does is only knowable + from FETCHED DATA, not the declaration - hence `spansFullWidth()`. + Both are mutation-tested in `tabSectionsTable.spec.js`. Checked and cleared: the "inline label/value pairs, not nested cards" density rule in Phase 5 does NOT block this. That rule is scoped to the PC Details HEADER block, where the constraint is adding zero height so the tab strip is diff --git a/frontend/src/components/PluginAssetPanels.vue b/frontend/src/components/PluginAssetPanels.vue index 922f1509..9966ad9d 100644 --- a/frontend/src/components/PluginAssetPanels.vue +++ b/frontend/src/components/PluginAssetPanels.vue @@ -3,7 +3,7 @@ a panel as JSON (title, endpoint, render mode, field map); this renders it on any asset detail page, so a plugin adds detail-page UI with no Vue. -->