diff --git a/docs/pro-runtime-hardening-workboard.md b/docs/pro-runtime-hardening-workboard.md index 7be3c93..8fb6a52 100644 --- a/docs/pro-runtime-hardening-workboard.md +++ b/docs/pro-runtime-hardening-workboard.md @@ -282,6 +282,7 @@ Einführen eines klaren Betriebsmodells mit Fault-, Recovery- und Muted-Zuständ - Control-plane UI now also offers a Danger Zone `Reset Fault` button that calls the same endpoint so operators can acknowledge faults from the dashboard. - Control-plane UI now posts an ops toast/log entry whenever the runtime state shifts so escalations and manual acknowledgements are immediately visible. +- Control-plane UI now keeps a compact Transition History panel beside the Fault History so operators can see recent runtime shifts without scrolling the activity log. ## Zielzustände laut Konzept @@ -334,6 +335,7 @@ Einführen eines klaren Betriebsmodells mit Fault-, Recovery- und Muted-Zuständ | 2026-04-05 | Manual fault reset endpoint | Added `POST /runtime/fault/reset` so operators can acknowledge `faulted` before the supervisor re-enters recovery. | | 2026-04-05 | Fault-reset UI shortcut | Danger Zone now hosts a Reset Fault button wired to `/runtime/fault/reset` so operators get an in-app acknowledgement path without manual HTTP calls. | | 2026-04-06 | Runtime transition visibility cue | Control UI now posts toast/log entries for runtime state shifts so ops instantly sees escalations and manual reset acknowledgements. | +| 2026-04-06 | Transition history panel | Added a compact Transition History panel next to the Fault History so the last few runtime state shifts stay visible even when the activity log is full. | ## WS-02 Verifikation | Datum | Fokus | Ergebnis | diff --git a/internal/control/ui.html b/internal/control/ui.html index ba94f0c..f3aeb7b 100644 --- a/internal/control/ui.html +++ b/internal/control/ui.html @@ -809,6 +809,45 @@ input.input-error { color: var(--text-muted); font-size: 11px; } +.transition-history { + margin-top: 12px; + padding: 10px; + border: 1px solid var(--border); + border-radius: 6px; + background: var(--surface); + font-size: 11px; + max-height: 180px; + overflow-y: auto; + line-height: 1.3; +} +.transition-history-entry { + display: flex; + justify-content: space-between; + gap: 10px; + padding: 4px 0; + border-bottom: 1px solid rgba(255, 255, 255, 0.08); +} +.transition-history-entry:last-child { + border-bottom: none; +} +.transition-history-entry .transition-history-time { + color: var(--text-dim); +} +.transition-history-entry.good { color: var(--green); } +.transition-history-entry.warn { color: var(--amber); } +.transition-history-entry.err { color: var(--accent); } +.transition-history-entry.info { color: var(--text); } +.transition-history-desc { + font-size: 10px; + flex: 1; + text-transform: uppercase; + letter-spacing: 0.5px; +} +.transition-history-empty { + padding: 6px 0; + color: var(--text-muted); + font-size: 11px; +} .section-note.reset-hint { font-size: 11px; color: var(--text-dim); @@ -1174,6 +1213,20 @@ input.input-error { +