docs(quick-260924-h7x): Proxmox-Status-Design und Reiter in der Kopfzeile
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+173
@@ -0,0 +1,173 @@
|
||||
---
|
||||
quick_id: 260924-h7x
|
||||
type: quick
|
||||
wave: 1
|
||||
autonomous: true
|
||||
files_modified:
|
||||
- apps/web/src/app/globals.css
|
||||
- apps/web/src/app/(portal)/modules/proxmox/page.tsx
|
||||
- apps/web/src/app/(portal)/modules/proxmox/components/ServerCard.tsx
|
||||
- apps/web/src/app/(portal)/modules/proxmox/components/proxmox-status.ts (new)
|
||||
- apps/web/src/app/(portal)/modules/proxmox/components/*.test.tsx
|
||||
- apps/web/src/components/layout/header.tsx
|
||||
- apps/web/src/components/dashboard/dashboard-tabs.tsx
|
||||
- apps/web/src/app/(portal)/page.tsx
|
||||
- apps/web/src/messages/de.json, en.json
|
||||
- CHANGELOG.md
|
||||
---
|
||||
|
||||
# Quick 260924-h7x — Proxmox-Seite: Status-Design mit Tiefe; Dashboard-Reiter in die Kopfzeile
|
||||
|
||||
Nutzerauftrag (24.09.): „Kennzeichnen als offline & verwaist. Das Proxmox-Modul scheint zu
|
||||
funktionieren, aber es gefällt mir optisch gar nicht. Benutze den Design-Skill und überarbeite
|
||||
etwas — mehr Tiefe, Farben nach Status etc. Die Reiter sind da, aber die müssen woanders hin,
|
||||
die nehmen zu viel Platz ein. Auch mit Design.“
|
||||
|
||||
Die frühere Sperre „KEIN Umbau der Proxmox-Modulseite“ (23.09.) ist damit durch den Nutzer
|
||||
selbst aufgehoben.
|
||||
|
||||
Design-Plan vom Orchestrator (frontend-design-Skill) — verbindlich, nicht neu erfinden.
|
||||
Keine neuen Pakete. App-Texte deutsch in Sie-Form, alle Schlüssel in de.json UND en.json.
|
||||
Keine Großbuchstaben-Etiketten (kein `uppercase`, kein `tracking-widest`), keine
|
||||
Mittelpunkt-Ketten „A · B · C“ in neuen Texten, kein „→“ an Knöpfen.
|
||||
|
||||
## Design-Tokens (in `globals.css`, `:root` und `.dark`)
|
||||
|
||||
Statusfarben als OKLCH-Variablen plus Tailwind-Abbildung in `@theme inline`
|
||||
(`--color-status-ok` usw., damit `bg-status-ok`, `text-status-ok`, `border-status-ok/40` gehen):
|
||||
|
||||
| Token | hell | dunkel | Bedeutung |
|
||||
|---|---|---|---|
|
||||
| `--status-ok` | `oklch(0.62 0.15 152)` | `oklch(0.72 0.15 152)` | in Ordnung |
|
||||
| `--status-warn` | `oklch(0.72 0.15 70)` | `oklch(0.80 0.14 75)` | Warnung |
|
||||
| `--status-down` | `oklch(0.58 0.21 27)` | `oklch(0.68 0.19 27)` | nicht erreichbar / Fehler |
|
||||
| `--status-idle` | `oklch(0.62 0.02 260)` | `oklch(0.60 0.02 260)` | noch nicht abgefragt |
|
||||
| `--status-orphan` | `oklch(0.55 0.01 260)` | `oklch(0.52 0.01 260)` | offline & verwaist |
|
||||
| `--well` | `oklch(0.975 0.003 260)` | `oklch(0.235 0.01 260)` | eingelassene Messfelder |
|
||||
|
||||
Kontrast prüfen: Text in Statusfarbe auf `--card` muss ≥ 4.5:1 (Fließtext) bzw. ≥ 3:1
|
||||
(große/fette Zahlen) erreichen — sonst Helligkeit anpassen und die gemessene Zahl in der
|
||||
SUMMARY nennen.
|
||||
|
||||
## Task 1 — Statuslogik als reine Funktionen (TDD)
|
||||
|
||||
Neue Datei `components/proxmox-status.ts`:
|
||||
|
||||
- `serverHealth(server): 'ok' | 'warn' | 'down' | 'idle' | 'orphan'`
|
||||
- `!server.isActive` → `orphan` (VORRANG vor allem anderen — „offline & verwaist“, auch wenn
|
||||
alte Messwerte im Zwischenlager liegen)
|
||||
- kein `status` oder `status.lastPolledAt === null` → `idle`
|
||||
- `!status.reachable` → `down`
|
||||
- erreichbar + irgendein Messwert über Warnschwelle → `warn`
|
||||
- sonst `ok`
|
||||
- Schwellen als EINE benannte Konstante `THRESHOLDS`: Last/Arbeitsspeicher/Datenspeicher
|
||||
warn ≥ 0.80, kritisch ≥ 0.92; PBS letzte Sicherung älter als 26 h → warn; `lastVerifyState`
|
||||
ungleich `ok` (und nicht null) → warn; PMG `virusCount > 0` → warn.
|
||||
- `meterLevel(fraction | null): 'ok' | 'warn' | 'crit' | 'unknown'` für die Balken.
|
||||
- `formatAge(epochSeconds|iso, now)` → „vor 3 Min.“, „vor 5 Std.“, „vor 2 Tagen“ über
|
||||
`Intl.RelativeTimeFormat('de')` bzw. next-intl — keine neue Abhängigkeit.
|
||||
- Tests für jede Verzweigung inkl. `null`-Werte (unbekannt ≠ 0, nie Warnung aus `null`).
|
||||
|
||||
## Task 2 — Proxmox-Seite und Karte neu gestalten
|
||||
|
||||
**Seitenkopf:** Titel „Proxmox“ links, darunter die Beschreibung. Rechts „Jetzt aktualisieren“
|
||||
(nur Admins, wie heute) als richtiger Knopf mit Kreispfeil-Symbol (dreht sich während des Laufs;
|
||||
`motion-reduce:animate-none`) und „Einstellungen“ als ruhiger Textlink. Breite `max-w-5xl`.
|
||||
|
||||
**Gesundheitsbalken (das eine prägnante Element der Seite):** direkt unter dem Kopf ein
|
||||
waagrechter Balken, 8 px hoch, voll gerundet, anteilig in Segmente je Zustand geteilt
|
||||
(Reihenfolge down, warn, ok, idle, orphan; leere Zustände entfallen). Darunter eine Zeile mit
|
||||
Legende: farbiger Punkt + Zahl + Wort („2 in Ordnung“, „1 nicht erreichbar“, „1 offline &
|
||||
verwaist“ …, ICU-Plural). Segmente `role="img"` mit `aria-label`, das die Zusammenfassung vorliest.
|
||||
Keine Zahl-in-riesig-plus-Verlauf-Heldenkachel.
|
||||
|
||||
**Kartenraster:** `grid gap-4 lg:grid-cols-2`. Sortierung: down, warn, ok, idle, orphan, darin
|
||||
`position`. (Die Einstellungsseite behält ihre Reihenfolge.)
|
||||
|
||||
**Karte (Tiefe über Status, nicht Einheits-Schatten):**
|
||||
- Karte `rounded-xl bg-card` mit Rand `border-border`, links eine 4 px breite Statusleiste
|
||||
(absolut positioniert, volle Höhe, Farbe = Status).
|
||||
- Schatten zweischichtig und im Statuston getönt, z. B.
|
||||
`shadow-[0_1px_2px_oklch(0_0_0/0.06),0_12px_28px_-14px_var(--status-x)]` — bei `orphan` KEIN
|
||||
farbiger Schatten, stattdessen gestrichelter Rand (`border-dashed`), Inhalt
|
||||
`opacity-70 saturate-50`.
|
||||
- Kopfzeile: Produktsymbol (kleines inline-SVG je Typ: PVE = Server-Einschübe, PBS =
|
||||
Archivkiste/Datenträger, PMG = Briefumschlag) in einem 32 px Feld mit `bg-well`, daneben Name
|
||||
(fett) und darunter Produktname ausgeschrieben („Virtualisierung“, „Datensicherung“,
|
||||
„Mail-Gateway“) plus Adresse klein und gedämpft. Rechts eine Statuspille: Punkt + Wort
|
||||
(„In Ordnung“, „Warnung“, „Nicht erreichbar“, „Noch nicht abgefragt“, „Offline & verwaist“),
|
||||
Hintergrund Statusfarbe /12, Text in Statusfarbe. Bei `ok` pulsiert der Punkt EINMAL beim
|
||||
Laden nicht — keine Dauer-Animation.
|
||||
- Fuß der Karte: „Letzte Abfrage vor 4 Min.“ (relativ, `title` mit exaktem Zeitpunkt).
|
||||
|
||||
**Messbereich je Produkt, als eingelassene Felder** (`bg-well`, `rounded-lg`,
|
||||
`shadow-[inset_0_1px_2px_oklch(0_0_0/0.06)]`):
|
||||
- **PVE:** oben zwei Kennzahlen nebeneinander: laufende Gäste (groß, `tabular-nums`) und
|
||||
gestoppte Gäste (gedämpft), Knotenzahl klein. Darunter je Knoten ein „Einschub“: Knotenname
|
||||
links, rechts zwei schmale Balken „Prozessor“ und „Arbeitsspeicher“ mit Prozentzahl
|
||||
(`tabular-nums`) und bei Speicher „12,0 / 64,0 GB“ als `title`/kleine Zeile. Balkenfarbe
|
||||
nach `meterLevel`. Unbekannter Wert: Balken schraffiert/leer + Text „unbekannt“, NIE 0 %.
|
||||
Deutsche Zahlformate (Komma) über `Intl.NumberFormat('de-DE')`.
|
||||
- **PBS:** je Datenspeicher ein Einschub: Name, Füllstandsbalken mit „1,2 / 4,0 TB“, darunter
|
||||
„Letzte Sicherung vor 5 Std.“ (warn-Farbe, wenn > 26 h; „noch keine Sicherung“ gedämpft) und
|
||||
Prüfstatus als kleine Pille (ok grün, sonst warn, null „unbekannt“ grau).
|
||||
- **PMG:** vier Zahlfelder im 2×2-Raster: Eingehend, Ausgehend, Spam, Viren; Viren > 0 in
|
||||
down-Farbe, sonst normal. `null` → „unbekannt“.
|
||||
|
||||
**Zustände ohne Messwerte:**
|
||||
- `down`: roter Hinweisblock im Well (`bg-status-down/8`, Rand links in Statusfarbe) mit der
|
||||
bekannten Fehlermeldung (`errors.*`) und darunter gedämpft „Zuletzt erreichbar: vor 2 Tagen“
|
||||
bzw. nichts, wenn nie. `errorDetail` klein und gedämpft in eigener Zeile, nicht in Klammern
|
||||
an den Satz gehängt.
|
||||
- `idle`: ruhiger Text wie heute (Admin-/Nicht-Admin-Variante bleibt, 260923-le6).
|
||||
- `orphan`: Text „Dieser Server ist deaktiviert und wird nicht mehr abgefragt.“ plus für Admins
|
||||
der Hinweis, dass er in den Einstellungen wieder aktiviert werden kann (Link). Alte Messwerte
|
||||
werden bei `orphan` NICHT angezeigt.
|
||||
|
||||
**Leer-, Lade-, Fehlerzustand der Seite:** Leerzustand als Well mit Serversymbol und Satz +
|
||||
Link (Admins); Laden als zwei Skelett-Karten (`animate-pulse`, `motion-reduce:animate-none`).
|
||||
|
||||
Tests: bestehende ServerCard-/Seitentests anpassen (Texte/Strukturen), neue Tests für
|
||||
orphan (Vorrang, keine alten Werte), Sortierung, Gesundheitsbalken-Zusammenfassung, unbekannte
|
||||
Werte als „unbekannt“. Die Nur-Admin-Regeln aus 260923-le6 müssen weiter getestet sein.
|
||||
|
||||
## Task 3 — Dashboard-Reiter in die Kopfzeile
|
||||
|
||||
Heute belegt `DashboardTabs` eine eigene Zeile über dem Raster (`app/(portal)/page.tsx`), die
|
||||
Kopfzeilenmitte (`components/layout/header.tsx`) zeigt nur den Text „Startseite“.
|
||||
|
||||
- Kopfzeile bekommt in der Mitte einen Einhängepunkt `<div id="header-center-slot">`. Auf der
|
||||
Startseite (`pathname === '/'`) entfällt der Text „Startseite“; auf allen anderen Seiten bleibt
|
||||
alles wie heute.
|
||||
- `DashboardTabs` rendert per `createPortal` in diesen Einhängepunkt (sobald er im DOM ist —
|
||||
`useEffect` + State; Rückfall: solange kein Einhängepunkt da ist, nichts rendern). Die eigene
|
||||
Zeile über dem Raster entfällt ersatzlos.
|
||||
- Gestaltung als kompakter Umschalter mit Tiefe: eine eingelassene Spur (`bg-muted`, `rounded-lg`,
|
||||
`p-0.5`, `shadow-[inset_0_1px_2px_oklch(0_0_0/0.08)]`, Höhe 32 px), darin die Reiter als
|
||||
Textknöpfe (`text-sm`, `px-3`, `h-7`); der aktive Reiter liegt erhaben darauf (`bg-card`,
|
||||
`shadow-sm`, `font-medium`, Text `foreground`), inaktive gedämpft mit Hover. Keine
|
||||
Unterstreichung, kein Gelb-Flächen-Reiter.
|
||||
- Viele Reiter: Spur höchstens `max-w-[min(56vw,720px)]`, waagrecht scrollbar ohne sichtbare
|
||||
Leiste, an den Rändern weich ausgeblendet (`mask-image` nur wenn überläuft), aktiver Reiter
|
||||
wird ins Bild gescrollt.
|
||||
- Bearbeitungsmodus: Umbenennen/Löschen/Ziehen/Anlegen bleiben funktional gleich (alle
|
||||
bestehenden Tests grün halten bzw. nur Selektoren anpassen). „+“ als 28-px-Rundknopf am Ende
|
||||
der Spur (immer sichtbar, wie heute der Anlegen-Knopf sichtbar ist — Verhalten beibehalten).
|
||||
Löschen-Kreuz erscheint im Bearbeitungsmodus klein im Reiter.
|
||||
- Genau EIN Reiter: Umschalter trotzdem zeigen (sonst weiß niemand, dass es Reiter gibt), aber
|
||||
nur mit „+“ daneben.
|
||||
- Mobil (< md): die Spur darf die Kopfzeilenmitte füllen; Logo-Schriftzug bleibt, Aktionen rechts
|
||||
bleiben erreichbar — nichts darf die Kopfzeile sprengen (overflow prüfen).
|
||||
- Tastatur: Pfeiltasten links/rechts zwischen Reitern (`role="tablist"`/`tab`, `aria-selected`),
|
||||
sichtbarer Fokusring.
|
||||
- `navigation "Dashboard-Reiter"`-Beschriftung bleibt als `aria-label`.
|
||||
|
||||
Tests: dashboard-tabs.test.tsx an Portal anpassen (Einhängepunkt im Test anlegen), neuer Test:
|
||||
Kopfzeile zeigt „Startseite“ nicht auf `/`, aber auf anderen Pfaden; Pfeiltasten.
|
||||
|
||||
## Tore
|
||||
|
||||
- `pnpm --filter web exec vitest run` komplett grün
|
||||
- `pnpm turbo run type-check lint` grün, Biome-Warnungen web nicht mehr als 53
|
||||
- CHANGELOG „Unveröffentlicht“: je ein Eintrag unter „Neu“/„Geändert“ in Nutzersprache
|
||||
- Browser-Nachweis macht der Orchestrator (hell UND dunkel, 1400 px und 390 px Breite)
|
||||
+172
@@ -0,0 +1,172 @@
|
||||
---
|
||||
quick_id: 260924-h7x
|
||||
phase: quick
|
||||
plan: 260924-h7x
|
||||
subsystem: web / proxmox-modul, dashboard, kopfzeile
|
||||
status: complete
|
||||
tags: [proxmox, design, statusfarben, dashboard-reiter, kopfzeile, a11y]
|
||||
requires: [quick-260923-dhh (Proxmox-Modul), quick-260923-le6 (Nur-Admin-Regeln), quick-260923-ad9 (Dashboard-Reiter)]
|
||||
provides:
|
||||
- Statuslogik proxmox-status.ts (serverHealth, THRESHOLDS, meterLevel, formatAge, Sortierung, Zusammenfassung)
|
||||
- Statusfarben-Tokens --status-* / --status-*-fg / --well in globals.css
|
||||
- Einhaengepunkt header-center-slot in der Kopfzeile
|
||||
affects:
|
||||
- apps/web/src/app/(portal)/modules/proxmox/*
|
||||
- apps/web/src/components/dashboard/dashboard-tabs.tsx
|
||||
- apps/web/src/components/layout/header.tsx
|
||||
tech-stack:
|
||||
added: []
|
||||
patterns:
|
||||
- Statusklassen als statische Tailwind-Zeichenketten (status-styles.ts), damit Tailwind sie findet
|
||||
- Tests mit echtem NextIntlClientProvider + de.json statt Uebersetzungs-Attrappe (ICU-Plural, Zahlformate mitgeprueft)
|
||||
- createPortal in einen Kopfzeilen-Einhaengepunkt, Rueckfall = nichts rendern
|
||||
key-files:
|
||||
created:
|
||||
- apps/web/src/app/(portal)/modules/proxmox/components/proxmox-status.ts
|
||||
- apps/web/src/app/(portal)/modules/proxmox/components/proxmox-status.test.ts
|
||||
- apps/web/src/app/(portal)/modules/proxmox/components/HealthBar.tsx
|
||||
- apps/web/src/app/(portal)/modules/proxmox/components/status-styles.ts
|
||||
- apps/web/src/components/layout/header-slot.ts
|
||||
modified:
|
||||
- apps/web/src/app/globals.css
|
||||
- apps/web/src/app/(portal)/modules/proxmox/page.tsx
|
||||
- apps/web/src/app/(portal)/modules/proxmox/components/ServerCard.tsx
|
||||
- apps/web/src/app/(portal)/modules/proxmox/components/ServerCard.test.tsx
|
||||
- apps/web/src/app/(portal)/modules/proxmox/proxmox-page-roles.test.tsx
|
||||
- apps/web/src/components/dashboard/dashboard-tabs.tsx
|
||||
- apps/web/src/components/dashboard/dashboard-tabs.test.tsx
|
||||
- apps/web/src/components/layout/header.tsx
|
||||
- apps/web/src/components/layout/header.test.tsx
|
||||
- apps/web/src/app/(portal)/page.tsx
|
||||
- apps/web/src/messages/de.json
|
||||
- apps/web/src/messages/en.json
|
||||
- apps/web/src/messages/umlaut-dictionary.ts
|
||||
- CHANGELOG.md
|
||||
decisions:
|
||||
- Statusfarben bekommen eine Textvariante --status-*-fg; die Flaechentoene aus dem Plan bleiben fuer Balken, Punkte und Leisten, erreichen als Schrift auf Weiss aber nur 2,6 bis 4,9:1
|
||||
- Bei „offline & verwaist“ werden nur Symbol und Name gedaempft; gedaempfte muted-Schrift fiele unter 3:1
|
||||
- Der „+“-Knopf der Reiter bleibt wie bisher nur im Bearbeitungsmodus sichtbar, sitzt aber ausserhalb der scrollenden Spur („immer sichtbar“ = nie weggescrollt)
|
||||
- Pfeiltasten verschieben nur den Fokus, gewaehlt wird mit Eingabe/Leertaste (ein Reiterwechsel laedt das ganze Dashboard)
|
||||
- Ziehhinweis als sr-only-Beschreibung der Spur plus Tooltip statt eigener Zeile
|
||||
metrics:
|
||||
duration: 16min
|
||||
completed: 2026-09-24
|
||||
tasks: 3
|
||||
files: 19
|
||||
plan_head_before: 3d266418fc83f4b0e5f5240f0fcd5017aebe0d10
|
||||
actuals:
|
||||
tokens: 35900
|
||||
tasks: 3
|
||||
commits: 4
|
||||
---
|
||||
|
||||
# Quick 260924-h7x: Proxmox-Seite mit Status-Design, Dashboard-Reiter in der Kopfzeile
|
||||
|
||||
Die Proxmox-Seite zeigt den Zustand jetzt über Farbe und Tiefe: oben ein Gesundheitsbalken mit Legende, darunter Karten, sortiert nach Zustand, mit Statusleiste, im Statuston getöntem Schatten und Statuspille. Die Messwerte liegen in eingelassenen Feldern mit Balken, relativen Zeitangaben und deutschem Zahlformat. Deaktivierte Server erscheinen als „Offline & verwaist“, ohne veraltete Messwerte. Die Dashboard-Reiter sitzen als kompakter Umschalter per Portal in der Mitte der Kopfzeile.
|
||||
|
||||
## Was gebaut wurde
|
||||
|
||||
**Task 1 — Statuslogik (TDD, 0fa7ce0).** `proxmox-status.ts` enthält nur reine Funktionen:
|
||||
- `serverHealth`: `orphan` hat Vorrang vor allem anderen, dann `idle`, `down`, `warn`, `ok`.
|
||||
- `THRESHOLDS` ist die einzige Quelle für die Schwellen: 0,80 Warnung, 0,92 kritisch, 26 h Sicherungsalter.
|
||||
- `meterLevel`, `ratio`, `isBackupStale`, `sortServersByHealth`, `summarizeHealth`.
|
||||
- `formatAge` nutzt `Intl.RelativeTimeFormat` und liefert „vor 3 Min.“, „vor 5 Std.“, „vor 2 Tagen“ sowie „jetzt“ unter einer Minute.
|
||||
|
||||
Ein `null` löst nirgends eine Warnung aus. 24 Tests. Die RED-Phase war belegt, weil das Modul fehlte.
|
||||
|
||||
**Task 2 — Seite und Karte (57c338f, Nachbesserung 0b659d6).**
|
||||
- **Tokens:** `--status-ok/warn/down/idle/orphan` und `--well` nach der Tabelle im Plan, jeweils hell und dunkel. Dazu kommt eine Textvariante `--status-*-fg` (Begründung unter Kontrast). Alle Tokens sind in `@theme inline` abgebildet. Mit einem Tailwind-Probelauf ist nachgewiesen, dass `bg-status-ok/12`, `bg-status-down/8`, `bg-well`, die getönten Schatten und `motion-reduce:animate-none` wirklich erzeugt werden.
|
||||
- **Kopf:** Titel und Beschreibung stehen links. Rechts steht „Einstellungen“ als ruhiger Textlink, danach „Jetzt aktualisieren“ als Hauptknopf mit Kreispfeil. Der Kreispfeil dreht sich während des Laufs, bei reduzierter Bewegung nicht. Beides ist nur für Admins sichtbar. Die Seitenbreite ist `max-w-5xl`.
|
||||
- **Gesundheitsbalken:** 8 px hoch, anteilig geteilt in der Reihenfolge down, warn, ok, idle, orphan. Leere Zustände entfallen. Der Balken ist `role="img"` und liest die Zusammenfassung vor, zum Beispiel „Zustand der Server: 1 nicht erreichbar, 2 in Ordnung“. Die Legende zeigt Punkt, fette Zahl und Wort über ICU-Plural.
|
||||
- **Karte:** Statusleiste links, 4 px breit. Zweischichtiger, im Statuston getönter Schatten; bei `orphan` gibt es keinen farbigen Schatten, sondern einen gestrichelten Rand. Das Produktsymbol steht in einem 32-px-Well (Server-Einschübe, Archivkiste, Briefumschlag). Darunter stehen Name, ausgeschriebener Produktname und Adresse. Die Statuspille hat keine Animation. Im Fuß steht „Letzte Abfrage vor 4 Min.“, der exakte Zeitpunkt liegt im `title`.
|
||||
- **PVE:** Laufende Gäste groß, gestoppte gedämpft, dazu die Knotenzahl. Je Knoten ein Einschub mit Balken für Prozessor und Arbeitsspeicher und „12,0 / 64,0 GB“. Unbekannte Werte erscheinen als schraffierte Spur mit „unbekannt“, nie als 0 %.
|
||||
- **PBS:** Je Datenspeicher der Füllstand mit „1,2 / 4,0 TB“ und „Letzte Sicherung vor 5 Std.“; bei mehr als 26 h in Warnfarbe. Dazu eine Prüfpille: grün bei ok, Warnfarbe bei anderem Ergebnis, grau bei „unbekannt“.
|
||||
- **PMG:** Ein 2×2-Raster aus Zahlfeldern. Viren über 0 stehen in der Fehlerfarbe.
|
||||
- **Zustände:**
|
||||
- `down`: Hinweisblock mit linkem Rand. Die Fehlermeldung steht im Klartext, `errorDetail` in einer eigenen Zeile, darunter „Zuletzt erreichbar vor 2 Tagen“.
|
||||
- `idle`: Admin- und Nicht-Admin-Text wie bisher.
|
||||
- `orphan`: Hinweissatz; Admins bekommen zusätzlich einen Verweis auf die Einstellungen.
|
||||
- Laden: zwei Skelettkarten.
|
||||
- Keine Server: Well mit Symbol.
|
||||
- **Aktuelle Zeitangaben:** Ein Minutentakt hält die relativen Zeitangaben aktuell.
|
||||
|
||||
**Task 3 — Reiter in der Kopfzeile (7416a92).**
|
||||
- **Einhängepunkt:** Die Kopfzeile rendert einen leeren `#header-center-slot`. Die Kennung steht in `components/layout/header-slot.ts`. Auf `/` entfällt „Startseite“, auf allen anderen Seiten bleibt alles wie bisher. Die Kopfzeilenmitte ist `min-w-0`, Logo und Aktionen rechts sind `shrink-0`.
|
||||
- **Portal:** `DashboardTabs` rendert per `createPortal` in den Einhängepunkt. Ohne Einhängepunkt rendert die Leiste nichts. Die eigene Zeile über dem Raster ist entfallen.
|
||||
- **Gestaltung:** Eine eingelassene Spur (`bg-muted`, inset-Schatten, 32 px), darauf liegt der aktive Reiter erhaben (`bg-card`, `shadow-sm`, `font-medium`).
|
||||
- **Überlauf:** Die Spur ist `max-w-[min(56vw,720px)]` breit, auf Mobilgeräten volle Breite. Sie scrollt ohne sichtbare Leiste. Die Ränder werden über `mask-image` weich ausgeblendet, aber nur bei Überlauf. Der aktive Reiter wird ins Bild gescrollt.
|
||||
- **Tastatur:** `role="tablist"`/`tab` mit `aria-selected` und wanderndem `tabIndex`. Pfeil links/rechts, Pos1 und Ende bewegen den Fokus, mit Umlauf. Der Fokusring ist sichtbar.
|
||||
- **Bearbeitungsmodus:** Der „+“-Knopf ist ein 28-px-Rundknopf außerhalb der Spur. Umbenennen und Löschen sitzen klein im Reiter. Der Löschdialog hängt am Dokumentkörper statt im Stapelkontext der Kopfzeile. Die Beschriftung `navigation "Dashboard-Reiter"` bleibt.
|
||||
|
||||
**CHANGELOG** unter „Unveröffentlicht“: ein Eintrag unter „Neu“ (Proxmox-Seite) und ein neuer Abschnitt „Geändert“ (Reiter in der Kopfzeile).
|
||||
|
||||
## Kontrast (gemessen, WCAG-Formel, OKLCH → sRGB)
|
||||
|
||||
Die Flächentöne aus dem Plan erreichen als Schrift auf `--card` (hell) nur diese Werte:
|
||||
|
||||
| Token | hell | dunkel |
|
||||
|---|---|---|
|
||||
| ok | 3,41 | 6,46 |
|
||||
| warn | 2,55 | 7,92 |
|
||||
| down | 4,76 | 4,80 |
|
||||
| idle | 3,64 | 3,82 |
|
||||
| orphan | 4,85 | 2,74 |
|
||||
|
||||
Nach der Planregel wurde deshalb die Helligkeit angepasst, und zwar als eigene Textvariante `--status-*-fg`. Die Flächentöne bleiben wie geplant.
|
||||
|
||||
| Textvariante | hell auf card | hell auf Pille (12 %) | dunkel auf card | dunkel auf Pille |
|
||||
|---|---|---|---|---|
|
||||
| ok `0.50 0.13 152` / `0.76 0.15 152` | 5,64 | 4,94 | 7,44 | 6,02 |
|
||||
| warn `0.52 0.12 60` / `0.82 0.14 75` | 5,72 | 5,15 | 8,47 | 6,63 |
|
||||
| down `0.52 0.20 27` / `0.74 0.16 27` | 6,11 | 5,10 | 6,09 | 5,24 |
|
||||
| idle `0.50 0.02 260` / `0.72 0.02 260` | 6,00 | 5,28 | 6,08 | 5,24 |
|
||||
| orphan `0.50 0.01 260` / `0.70 0.01 260` | 6,00 | 5,17 | 5,64 | 5,06 |
|
||||
|
||||
Alle Werte liegen bei mindestens 4,5:1. Gedämpfte Schrift auf verwaisten Karten (`opacity-70`) hätte bei `muted-foreground` nur 2,75:1 (hell) bzw. 3,02:1 (dunkel). Deshalb wird dort nur der Name in Vordergrundfarbe gedämpft (7,54 bzw. 7,13).
|
||||
|
||||
Die Fläche `warn` hat im hellen Modus als Grafik 2,55:1 zu Weiß. Balken und Punkte in Warnfarbe stehen aber immer neben einer Zahl oder einem Wort, die Farbe trägt die Aussage also nicht allein.
|
||||
|
||||
## Abweichungen vom Plan
|
||||
|
||||
**1. [Rule 2 – Kontrast] Textvariante der Statusfarben.** Der Plan erlaubt ausdrücklich, die Helligkeit anzupassen. Umgesetzt ist das als zusätzliches `-fg`-Token und nicht als Änderung der Flächentöne, damit Balken und Leisten die geplante Leuchtkraft behalten. Betrifft `globals.css` und `status-styles.ts`.
|
||||
|
||||
**2. [Rule 2 – Kontrast] Dämpfung bei „verwaist“ eingegrenzt.** Der Plan sieht `Inhalt opacity-70 saturate-50` vor. Umgesetzt ist das nur an Symbol und Name. Pille, Produktname, Adresse, Hinweis und Fuß bleiben voll lesbar, weil gedämpfte Schrift unter 3:1 fiele. Commit 0b659d6.
|
||||
|
||||
**3. Auslegung „+“ „immer sichtbar“.** Der Knopf bleibt wie bisher nur im Bearbeitungsmodus sichtbar, so verlangt es „Verhalten beibehalten“ und bestehender Test 4. Er sitzt jedoch außerhalb der scrollenden Spur, damit er nie weggescrollt wird.
|
||||
|
||||
**4. Zusätzliche Dateien:**
|
||||
- `HealthBar.tsx` und `status-styles.ts` (Proxmox): die Klassen werden an zwei Stellen gebraucht.
|
||||
- `components/layout/header-slot.ts`: die Kopfzeile soll nicht die Reiter-Komponente importieren.
|
||||
- `umlaut-dictionary.ts`: „Prozessor“ und „Arbeitsspeicher“ sind korrektes Deutsch mit „ss“ und stehen jetzt auf der Freigabeliste der Umlaut-Wache.
|
||||
|
||||
**5. Übersetzungsschlüssel.** Nicht mehr genutzte Schlüssel wurden ersetzt:
|
||||
- aus `card.pve.*`: `nodeCount`, `guests`
|
||||
- aus `card.pbs.*`: `lastBackup`, `verifyState`
|
||||
- aus `card.*`: `lastPolledLabel`, `lastOkLabel`
|
||||
|
||||
Neu sind `health.*`, `legend.*`, `card.product.*` und weitere. Die Änderungen stehen in de.json und en.json gleichermaßen.
|
||||
|
||||
**6. Formatierung.** `biome format` wurde auf die geänderten Proxmox-Dateien angewendet. Dadurch ist auch `proxmox-status.ts` aus Task 1 in Commit 57c338f rein umformatiert.
|
||||
|
||||
## Tore
|
||||
|
||||
- `pnpm --filter web exec vitest run`: 87 Dateien, 789 Tests grün. Proxmox allein: 65.
|
||||
- `pnpm turbo run type-check lint`: 9/9 erfolgreich.
|
||||
- Biome-Warnungen web: 53, nicht mehr als vorher (53).
|
||||
- Verbotene Muster: kein `uppercase`, kein `tracking-widest`, keine Mittelpunkt-Ketten und kein „→“ in den neuen Dateien (per grep geprüft).
|
||||
- Den Browser-Nachweis (hell/dunkel, 1400 px/390 px) macht wie vereinbart der Orchestrator. Docker wurde nicht neu gebaut.
|
||||
|
||||
## Hinweise für die Browser-Prüfung
|
||||
|
||||
- **Mobile Kopfzeile bei 390 px:** Rechnerisch bleiben für die Mitte etwa 80 px, also etwa ein Reiter sichtbar, der Rest ist scrollbar. Im Bearbeitungsmodus kommen 28 px für „+“ dazu. Bitte prüfen, dass nichts überläuft.
|
||||
- **Ränder der Spur:** Die weiche Ausblendung erscheint nur bei Überlauf. Mit drei oder mehr langen Reiternamen kann man das prüfen.
|
||||
- **Verwaiste Karte:** gestrichelter Rand, graue Leiste, kein farbiger Schatten, keine alten Messwerte.
|
||||
|
||||
## Known Stubs
|
||||
|
||||
Keine.
|
||||
|
||||
## Self-Check: PASSED
|
||||
|
||||
- FOUND: proxmox-status.ts, proxmox-status.test.ts, HealthBar.tsx, status-styles.ts, header-slot.ts
|
||||
- FOUND: 0fa7ce0, 57c338f, 7416a92, 0b659d6
|
||||
Reference in New Issue
Block a user