Grotti 3.2.0: Jetzt-Liste, Filament-Pause, Strom-Torte, UI-Polish.

Jetzt/Topbar und Material-Routing, Pause bei Filament-Ende, Druckbericht mit Stromanteilen, Design- und Kamera-Stream-Polish; Bedarf-Alert-Spam und Platte-belegt-Bugs behoben.
This commit is contained in:
Dominic Gundel committed 2026-10-18 14:58:32 +02:00
1 parent 6e59df22e5
commit 4ddffbbeb1
68 files changed
+4348 -1215

No files matched your search

+23 -15
View File
@@ -3,21 +3,23 @@
<div class="page-head">
<div>
<h1>Warteschlange</h1>
<p class="tiny">Wartende und laufende Aufträge. Direktstarts erscheinen unter Läuft. Priorität mit den Pfeilen ändern.</p>
<p class="tiny">Wartende und laufende Drucke. Direktstarts erscheinen unter Läuft. Priorität mit den Pfeilen ändern.</p>
</div>
<div class="page-head-side">
<a class="ghost" id="q-bedarf" href="/material#bedarf" hidden></a>
<button type="button" class="ghost" id="q-refresh"><svg class="ico"><use href="#i-refresh"/></svg>Neu laden</button>
</div>
</div>
<div class="filter-bar" id="q-filter" role="group" aria-label="Status">
<button type="button" class="fchip on" data-status="">Alle aktiv</button>
<button type="button" class="fchip" data-status="running">Läuft</button>
<button type="button" class="fchip" data-status="waiting">Wartet</button>
<button type="button" class="fchip" data-status="error">Fehler</button>
<button type="button" class="fchip" data-status="history">Historie</button>
<div class="toolbar" id="q-filter" role="group" aria-label="Status">
<div class="fchips">
<button type="button" class="fchip on" data-status="">Alle aktiv</button>
<button type="button" class="fchip" data-status="running"><svg class="ico"><use href="#i-play"/></svg>Läuft</button>
<button type="button" class="fchip" data-status="waiting"><svg class="ico"><use href="#i-clock"/></svg>Wartet</button>
<button type="button" class="fchip" data-status="error"><svg class="ico"><use href="#i-alert"/></svg>Fehler</button>
<button type="button" class="fchip" data-status="history"><svg class="ico"><use href="#i-history"/></svg>Historie</button>
</div>
<div class="tools-end"><span id="q-note" class="tiny"></span></div>
</div>
<p id="q-note" class="tiny"></p>
<div class="card table-wrap">
<table>
<thead>
@@ -87,8 +89,13 @@ function render() {
if (!shown.length) {
const hint = jobs.length
? "Nichts in dieser Ansicht."
: (liveDirect.length ? "Keine Queue-Aufträge — laufende Direktstarts unter „Läuft“." : "Noch kein Eintrag.");
body.innerHTML = '<tr><td class="empty" colspan="6"><div class="empty-state">' + icon("queue") + '<p>' + hint + '</p></div></td></tr>';
: (liveDirect.length
? "Keine Einträge in der Warteschlange — laufende Direktstarts unter „Läuft“."
: "Noch kein Eintrag.");
const cta = (!jobs.length && !liveDirect.length)
? '<p><a class="btn-primary" href="/dateien">' + icon("send") + ' Datei senden</a></p>'
: "";
body.innerHTML = '<tr><td class="empty" colspan="6"><div class="empty-state">' + icon("queue") + '<p>' + hint + '</p>' + cta + '</div></td></tr>';
document.getElementById("q-note").textContent = "";
return;
}
@@ -98,11 +105,11 @@ function render() {
if (job.direct) {
return `<tr data-direct="${escapeHtml(job.host)}">
<td>${chipHtml("printing", "läuft")}</td>
<td><span title="${escapeHtml(job.filename || "")}">${escapeHtml(jobLabel(job.filename))}</span></td>
<td><span class="cell-file" title="${escapeHtml(job.filename || "")}">${escapeHtml(jobLabel(job.filename))}</span></td>
<td><a href="/#${encodeURIComponent(job.host)}">${escapeHtml(targetOf(job))}</a></td>
<td>—</td>
<td class="tiny">${escapeHtml(job.message || "")}</td>
<td class="queue-tools"><a class="icon-btn" href="/#${encodeURIComponent(job.host)}" title="Zur Wand">${icon("printer")}</a></td>
<td class="actions-cell"><a class="icon-btn" href="/#${encodeURIComponent(job.host)}" title="Zur Wand" aria-label="Zur Wand">${icon("printer")}</a></td>
</tr>`;
}
const waitIdx = waiting.findIndex((j) => j.id === job.id);
@@ -123,13 +130,14 @@ function render() {
} else if (st === "waiting" || st === "running") {
tools.push(`<button type="button" class="icon-btn danger" data-cancel="${job.id}" title="Abbrechen">${icon("x")}</button>`);
}
const chipState = st === "running" ? "printing" : st === "waiting" ? "waiting" : st === "error" ? "error" : st === "done" ? "done" : st === "cancelled" || st === "dismissed" ? "dismissed" : "complete";
return `<tr data-id="${job.id}">
<td>${chipHtml(st === "running" ? "printing" : st === "waiting" ? "waiting" : st === "error" ? "error" : "complete", STATUS_LABEL[st] || st)}</td>
<td><span title="${escapeHtml(job.filename || "")}">${escapeHtml(jobLabel(job.filename))}</span>${rep ? " · " + escapeHtml(rep) : ""}</td>
<td>${chipHtml(chipState, STATUS_LABEL[st] || st)}</td>
<td><span class="cell-file" title="${escapeHtml(job.filename || "")}">${escapeHtml(jobLabel(job.filename))}</span>${rep ? " · " + escapeHtml(rep) : ""}</td>
<td>${job.host ? `<a href="/#${encodeURIComponent(job.host)}">${escapeHtml(targetOf(job))}</a>` : escapeHtml(targetOf(job))}</td>
<td>${steps || "—"}</td>
<td class="tiny">${escapeHtml(job.message || "")}</td>
<td class="queue-tools">${tools.join("")}</td>
<td class="actions-cell">${tools.join("")}</td>
</tr>`;
}).join("");
document.getElementById("q-note").textContent = shown.length === 1 ? "1 Eintrag" : shown.length + " Einträge";