oberflaeche v4: Uebersicht als Startseite, KI-Box und Homelab mit Monitoring, Homelab-Updates je Geraet mit Alle aktualisieren, Protokoll, Einstellungsseite, neues Tab-Symbol
- Startseite "Alles auf einen Blick": Gesamtlage, je Bereich Messwerte mit Verlauf, wer welche Updates hat (Kurzform, Klick fuehrt in den Bereich), Hinweise, als Naechstes und zuletzt eingespielt - Menue: Uebersicht, KI-Box (Cockpit, Updates, Modelle, Monitoring), Homelab (Cockpit, Updates, Monitoring, Protokoll), Einstellungen; Bereichsfarben Indigo und Violett; alte Adressen /updates und /modelle leiten weiter - Homelab-Updates je Geraet: App-Version laeuft -> neu (mit Grund, wenn sie wartet), Pakete, Rueckweg, Knoepfe; Alle aktualisieren mit Plan in der Rueckfrage und Fortschritt; Cockpit zeigt die Gesundheit der Geraete - Einstellungen als Seite: KI-Box, Homelab (Arcane-Schluessel, Docker echt/Probelauf, Ausfuehrer), Meldungen, Software-Stand - Diagramme: Verlauf mit Fadenkreuz, Legende und Tabellenansicht, Kennzahlen mit Linie; Farben geprueft - Tab-Symbol: favicon.ico/.svg, apple-touch-icon, Manifest-Icons Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
bf1153cb66
commit
1104200a30
@@ -1,18 +1,22 @@
|
||||
import { useNavigate } from "@tanstack/react-router"
|
||||
import { Link, useNavigate } from "@tanstack/react-router"
|
||||
import { ArrowRight } from "lucide-react"
|
||||
import { Chip, type ChipArt, Zustandsfeld } from "@/components/cockpit/Chip"
|
||||
import { Panel } from "@/components/cockpit/Panel"
|
||||
import { GeraeteListe } from "@/components/homelab/GeraeteListe"
|
||||
import { Gesundheit } from "@/components/homelab/Gesundheit"
|
||||
import { Lagebild } from "@/components/homelab/Lagebild"
|
||||
import { UpdateListe } from "@/components/homelab/UpdateListe"
|
||||
import { AlleKnopf, SammellaufFortschritt } from "@/components/homelab/Sammellauf"
|
||||
import { UpdateTabelle } from "@/components/homelab/UpdateTabelle"
|
||||
import {
|
||||
useHomelab, useHomelabHinweise, useHomelabLaeufe, useInstanz, usePartner, useZielAktion,
|
||||
useHomelab, useHomelabHinweise, useHomelabLaeufe, useHomelabMesswerte, useInstanz, usePartner, useSammellauf,
|
||||
useZielAktion,
|
||||
} from "@/lib/abfragen"
|
||||
import { lage, lampeFuer, offeneUpdates } from "@/lib/homelab"
|
||||
import type { Hinweis, HomelabLauf, HomelabStand, PartnerStatus } from "@/lib/typen"
|
||||
import { flugplanZeit } from "@/lib/zeit"
|
||||
|
||||
// Der Bereich Homelab hat zwei Seiten wie die KI-Box: das Cockpit (Lage, Hinweise, Geräte) und die
|
||||
// Updates (was ansteht, was gelaufen ist). Aus der KI-Box steht hier nichts — die hat ihren eigenen Bereich.
|
||||
// Der Bereich Homelab: das Cockpit zeigt, wie es den Geräten geht (Lage, Hinweise, Netz, CPU, Speicher,
|
||||
// Platte); die Updates-Seite zeigt je Gerät die Versionen, was ansteht und was gelaufen ist. Monitoring und
|
||||
// Protokoll haben eigene Seiten. Aus der KI-Box steht hier nichts — die hat ihren eigenen Bereich.
|
||||
|
||||
/** Was der Homelab-Teil übernimmt (Bestandsaufnahme vom 24.09.2026). */
|
||||
const GERAETE = ["Proxmox-Host", "AdGuard", "NPMplus", "NetBird", "PVE Scripts Local", "Gitea", "PBS", "Arcane mit Docker"]
|
||||
@@ -178,10 +182,11 @@ function useHomelabBereich() {
|
||||
}
|
||||
}
|
||||
|
||||
/** Homelab · Cockpit: die Lage auf einen Blick, Hinweise und alle Geräte. */
|
||||
/** Homelab · Cockpit: die Lage auf einen Blick, Hinweise und wie es jedem Gerät geht. */
|
||||
export function HomelabSeite() {
|
||||
const navigate = useNavigate()
|
||||
const { ersatz, stand, laufend, hinweise, aktion } = useHomelabBereich()
|
||||
const { ersatz, stand, laufend, hinweise } = useHomelabBereich()
|
||||
const mess = useHomelabMesswerte("1h", !!stand)
|
||||
if (ersatz || !stand) return ersatz
|
||||
|
||||
const berichtZeit = stand.bericht ? zeitAus(stand.bericht.empfangen) : null
|
||||
@@ -201,31 +206,50 @@ export function HomelabSeite() {
|
||||
<Panel
|
||||
titel="Geräte"
|
||||
id="geraete"
|
||||
rechts={berichtZeit ? <span className="ziffern text-sm text-text-3">Stand {berichtZeit}</span> : undefined}
|
||||
rechts={
|
||||
<span className="flex items-center gap-3">
|
||||
{berichtZeit && <span className="ziffern text-sm text-text-3">Stand {berichtZeit}</span>}
|
||||
<Link to="/homelab/monitoring" className="inline-flex items-center gap-1 text-sm text-lab-text hover:underline">
|
||||
Monitoring <ArrowRight className="size-3.5" aria-hidden />
|
||||
</Link>
|
||||
</span>
|
||||
}
|
||||
>
|
||||
<GeraeteListe ziele={stand.ziele} laufend={laufend} gesperrt={aktion.isPending} onAktion={(a) => aktion.mutate(a)} />
|
||||
<Gesundheit ziele={stand.ziele} messwerte={mess.data?.geraete} />
|
||||
{mess.isError && (
|
||||
<p className="text-xs text-text-3">CPU und Speicher erscheinen, sobald der Ausführer Messwerte schickt.</p>
|
||||
)}
|
||||
</Panel>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
/** Homelab · Updates: was ansteht — ein Knopf je Update — und was gelaufen ist. */
|
||||
/** Homelab · Updates: je Gerät die Versionen, „Alle aktualisieren“ und was gelaufen ist. */
|
||||
export function HomelabUpdatesSeite() {
|
||||
const { ersatz, stand, laufend, laeufe, aktion } = useHomelabBereich()
|
||||
const sammel = useSammellauf(!!stand)
|
||||
if (ersatz || !stand) return ersatz
|
||||
|
||||
const lauf = sammel.data?.sammellauf ?? null
|
||||
const sammelLaeuft = lauf?.status === "laeuft"
|
||||
const knopf = offeneUpdates(stand.ziele).filter((u) => u.baustein.aktion).length
|
||||
return (
|
||||
<>
|
||||
<Panel titel="Updates">
|
||||
<Panel
|
||||
titel="Updates"
|
||||
rechts={<AlleKnopf anzahl={knopf} gesperrt={aktion.isPending || sammelLaeuft || !stand.ausfuehrer.verbunden} />}
|
||||
>
|
||||
<p className="-mt-2 text-[15px] text-text-2">
|
||||
Du startest jedes Update selbst. Vorher wird gesichert, danach geprüft; ist die Prüfung rot, geht es von
|
||||
selbst zurück.
|
||||
Je Gerät, was läuft und was neu ist. Du startest jedes Update selbst — einzeln oder alle nacheinander.
|
||||
Vorher wird gesichert, danach geprüft; ist die Prüfung rot, geht es von selbst zurück.
|
||||
</p>
|
||||
<AusfuehrerHinweis stand={stand} />
|
||||
<UpdateListe
|
||||
updates={offeneUpdates(stand.ziele)}
|
||||
{/* Ein fertiger Lauf bleibt sechs Stunden stehen — gemessen am letzten Bericht, nicht an der Uhr beim Zeichnen. */}
|
||||
{lauf && (sammelLaeuft || (lauf.ende && (stand.bericht?.empfangen ?? 0) - lauf.ende < 6 * 3600)) && <SammellaufFortschritt lauf={lauf} />}
|
||||
<UpdateTabelle
|
||||
ziele={stand.ziele}
|
||||
laufend={laufend}
|
||||
gesperrt={aktion.isPending || !stand.ausfuehrer.verbunden}
|
||||
gesperrt={aktion.isPending || sammelLaeuft || !stand.ausfuehrer.verbunden}
|
||||
onAktion={(a) => aktion.mutate(a)}
|
||||
/>
|
||||
</Panel>
|
||||
|
||||
Reference in New Issue
Block a user