Grotti 3.1.0: Bedarf-UI, Zeitfenster, HT/NT, Theme, Chrome-Fixes.
Bedarf in Sidebar/Material, Drucker-Zeitfenster und Tarif in Einstellungen, helles Theme; Legacy-Token und /api/drucker entfernt; SSE/SW-Fixes gegen hängende Navigation in Chrome.
This commit is contained in:
1 parent
8e88efc094
commit
6e59df22e5
23 files changed
+741
-171
No files matched your search
@@ -14,6 +14,20 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section class="card bedarf-card" id="bedarf-card" hidden>
|
||||
<div class="lib-head">
|
||||
<h2 id="bedarf">Bedarf aus Warteschlange</h2>
|
||||
<span class="count" id="bedarf-short-count">0</span>
|
||||
</div>
|
||||
<p class="hint" id="bedarf-hint">Fehlmenge = Queue-Gewicht minus Spulenrest (gleiche Sorte/Farbe).</p>
|
||||
<div class="table-wrap">
|
||||
<table>
|
||||
<thead><tr><th>Sorte</th><th>Farbe</th><th class="num">Queue</th><th class="num">Rest</th><th class="num">Fehlt</th><th class="num">Jobs</th></tr></thead>
|
||||
<tbody id="bedarf-rows"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="tabs mat-tabs" role="tablist">
|
||||
<button type="button" class="on" data-view="spools" role="tab"><svg class="ico"><use href="#i-spool"/></svg>Spulen</button>
|
||||
<button type="button" data-view="sorten" role="tab"><svg class="ico"><use href="#i-layers"/></svg>Sorten</button>
|
||||
@@ -721,17 +735,58 @@ function render() {
|
||||
renderSorten();
|
||||
}
|
||||
|
||||
function renderBedarf(data) {
|
||||
const card = document.getElementById("bedarf-card");
|
||||
const shortfall = (data && data.shortfall) || [];
|
||||
const needed = (data && data.needed) || [];
|
||||
if (!needed.length && !shortfall.length) {
|
||||
card.hidden = true;
|
||||
return;
|
||||
}
|
||||
card.hidden = false;
|
||||
document.getElementById("bedarf-short-count").textContent = shortfall.length
|
||||
? shortfall.length + " Fehl"
|
||||
: "ok";
|
||||
document.getElementById("bedarf-hint").textContent = shortfall.length
|
||||
? shortfall.length + " Sorten reichen nicht für die wartende Queue."
|
||||
: "Queue hat Bedarf — Spulenrest reicht.";
|
||||
const rows = (shortfall.length ? shortfall : needed).map((item) => {
|
||||
const missing = item.shortfall_g != null ? grams(item.shortfall_g) : "—";
|
||||
const rest = item.remaining_g != null
|
||||
? grams(item.remaining_g)
|
||||
: "—";
|
||||
return `<tr class="${item.shortfall_g > 0 ? "warn" : ""}">
|
||||
<td>${escapeHtml(item.material_type || "—")}</td>
|
||||
<td>${escapeHtml(item.color || "—")}</td>
|
||||
<td class="num">${grams(item.weight_g)}</td>
|
||||
<td class="num">${rest}</td>
|
||||
<td class="num">${missing}</td>
|
||||
<td class="num">${item.jobs || 0}</td>
|
||||
</tr>`;
|
||||
}).join("");
|
||||
document.getElementById("bedarf-rows").innerHTML = rows
|
||||
|| '<tr><td class="empty" colspan="6">Kein Queue-Bedarf.</td></tr>';
|
||||
}
|
||||
|
||||
async function load() {
|
||||
[spools, printers, materials, palette] = await Promise.all([
|
||||
const [spoolData, printerData, materialData, paletteData, bedarfData] = await Promise.all([
|
||||
api("/spulen"),
|
||||
api("/drucker?live=0"),
|
||||
api("/materialien"),
|
||||
api("/farben"),
|
||||
api("/bedarf").catch(() => ({ needed: [], shortfall: [] })),
|
||||
]);
|
||||
spools = spoolData;
|
||||
printers = printerData;
|
||||
materials = materialData;
|
||||
palette = paletteData;
|
||||
render();
|
||||
renderPalette();
|
||||
renderBedarf(bedarfData);
|
||||
}
|
||||
|
||||
window.onBedarfChanged = renderBedarf;
|
||||
|
||||
function setScanNote(text, ok) {
|
||||
const note = document.getElementById("scan-note");
|
||||
if (!text) {
|
||||
|
||||
Reference in new issue
Block a user