// overview.js — Dashboard-Kopf: Hero + kompakte Modell-Liste. import { $, esc } from "../core/ui.js"; let S = null; // letzter Status let J = []; // letzte Job-Liste const RUNNING = new Set(["running", "ready", "loading", "starting"]); function counts() { const models = S?.models || []; return { total: models.length, running: models.filter(m => RUNNING.has(m.state)).length, jobsRun: J.filter(j => j.state === "running" || j.state === "queued").length, jobsErr: J.filter(j => j.state === "failed").length, }; } function mini(label, val, tone = "") { const v = tone ? `${val}` : val; return `
${label}
${v}
`; } function renderHero() { const c = counts(); $("#hero").innerHTML = `
Übersicht

Mission Control

Steuerzentrale für deinen lokalen llama-swap-Stack — Modelle, Downloads, Wartung und Schnelltest an einem Ort.

${mini("Modelle", c.total)} ${mini("Aktiv", c.running, "on")} ${mini("Jobs", c.jobsRun)} ${mini("Fehler", c.jobsErr, c.jobsErr ? "bad" : "")}
`; } function modelRow(m) { const on = RUNNING.has(m.state); const dot = m.state === "loading" || m.state === "starting" ? "load" : on ? "on" : ""; const state = on ? (m.state === "loading" ? "lädt…" : "geladen") : "bereit"; let caps = ""; if (m.meta && m.meta.caps) { caps = m.meta.caps.map(c => { if (c === "Code") return `{ }`; if (c === "Bild") return `👁`; return ""; }).join(""); } return `
${esc(m.name)}${caps}
TTL ${m.ttl ?? "—"}${typeof m.ttl === "number" ? "s" : ""}
${m.port ?? "auto"}
${state}
`; } function renderModels() { const models = S?.models || []; $("#ov-models").innerHTML = `

Aktuelle Modelle im Stack

${models.length || ""}
${models.length ? `
${models.map(modelRow).join("")}
` : `
Keine Modelle konfiguriert
Hol dir unter „Cookbook“ eins von HuggingFace.
`}`; } function renderAll() { renderHero(); renderModels(); } function mount() { renderAll(); } function onStatus(s) { S = s; renderAll(); } function onJobs(jobs) { J = jobs || []; renderHero(); } export default { id: "overview", mount, onStatus, onJobs };