feat(260924-i8v): Serverliste mit Kennzahl, Auswahlfilter, Links und Minutentakt der Proxmox-Kachel

- Zeilen nach down, warn, ok, idle, orphan mit genau einer Kennzahl, unbekannt statt 0
- config.serverIds filtert Liste und Balken, nur geloeschte Kennungen: eigener Satz
- Ansichtsmodus Links auf /modules/proxmox, Bearbeitungsmodus ohne Links
- Groessenstufen per Container-Query, Nachladen alle 60 s, pausiert bei verborgenem Tab
- formatPercent/formatCount einmal in components/proxmox, ServerCard nutzt sie

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-24 13:28:43 +02:00
parent 92bf1307f6
commit a217d606bb
6 changed files with 366 additions and 68 deletions
@@ -2,16 +2,10 @@
import Link from 'next/link';
import { useLocale, useTranslations } from 'next-intl';
import type {
ProxmoxErrorKind,
ProxmoxPbsMetrics,
ProxmoxPmgMetrics,
ProxmoxProductType,
ProxmoxPveMetrics,
ProxmoxServer,
} from '@/lib/proxmox-api';
import {
formatAge,
formatCount,
formatPercent,
isBackupStale,
meterLevel,
ratio,
@@ -20,6 +14,14 @@ import {
toEpochMs,
} from '@/components/proxmox/proxmox-status';
import { HEALTH_STYLE, METER_FILL, METER_TEXT, WELL } from '@/components/proxmox/status-styles';
import type {
ProxmoxErrorKind,
ProxmoxPbsMetrics,
ProxmoxPmgMetrics,
ProxmoxProductType,
ProxmoxPveMetrics,
ProxmoxServer,
} from '@/lib/proxmox-api';
type Translator = ReturnType<typeof useTranslations>;
@@ -50,16 +52,6 @@ function formatBytePair(used: number | null, total: number | null, locale: strin
return `${nf.format(used / divisor)} / ${nf.format(total / divisor)} ${BYTE_UNITS[exponent]}`;
}
function formatPercent(fraction: number, locale: string): string {
return new Intl.NumberFormat(locale, { style: 'percent', maximumFractionDigits: 0 }).format(
fraction,
);
}
function formatCount(value: number, locale: string): string {
return new Intl.NumberFormat(locale).format(value);
}
/** Exakter Zeitpunkt fuer das `title`-Attribut der relativen Angaben. */
function exactTime(value: number | string | null | undefined, locale: string): string | undefined {
const ms = toEpochMs(value);