import { systemBaustein, appBaustein } from "@/lib/homelab" import type { BausteinStand, ZielStand } from "@/lib/typen" // Die Kurzform für die Übersicht: wer hat wo welche Updates — in einer Zeile je Gerät. export interface KurzZeile { id: string name: string teile: string[] /** Etwas davon lässt sich per Knopf einspielen. */ knopf: boolean } /** Warum ein Update keinen Knopf hat, in zwei, drei Worten. */ function wartetText(b: BausteinStand): string | null { if (b.aktion) return null const g = b.grund ?? "" const ab = g.match(/erst ab (\d{2}\.\d{2}\.(?:\d{4})? ?\d{2}:\d{2})/)?.[1] if (ab) return `ab ${ab}` if (/eigene Oberfläche|eigenen Oberfläche|eigenes Update/i.test(g)) return "über die App" return null } /** „App → 0.79.0 (ab 26.09. 08:06)“, „48 Pakete“, „11 Images“ — was an einem Gerät ansteht. */ export function kurzform(ziel: ZielStand): KurzZeile | null { const neu = ziel.bausteine.filter((b) => b.zustand === "neu") if (neu.length === 0) return null const teile: string[] = [] const app = appBaustein(ziel) if (app?.zustand === "neu") { const w = wartetText(app) teile.push(`App → ${app.verfuegbar ?? "neu"}${w ? ` (${w})` : ""}`) } const sys = systemBaustein(ziel) if (sys?.zustand === "neu") teile.push(sys.kurz || (sys.id === "docker" ? "Images" : "Pakete")) // KI-Box: Bausteine heißen selbst (Betriebssystem, Hermes, Motor …). for (const b of neu) { if (b === app || b === sys) continue teile.push(`${b.name}${b.kurz ? ` · ${b.kurz}` : ""}`) } return { id: ziel.id, name: ziel.name, teile, knopf: neu.some((b) => !!b.aktion) } } /** Die KI-Box ist ein Gerät mit mehreren Bausteinen — dort steht je Baustein eine Zeile. */ function bausteinZeilen(ziel: ZielStand): KurzZeile[] { return ziel.bausteine .filter((b) => b.zustand === "neu") .map((b) => ({ id: `${ziel.id}-${b.id}`, name: b.name, teile: [b.kurz || b.verfuegbar || "neu"], knopf: !!b.aktion })) } /** Alle Kurzzeilen eines Bereichs: erst, was per Knopf geht, dann der Rest. */ export function kurzformen(ziele: ZielStand[]): KurzZeile[] { const zeilen = ziele.flatMap((z) => (z.art === "ki-box" ? bausteinZeilen(z) : [kurzform(z)])) .filter((z): z is KurzZeile => z !== null) return [...zeilen.filter((z) => z.knopf), ...zeilen.filter((z) => !z.knopf)] } export type Lagestufe = "ok" | "info" | "gelb" | "rot" /** Die Gesamtlage über beide Bereiche — Störung vor Hinweis vor offenen Updates. */ export function gesamtlage(e: { getrennt: string[] stumm: string[] hinweiseRot: number hinweise: number updates: number }): { stufe: Lagestufe; titel: string; text: string } { if (e.getrennt.length > 0) { return { stufe: "rot", titel: "Verbindung weg", text: `${e.getrennt.join(" und ")} antwortet nicht.` } } if (e.stumm.length > 0 || e.hinweiseRot > 0) { const was = e.stumm.length > 0 ? `${e.stumm.join(", ")} antwortet nicht` : "Ein roter Hinweis wartet" return { stufe: "rot", titel: "Störung", text: `${was}.` } } if (e.hinweise > 0) { return { stufe: "gelb", titel: e.hinweise === 1 ? "1 Hinweis" : `${e.hinweise} Hinweise`, text: "Bei Gelegenheit ansehen." } } if (e.updates > 0) { return { stufe: "info", titel: "Alles läuft", text: `${e.updates} ${e.updates === 1 ? "Update steht" : "Updates stehen"} bereit.` } } return { stufe: "ok", titel: "Alles läuft", text: "Keine Hinweise, keine offenen Updates." } }