13 KiB
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:
8bfa4fc467actuals: 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.tssamt Test,HealthBar.tsx,status-styles.ts) liegen jetzt pergit mvunterapps/web/src/components/proxmox/. Die Git-Historie bleibt erhalten. Modulseite undServerCardimportieren sie über@/components/proxmox/.... An der Logik hat sich nichts geändert. HealthBarhat eine neue Variantevariant="compact": 6 px hoch (h-1.5), ohne Legende und mitaria-hidden. Die Variantefullist Standard, die Modulseite sieht unverändert aus. Beide tragendata-variant.packages/shared:'proxmox'steht am Ende vonWIDGET_TYPES, dazuWIDGET_MODULE_SLUGS = { proxmox: 'proxmox' }. Der Kommentar „bewusst leer“ ist in beiden Dateien korrigiert, insharedund inwidget-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 passendevi.mockim 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[]. Mitnullfehlt Proxmox, und zwar an der echten Kachel statt an der vorher nur vorübergehend umgebauten Uhr. - Die API-Spec prüft
getModuleSlugForWidgetType('proxmox') === 'proxmox'.
- Die Registry kennt zehn Typen. Nur proxmox trägt einen Modul-Slug. Die Tests für einen unbekannten Typ nutzen jetzt
Aufgabe 2: Serverliste (RED 92bf130, GREEN a217d60)
formatPercentundformatCountsind unverändert ausServerCard.tsxnachproxmox-status.tsgezogen. ServerCard importiert sie von dort, damit das Zahlformat nicht doppelt existiert.- Die reinen Funktionen in
proxmox-widget-model.ts:resolveProxmoxWidgetConfigliest 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, wirdselectionGonegesetzt.widgetKeyFigurewä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 alssr-only. - Die Kennzahl steht rechts mit
@max-[15rem]:hidden. Wiederholt sie nur den Zustand, ist siearia-hidden. - Die Liste trägt
[@container(max-height:7.5rem)]:hidden @max-[8rem]:hidden. - Im Ansichtsmodus ist jede Zeile ein
next/linkauf/modules/proxmox. Im Bearbeitungsmodus ist sie eindivohne Tabstopp, das gilt auch für den Admin-Link im Leerzustand. - Takt:
REFRESH_MS = 60_000, bei verborgenem Tab kein Abruf,visibilitychangezurück auf sichtbar lädt sofort. Beim Aushängen wird aufgeräumt. - Scheitert ein späteres Nachladen, bleibt die zuletzt geladene Liste stehen.
- Die gefilterte Liste speist Balken, Zusammenfassung und Zeilen, sortiert nach
Aufgabe 3: Einstellen, Doku, Tore (RED 377b6e3, GREEN 586da44, Doku 602a45c)
ProxmoxServerPicker:- ein
fieldsetmit 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 peruseId onChangeliefert die Kennungen in Listenreihenfolge und nur für vorhandene Server. Kennungen gelöschter Server räumen sich dabei selbst auf.
- ein
- Kachel im Bearbeitungsmodus:
pt-5unter 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(Titelproxmox-widget-titleplus 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
- [Rule 1, Kommentar]
apps/api/src/dashboard/widget-module-map.tsstand 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). - Zeitgeber-Tests: Statt
vi.useFakeTimers()ohne Einschränkung werden nursetInterval/clearIntervalgefälscht, beim Entprell-Test nursetTimeout/clearTimeout. Grund:findBy/waitForder Testing Library laufen übersetTimeoutund blieben mit vollständig gefälschten Zeitgebern unter Vitest hängen. Die geforderten Nachweise sind unverändert erbracht (60 s, verborgen, sichtbar, Aushängen). - 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.
- Biome: Importreihenfolge in
ServerCard.tsxund Formatierung der neuen Dateien mitbiome check --writeangeglichen. 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"unddata-server-name, die Kennzahldata-testid="proxmox-key-figure", die Listedata-testid="proxmox-list", die Zusammenfassungdata-testid="proxmox-summary", der Balkendata-testid="health-bar"mitdata-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
configgelesen. 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.