Files
tessera-ctl/.planning/quick/260924-i8v-proxmox-kachel-fuers-dashboard/260924-i8v-SUMMARY.md
T
schalli dd09c08311
Tessera CI/CD / Lint & Type Check (push) Successful in 54s
Tessera CI/CD / Tests (push) Successful in 1m22s
Tessera CI/CD / Desktop-Pakete bauen (push) Successful in 20s
Tessera CI/CD / Build & Publish Images (push) Successful in 3m18s
docs(quick-260924-i8v): Proxmox-Kachel fuers Dashboard
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-24 13:38:17 +02:00

13 KiB
Raw Blame History


quick_id: 260924-i8v phase: quick plan: 260924-i8v subsystem: web / dashboard, proxmox-modul; shared (Kacheltypen); api (Kachel-Modul-Zuordnung) status: complete tags: [proxmox, dashboard, modul-kachel, container-query, statusfarben, a11y] requires: [quick-260922-m1h (Modul bringt Kachel mit), quick-260924-h7x (Statussprache Proxmox), quick-260923-dhh (Proxmox-Modul)] provides:

  • Kacheltyp proxmox (WIDGET_TYPES zuletzt, WIDGET_MODULE_SLUGS = { proxmox: 'proxmox' })
  • ProxmoxWidget mit Balken, Zusammenfassung, Serverliste, Minutentakt, Bearbeitungsmodus
  • gemeinsamer Ordner apps/web/src/components/proxmox/ (Statuslogik, HealthBar compact, Stile, Zahlformat, Serverauswahl)
  • ProxmoxWidgetConfigForm fuer Einstellungen > Dashboard affects:
  • apps/web/src/app/(portal)/modules/proxmox/* (Importpfade, Zahlformat aus gemeinsamer Datei)
  • apps/web/src/components/dashboard/widget-registry.tsx, (portal)/page.tsx
  • apps/web/src/components/settings/widget-settings-panel.tsx
  • apps/api/src/dashboard/widget-module-map.* (Zuordnung jetzt nicht mehr leer) tech-stack: added: [] patterns:
    • Modul-Kachel liest nur das Zwischenlager des Moduls, nie eine Live-Abfrage (Grep-Tor + Spion im Test)
    • Zeilen im Ansichtsmodus Links, im Bearbeitungsmodus schlichte Elemente (Abbruch-Selektor des Rasters)
    • Groessenstufen per Container-Query am Wrapper-Rumpf, kein innerer Container
    • Zeitgeber-Tests faelschen nur setInterval bzw. setTimeout, damit die Warte-Helfer der Testing Library laufen key-files: created:
    • apps/web/src/components/dashboard/widgets/proxmox-widget.tsx
    • apps/web/src/components/dashboard/widgets/proxmox-widget.test.tsx
    • apps/web/src/components/dashboard/widgets/proxmox-widget-model.ts
    • apps/web/src/components/dashboard/widgets/proxmox-widget-model.test.ts
    • apps/web/src/components/proxmox/proxmox-server-picker.tsx
    • apps/web/src/components/proxmox/proxmox-server-picker.test.tsx
    • apps/web/src/components/settings/proxmox-widget-config-form.tsx
    • apps/web/src/components/settings/proxmox-widget-config-form.test.tsx moved:
    • apps/web/src/components/proxmox/proxmox-status.ts (git mv aus app/(portal)/modules/proxmox/components/)
    • apps/web/src/components/proxmox/proxmox-status.test.ts (git mv)
    • apps/web/src/components/proxmox/HealthBar.tsx (git mv)
    • apps/web/src/components/proxmox/status-styles.ts (git mv) modified:
    • packages/shared/src/index.ts
    • apps/api/src/dashboard/widget-module-map.ts
    • apps/api/src/dashboard/widget-module-map.spec.ts
    • apps/web/src/app/(portal)/modules/proxmox/page.tsx
    • apps/web/src/app/(portal)/modules/proxmox/components/ServerCard.tsx
    • apps/web/src/app/(portal)/page.tsx
    • apps/web/src/app/(portal)/page.test.tsx
    • apps/web/src/components/dashboard/widget-registry.tsx
    • apps/web/src/components/dashboard/widget-registry.test.tsx
    • apps/web/src/components/dashboard/widget-catalog-modal.test.tsx
    • apps/web/src/components/settings/widget-settings-panel.tsx
    • apps/web/src/components/settings/widget-settings-panel.test.tsx
    • apps/web/src/messages/de.json
    • apps/web/src/messages/en.json
    • docs/anleitung-anwender.md
    • docs/anleitung-entwicklung.md
    • CHANGELOG.md decisions:
  • Die Kachel zeigt im Zustand „ausgewählte Server gibt es nicht mehr“ bei offener Auswahl direkt die Auswahl statt des Satzes, damit sich der Zustand an Ort und Stelle beheben lässt
  • „Server auswählen“ erscheint nur, wenn eine Serverliste geladen und nicht leer ist
  • Speichern aus der Kachel (Titel, Auswahl) fängt Fehler still ab; der nächste Ladevorgang zeigt den gespeicherten Stand
  • Die Kennzahl bei PVE-Warnung fällt auf die Gästezahl zurück, falls kein einziger Auslastungswert bekannt ist metrics: duration: 22min completed: 2026-09-24 tasks: 3 files: 29 plan_head_before: 8bfa4fc467 actuals: tokens: 29800 tasks: 3 commits: 6

Quick 260924-i8v: Proxmox-Kachel fürs Dashboard

Die erste echte Modul-Kachel: „Proxmox“ zeigt oben einen 6 px hohen Gesundheitsbalken und darunter in Worten „Alles in Ordnung“ oder zum Beispiel „1 nicht erreichbar, 1 mit Warnung“ in der Farbe des schlimmsten Zustands. Darunter stehen die Server nach Dringlichkeit, jeder mit Statuspunkt, Name und genau einer Kennzahl. Ein Klick führt zur Modulseite. Die Kachel liest nur das Zwischenlager, frischt sich minütlich auf, lässt sich auf Titel und Serverauswahl einstellen und stuft sich per Container-Query ab.

Was gebaut wurde

Aufgabe 1: Durchstich (a906c67)

  • Die vier gemeinsamen Dateien (proxmox-status.ts samt Test, HealthBar.tsx, status-styles.ts) liegen jetzt per git mv unter apps/web/src/components/proxmox/. Die Git-Historie bleibt erhalten. Modulseite und ServerCard importieren sie über @/components/proxmox/.... An der Logik hat sich nichts geändert.
  • HealthBar hat eine neue Variante variant="compact": 6 px hoch (h-1.5), ohne Legende und mit aria-hidden. Die Variante full ist Standard, die Modulseite sieht unverändert aus. Beide tragen data-variant.
  • packages/shared: 'proxmox' steht am Ende von WIDGET_TYPES, dazu WIDGET_MODULE_SLUGS = { proxmox: 'proxmox' }. Der Kommentar „bewusst leer“ ist in beiden Dateien korrigiert, in shared und in widget-module-map.ts.
  • Registry: 3/4/8/8 mit Rechenkommentar, Inline-Symbol mit Server-Einschüben, moduleSlug: WIDGET_MODULE_SLUGS.proxmox.
  • registerWidget('proxmox', ProxmoxWidget) steht in (portal)/page.tsx, das passende vi.mock im Seitentest.
  • Die bestehenden Tests sind nachgezogen:
    • Die Registry kennt zehn Typen. Nur proxmox trägt einen Modul-Slug. Die Tests für einen unbekannten Typ nutzen jetzt 'gibt-es-nicht'.
    • Der Katalog zeigt zehn Kacheln bei ['proxmox'], neun bei []. Mit null fehlt Proxmox, und zwar an der echten Kachel statt an der vorher nur vorübergehend umgebauten Uhr.
    • Die API-Spec prüft getModuleSlugForWidgetType('proxmox') === 'proxmox'.

Aufgabe 2: Serverliste (RED 92bf130, GREEN a217d60)

  • formatPercent und formatCount sind unverändert aus ServerCard.tsx nach proxmox-status.ts gezogen. ServerCard importiert sie von dort, damit das Zahlformat nicht doppelt existiert.
  • Die reinen Funktionen in proxmox-widget-model.ts:
    • resolveProxmoxWidgetConfig liest die Konfiguration abwehrend: Nicht-Strings und leere Kennungen fallen weg, doppelte zählen einmal.
    • selectServers: leere Auswahl bedeutet alle Server; bleiben nur gelöschte Kennungen, wird selectionGone gesetzt.
    • widgetKeyFigure wählt die eine Kennzahl je Zeile:
      • Status bei down, idle und orphan
      • Gäste bei PVE im Normalzustand, bei PVE-Warnung der höchste bekannte Anteil aus CPU, RAM und Speicher
      • bei PBS die älteste bekannte Sicherung samt Hinweis, ob sie veraltet ist
      • bei PMG countIn
      • sonst unknown, nie 0
  • Kachel:
    • Die gefilterte Liste speist Balken, Zusammenfassung und Zeilen, sortiert nach sortServersByHealth.
    • Je Zeile ein Punkt, der Name (bei orphan nur der Name mit opacity-70) und das Zustandswort als sr-only.
    • Die Kennzahl steht rechts mit @max-[15rem]:hidden. Wiederholt sie nur den Zustand, ist sie aria-hidden.
    • Die Liste trägt [@container(max-height:7.5rem)]:hidden @max-[8rem]:hidden.
    • Im Ansichtsmodus ist jede Zeile ein next/link auf /modules/proxmox. Im Bearbeitungsmodus ist sie ein div ohne Tabstopp, das gilt auch für den Admin-Link im Leerzustand.
    • Takt: REFRESH_MS = 60_000, bei verborgenem Tab kein Abruf, visibilitychange zurück auf sichtbar lädt sofort. Beim Aushängen wird aufgeräumt.
    • Scheitert ein späteres Nachladen, bleibt die zuletzt geladene Liste stehen.

Aufgabe 3: Einstellen, Doku, Tore (RED 377b6e3, GREEN 586da44, Doku 602a45c)

  • ProxmoxServerPicker:
    • ein fieldset mit der Legende „Angezeigte Server“ und dem sichtbaren Hinweis „Ohne Auswahl zeigt die Kachel alle Server.“
    • je Server ein Kästchen, sortiert nach position, Name plus Produktwort, eindeutige Kennungen per useId
    • onChange liefert die Kennungen in Listenreihenfolge und nur für vorhandene Server. Kennungen gelöschter Server räumen sich dabei selbst auf.
  • Kachel im Bearbeitungsmodus:
    • pt-5 unter der Griffleiste. Die Kopfzeile erscheint immer, mit Titelfeld (widgetNoDrag, 1500 ms entprellt, updateWidgetConfig({ title })) und dem Textknopf „Server auswählen“ (aria-expanded, data-no-drag).
    • Die offene Auswahl ersetzt den Listenbereich in einer Hülle mit widgetNoDrag. Sie bekommt die ungefilterte, schon geladene Liste; ein zusätzlicher Abruf findet nicht statt.
    • Eine Änderung filtert sofort und speichert { serverIds }. Beim Verlassen des Bearbeitungsmodus schließt die Auswahl.
  • ProxmoxWidgetConfigForm (Titel proxmox-widget-title plus Auswahl) ist unter Einstellungen > Dashboard eingehängt. Die Instanz-Kopfzeile zeigt „Proxmox #1 — Titel“.
  • Doku:
    • Anwenderdoku: Tabellenzeile „Proxmox“, Aufzählung der zusätzlichen Einstellungen, Absatz „Dashboard > Widgets“, Absatz im Abschnitt „### Proxmox“.
    • Entwicklerdoku: Proxmox als erstes Beispiel unter „Eine Kachel zum Modul“, mit dem Ort components/proxmox/.
    • CHANGELOG: ein Punkt unter „Unveröffentlicht > Neu“.

Abweichungen vom Plan

  1. [Rule 1, Kommentar] apps/api/src/dashboard/widget-module-map.ts stand nicht in der Dateiliste. Sein Kopfkommentar behauptete aber weiterhin „Die Tabelle ist bewusst leer“. Korrigiert ist nur der Kommentar, der Code ist unverändert (a906c67).
  2. Zeitgeber-Tests: Statt vi.useFakeTimers() ohne Einschränkung werden nur setInterval/clearInterval gefälscht, beim Entprell-Test nur setTimeout/clearTimeout. Grund: findBy/waitFor der Testing Library laufen über setTimeout und blieben mit vollständig gefälschten Zeitgebern unter Vitest hängen. Die geforderten Nachweise sind unverändert erbracht (60 s, verborgen, sichtbar, Aushängen).
  3. Auswahl im Zustand „Server gibt es nicht mehr“: Ist die Auswahl im Bearbeitungsmodus offen, zeigt die Kachel dort die Auswahl statt des Satzes. Der Satz selbst fordert dazu auf, im Bearbeitungsmodus andere Server zu wählen, und das ist so an Ort und Stelle möglich.
  4. Biome: Importreihenfolge in ServerCard.tsx und Formatierung der neuen Dateien mit biome check --write angeglichen. Die Reihenfolge verschob sich durch den neuen @/components-Pfad. Keine Logikänderung.

Keine Architekturfragen, keine neuen Pakete, keine Anmelde-Sperren.

Tore (gemessen)

Tor Ergebnis
Web-Tests vollständig (vitest run) 91 Dateien, 864 Tests grün
API-Tests vollständig (vitest run) 84 Dateien, 1370 Tests grün, darunter src/prisma/rls-access-inventory.spec.ts (30 Tests, einzeln nachgeprüft)
pnpm turbo run type-check lint 9 von 9 Aufgaben erfolgreich
Biome-Warnungen Web 53 (Grenze 53); die neuen Dateien sind warnungsfrei
Stil-Grep (uppercase, tracking-widest, Mittelpunkt, Pfeil, dangerouslySetInnerHTML) leer
Abfrage-Grep pollServer in Kachel, Modell, Auswahl, Formular 0 Treffer außerhalb von Kommentaren
Übersetzungen widgets.proxmox.* (15 Schlüssel) in de und en vollständig; die Umlaut-Wache ist grün
Tailwind-Probelauf (Wegwerfskript im Scratchpad, danach gelöscht) @container (width < 15rem), @container (width < 8rem) und @container (max-height:7.5rem) werden erzeugt
any, !, biome-ignore in neuen Dateien keine

TDD: Die RED-Phase ist im Verlauf belegt: Test-Commit 92bf130 vor a217d60 und Test-Commit 377b6e3 vor 586da44. Die Tests schlugen aus dem richtigen Grund fehl: fehlende Exporte, Zeilen und Module.

Hinweise für den Browser-Nachweis

  • Die Kachel braucht einen neu gebauten Web-Container, also --build. Docker wurde vom Executor nicht angefasst.
  • Zeilen tragen data-testid="proxmox-row" und data-server-name, die Kennzahl data-testid="proxmox-key-figure", die Liste data-testid="proxmox-list", die Zusammenfassung data-testid="proxmox-summary", der Balken data-testid="health-bar" mit data-variant="compact".
  • Größenstufen: bei 4 Spalten (rund 216 px, also unter 15rem = 240 px) nur Punkte und Namen. Bei 3×4 (104 px hoch, unter 7.5rem = 120 px) nur Balken und Zusammenfassung.
  • Netzwerk: im Minutentakt nur GET /modules/proxmox/servers. Beim Öffnen von „Server auswählen“ gibt es keinen weiteren Abruf.
  • Im Bearbeitungsmodus sind Titelfeld, Knopf und Auswahlhülle vom Ziehen ausgenommen. Die Zeilen sind keine Links, die Kachel bleibt über ihnen ziehbar.

Bewusst offen

  • Einstellungen > Dashboard zeigt weiterhin nur die Kacheln des ersten Reiters (bekannte Grenze aus quick-260923-ad9). Deshalb gibt es Titel und Serverauswahl zusätzlich direkt an der Kachel.
  • Lokaler Titel- und Auswahlzustand der Kachel wird wie bei den Favoriten nur beim Einhängen aus config gelesen. Eine Änderung unter Einstellungen > Dashboard wirkt auf eine gleichzeitig offene Dashboard-Seite erst nach dem Neuladen.

Known Stubs

Keine.

Self-Check: PASSED

  • Alle angelegten Dateien vorhanden: proxmox-widget.tsx, proxmox-widget-model.ts, beide Tests, proxmox-server-picker.tsx samt Test, proxmox-widget-config-form.tsx samt Test, die vier verschobenen Dateien unter components/proxmox/.
  • Alle Commits vorhanden: a906c67, 92bf130, a217d60, 377b6e3, 586da44, 602a45c.