feat(260924-i8v): Proxmox-Kachel als Durchstich mit Balken und Zusammenfassung

- Typ proxmox am Ende von WIDGET_TYPES, WIDGET_MODULE_SLUGS = { proxmox: 'proxmox' }
- gemeinsame Statusteile (proxmox-status, HealthBar, status-styles) nach components/proxmox/
- HealthBar variant compact: 6 px, ohne Legende, aria-hidden
- Registry 3/4/8/8, Katalog-/Registry-/API-Tests auf die erste Modul-Kachel umgestellt
- ProxmoxWidget liest nur listServers, zeigt Lade-, Leer-, Fehlerzustand

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-24 13:24:51 +02:00
parent 8bfa4fc467
commit a906c6705d
19 changed files with 556 additions and 69 deletions
@@ -0,0 +1,32 @@
import { HEALTH_ORDER, type ServerHealth } from '@/components/proxmox/proxmox-status';
/**
* Reine Funktionen der Proxmox-Kachel (quick-260924-i8v) — ohne React,
* damit jede Verzweigung einzeln pruefbar ist (Muster `picture-frame-config.ts`).
* Die Statuslogik selbst (Zustand je Server, Schwellen, Sortierung) kommt
* aus `components/proxmox/proxmox-status.ts` und wird hier nicht kopiert.
*/
export interface HealthSummary {
/** Es gibt Server, und keiner weicht von „in Ordnung“ ab. */
allOk: boolean;
/** Alle Zustaende ausser `ok` mit Anzahl > 0, in `HEALTH_ORDER`. */
entries: Array<{ health: ServerHealth; count: number }>;
/** Schlimmster vorhandene Zustand (erster in `HEALTH_ORDER` mit Anzahl > 0). */
worst: ServerHealth | null;
}
/**
* Zusammenfassung fuer die Zeile unter dem Balken: „Alles in Ordnung“ oder
* die Abweichungen („1 nicht erreichbar, 1 mit Warnung“). Die Anzahl `ok`
* wird bewusst nicht genannt — die Zeile soll sagen, was zu tun ist.
*/
export function healthSummary(counts: Record<ServerHealth, number>): HealthSummary {
const entries = HEALTH_ORDER.filter((h) => h !== 'ok' && counts[h] > 0).map((health) => ({
health,
count: counts[health],
}));
const total = HEALTH_ORDER.reduce((sum, h) => sum + counts[h], 0);
const worst = HEALTH_ORDER.find((h) => counts[h] > 0) ?? null;
return { allOk: total > 0 && entries.length === 0, entries, worst };
}