83 lines
3.4 KiB
TypeScript
83 lines
3.4 KiB
TypeScript
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." }
|
|
}
|