UI β Resource DashboardΒΆ
A Kubernetes-style operator console hosted by CPA. Each resource kind has a table view; selecting an instance opens a slide-over detail panel. The model behind it is the
TimedResourcetree (resource-model.md); the design decisions are in ADR-048.
GoalsΒΆ
- One console for every resource kind:
Session,SessionPart,PodInstance,Host/Worker, and catalog definitions. - Make desired vs actual state and lifecycle phases first-class in the UI.
- Keep the existing Bootstrap 5 + vanilla web components + SSE stack; grow shared components
in
lcm-core(lcm_ui).
Component viewΒΆ
C4Component
title Component View β Unified Resource Dashboard (in CPA UI subapp)
Person(operator, "Operator")
Container_Boundary(ui, "CPA UI subapp (Bootstrap 5 + web components)") {
Component(nav, "Resource-type nav", "web component", "Lists kinds: Sessions, Parts, Pods, Hosts, Definitions")
Component(table, "Resource table", "shared lcm-core component", "Per-type list, status badges, drill-down")
Component(panel, "Detail slide-over", "shared lcm-core component", "Tabs: overview/lifecycle/history/related/yaml/reports/logs")
Component(actions, "Action bar", "web component", "Declarative (set desired) + imperative (start/stop/grade)")
Component(sse, "SSE client", "web component", "Live status/phase updates")
Component(iframe, "SE report widget", "iframe", "Embeds SE job outputs / reports")
}
Container(api, "CPA API subapp", "FastAPI", "Resource REST + /events/stream (SSE)")
Container(se, "Scenario Engine UI", "FastAPI", "Job outputs / reports")
Rel(operator, nav, "Browses")
Rel(nav, table, "Selects kind")
Rel(table, panel, "Opens instance")
Rel(panel, actions, "Hosts")
Rel(table, api, "GET resources", "HTTPS")
Rel(actions, api, "Set desired / commands", "HTTPS")
Rel(sse, api, "Subscribe", "SSE")
Rel(iframe, se, "Embeds report UI", "HTTPS")
UpdateLayoutConfig($c4ShapeInRow="3", $c4BoundaryInRow="1")
Navigation: per-type lists + drill-downΒΆ
A left nav lists resource kinds. Each opens a table; rows drill down to owned resources (Session β Parts β Pods β Host) via breadcrumbs.
ββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β RESOURCES β Sessions [+ New] [β³ Sync] β
β β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β βΈ Sessions β NAME PROFILE STATUS DESIRED PARTS AGE β
β Parts β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β Pods β ccie-ent-042 ExpertExam β Active Active 3 01:12 β
β Hosts β lab-1.1.1-x9 Lablet β Provis. Ready 1 00:03 β
β βββββββββ β ccde-des-room DesignExpert β Active Active 4 00:48 β
β CATALOG β prac-vmw-7 PracticeLab β Sched. Ready 1 β β
β SessionDef β β
β PartDef β status legend: β ready/active β transitioning β scheduled β
β PodDef β β failed β
β βββββββββ β β
β INFRA β β
β Workers β β
ββββββββββββββββ΄ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Detail: slide-over side panelΒΆ
Selecting a row slides a panel in from the right (the table stays visible). Tabs expose the full resource. Declarative + imperative actions live in the header.
ββββββββββββββββββββββββββββββββββββββββββββββββββββ
Sessions table β β ccie-ent-042 β Active [Set desired βΎ]β
(dimmed) β Session Β· ExpertExam [Reconcile] β
β βββββββββββββββββββββββββββββββββββββββββββββββββ
β Overview | Lifecycle | History | Related | YAML β
β | Reports | Logs β
β βββββββββββββββββββββββββββββββββββββββββββββββββ
β SPEC (desired) STATUS (actual) β
β desired_status: Active status: Active β
β timeslot.start: 09:00 started_at: 09:00 β
β parts: 3 current_part: DOO β
β βββββββββββββββββββββββββββββββββββββββββββββββββ
β PARTS (drill-down) β
β 1 β DES (web, no pod) completed β
β 2 β DOO pod: hw-rack-3 active β
β 3 β AI-DOO pod: cml-aws (JIT) scheduled β
ββββββββββββββββββββββββββββββββββββββββββββββββββββ
Lifecycle tab (desired vs actual phases)ΒΆ
Lifecycle β SessionPart "DOO" engine legend: [P] pipeline [W] workflow
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β instantiate [P] ββ β ready [P] ββ βΆ grade [W] ββ β teardown [P]
β SE job: grade-lab@0.1.0 (running)
desired_status: Active retries: 0/3 last transition: 10:42 by system
History tab (state transitions)ΒΆ
State history β newest first
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
10:42 ready β grading event:student_submit by: system
09:05 provisioning β ready phase:ready complete by: PartMgr
08:55 scheduled β provisioning provision_at reached by: scheduler
Tabs referenceΒΆ
| Tab | Shows |
|---|---|
| Overview | desired_status vs status side by side; key timeslot/lifecycle fields. |
| Lifecycle & phases | phase chain, current vs desired, engine per phase, progress, retries. |
| State history / events | the state_history timeline (StateTransitions). |
| Related | parent, children, and bound host (clickable drill-down). |
| Raw YAML/JSON | the resource spec/status document. |
| Reports & artifacts | SE outputs, embedded as an iframe widget. |
| Live logs | streamed reconcile/automation logs. |
ActionsΒΆ
- Declarative (aligned with the reconciliation framework, ADR-047):
set
desired_status(e.g.Ready,Active,TornDown), retry a phase, force a reconcile. - Imperative (operator break-glass): start/stop/grade/teardown now.
Real-timeΒΆ
The dashboard subscribes to CPA's /events/stream (SSE β ADR-013)
for live status, phase progress, and transitions, with optional filtering by resource kind/ids.
Shared components in lcm-coreΒΆ
Promoted into lcm_ui for reuse across every service UI:
resource-table, resource-detail-panel, status-badge, lifecycle-phases,
state-history-timeline, desired-status-editor, sse-client.
RelatedΒΆ
- resource-model.md β the model the dashboard renders.
- ADR-048 β dashboard decisions.
- ADR-009 β shared core package.