# UI Information Architecture ## Asset Page Required section order: 1. `Current Components` 2. `Previous Components` (directly below Current Components) 3. `Movement & Events` (timeline cards) `Previous Components` lists components that were previously installed on the asset and are currently removed. Asset card editing contract: - Card has `Edit` toggle. - In edit mode: - Read-only card fields switch to editable inputs. - `Edit` button changes to `Save`. - `Cancel` button appears next to `Save`. - `Save` persists changes through `PUT /registry/assets/{id}`. - `Cancel` reverts unsaved form values and returns to read-only mode. ## Component Page Required content: - Component card including current firmware - Installation history table with: - Asset - Installed At - Removed At - Timeline is rendered as grouped cards (not raw event rows), same interaction model as asset page. ## Timeline UX (Asset + Component Pages) Timeline rendering rules: - Timeline UI renders **cards grouped by day**, not a flat list of raw `timeline_events`. - Multiple events of the same visual action in one day are **visually deduplicated** by `action + context`. - Correlated mass operations (`correlation_id`) are shown as a **single bulk card** with affected counts. - Asset timeline has an additional fallback collapse rule for movement cards: - `Installation` / `Removal` events without `correlation_id` are collapsed by `source_type` + `visual_action` + **1-hour bucket**. - `correlation_id` grouping takes precedence over the 1-hour fallback. - Every card shows source label (`Ingest`, `CSV import`, `Manual edit`, `System`) derived from history event `source_type`. - Every card is clickable and opens a **single drilldown modal**: - left pane: concrete events in the card - right pane: details of selected event - no nested modal Scope-specific timeline card content: - On asset page, card summary must not repeat the current asset label in each row/card. - On component page, card summary must not repeat the current component label/serial/model in each row/card. - Instead, show the opposite side of the relation (asset on component page, component on asset page), plus slot/device when available. - Collapsed `Installation` / `Removal` cards render a two-column summary: - left: `Models` as chips (`32x MODEL_A`, `8x MODEL_B`) - right: `Slots` as chips with aggregation (`AOC#[1..4]`) - component serials are not shown in collapsed movement cards - raw event counts are not shown in collapsed movement cards Timeline filters: - Filters are server-side (history timeline API) and include: - date range - action - source - device - slot - `Part number / Model` (v1 maps to `model`) - serial - On component page, filters that are invariant for the current component scope (component serial / part number) are hidden. - On asset page, filters that are invariant for the current asset scope are hidden. Timeline drilldown modal: - Card drilldown uses the same timezone (`tz`) as the visible timeline grouping. - Collapsed `Installation` / `Removal` modal header/meta is human-readable (`Installed N components` / `Removed N components`) and avoids raw `N events` wording. Component card editing contract: - Card has `Edit` toggle with the same mode behavior as asset card (`Edit` -> `Save`, show `Cancel`). - `Save` persists changes through `PUT /registry/components/{id}`. - `Cancel` reverts unsaved form values. ## List Pages Creation flows: - Assets list page provides `New Asset` action that opens modal form and creates entity via `POST /assets`. - Components list page provides `New Component` action that opens modal form and creates entity via `POST /components`. Shared list behavior: - Every table-based list in UI pages must provide pagination in one shared visual style: - Summary: `Showing X–Y of N` - Navigation: `Prev`, page links with ellipsis when needed, `Next` - Query contract: page number is controlled through URL query (`page` for list pages, section-specific keys for multi-list pages such as dashboard). - Every table header must provide per-column text filtering: - A filter input is rendered under each column header. - Input suggestions are populated from current values visible in that table (current page/slice). - Filtering is case-insensitive and applies as substring match. Assets list specifics: - `All Assets` table filtering is server-side and applies to the full dataset before pagination. - `All Assets` supports global bulk selection: - Header `Select` checkbox can select all assets across all pagination pages. - Selected IDs persist across page navigation and are stored in browser local storage. ## Global Search - UI top bar provides a global search form available on all pages. - Global search page (`/ui/search`) searches across: - Assets - Components - Failure events - Results are split by entity type and paginated independently per section. ## Supporting Repositories Required By UI - `timeline.EventRepository.ListLatestBySubjectsAndEventTypes(...)` - `registry.InstallationRepository.ListPreviousComponentsByAsset(...)` - `registry.InstallationRepository.ListInstallationHistoryByComponent(...)`