Grotti 3.4.0: Dateien umbenennen, Bedarf/PLA-Match, Pause- und gklib-Fixes.
This commit is contained in:
1 parent
67a89d1794
commit
dd0e7ebc6b
16 files changed
+430
-58
No files matched your search
@@ -360,17 +360,37 @@ function spoolWarnText() {
|
||||
const hosts = selectedHosts();
|
||||
const fileTypes = ((file.filaments || []).map((f) => (f.type || "").toLowerCase()).filter(Boolean));
|
||||
const fileProfiles = ((file.filaments || []).map((f) => (f.profile || "").toLowerCase()).filter(Boolean));
|
||||
const PROFILE_VARIANTS = ["meta", "matte", "matt", "silk", "plus", "hf", "cf"];
|
||||
function profileHasVariant(want) {
|
||||
return PROFILE_VARIANTS.some((v) => new RegExp("\\b" + v + "\\b", "i").test(want || ""));
|
||||
}
|
||||
function profileBaseType(want) {
|
||||
const m = String(want || "").toLowerCase().match(/\b(pla|petg|abs|asa|tpu|pa|pc|hips|pva)\b/);
|
||||
return m ? m[1] : "";
|
||||
}
|
||||
function profileOk(spoolRows) {
|
||||
if (!fileProfiles.length) return true;
|
||||
const names = spoolRows.map((s) => (s.name || "").toLowerCase()).filter(Boolean);
|
||||
if (!names.length) return true;
|
||||
return fileProfiles.every((want) => names.some((n) => {
|
||||
if (n === want) return true;
|
||||
if (!n.startsWith(want) || /[a-z0-9]/i.test(n.charAt(want.length) || "")) return false;
|
||||
const rest = n.slice(want.length).replace(/^[\s·\-_|/]+/, "");
|
||||
const first = (rest.split(/\s+/)[0] || "").toLowerCase();
|
||||
return !["meta", "matte", "matt", "silk", "plus", "hf", "cf"].includes(first);
|
||||
}));
|
||||
const types = spoolRows.map((s) => (s.material_type || "").toLowerCase()).filter(Boolean);
|
||||
if (!names.length && !types.length) return true;
|
||||
return fileProfiles.every((want) => {
|
||||
if (names.some((n) => {
|
||||
if (n === want) return true;
|
||||
if (!n.startsWith(want) || /[a-z0-9]/i.test(n.charAt(want.length) || "")) return false;
|
||||
const rest = n.slice(want.length).replace(/^[\s·\-_|/]+/, "");
|
||||
const first = (rest.split(/\s+/)[0] || "").toLowerCase();
|
||||
return !PROFILE_VARIANTS.includes(first);
|
||||
})) return true;
|
||||
// Basis-Profil (nur „… PLA“): Typ reicht, Marke egal — keine Meta/Matte-Spule
|
||||
if (profileHasVariant(want)) return false;
|
||||
const kind = profileBaseType(want);
|
||||
if (!kind) return true;
|
||||
return spoolRows.some((s) => {
|
||||
const t = (s.material_type || "").toLowerCase();
|
||||
const n = (s.name || "").toLowerCase();
|
||||
return t === kind && !profileHasVariant(n);
|
||||
});
|
||||
});
|
||||
}
|
||||
for (const host of hosts) {
|
||||
const name = (printers.find((p) => p.host === host) || {}).name || host;
|
||||
@@ -827,11 +847,12 @@ function thumbHtml(file) {
|
||||
|
||||
function libItemHtml(file) {
|
||||
const project = projects.find((p) => String(p.id) === String(file.project_id));
|
||||
const rename = `<button type="button" class="icon-btn" data-rename="${file.id}" title="Umbenennen">${icon("edit")}</button>`;
|
||||
const del = `<button type="button" class="icon-btn" data-delete="${file.id}" title="Datei löschen">${icon("trash")}</button>`;
|
||||
return `<div class="lib-item ${String(file.id) === String(sel.fileId) ? "on" : ""}" role="button" tabindex="0" data-file="${file.id}">
|
||||
${thumbHtml(file)}
|
||||
<span style="min-width:0"><span class="t" title="${escapeHtml(file.name)}">${escapeHtml(file.name)}</span><span class="m">${alwaysMeta(file, project)}</span></span>
|
||||
<span class="side">${moveSelectHtml(file)}${infoPopupHtml(file)}${del}</span>
|
||||
<span class="side">${moveSelectHtml(file)}${infoPopupHtml(file)}${rename}${del}</span>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
@@ -1530,6 +1551,24 @@ document.getElementById("lib-list").addEventListener("click", (event) => {
|
||||
event.stopPropagation();
|
||||
return;
|
||||
}
|
||||
const ren = event.target.closest("[data-rename]");
|
||||
if (ren) {
|
||||
event.stopPropagation();
|
||||
const file = files.find((f) => String(f.id) === String(ren.dataset.rename));
|
||||
if (!file) return;
|
||||
const next = window.prompt("Neuer Dateiname:", file.name);
|
||||
if (next == null) return;
|
||||
const trimmed = String(next).trim();
|
||||
if (!trimmed || trimmed === file.name) return;
|
||||
api("/dateien/" + file.id + "/umbenennen", { method: "POST", json: { name: trimmed } })
|
||||
.then(async (saved) => {
|
||||
toast("Umbenannt in „" + (saved.name || trimmed) + "“.", "good");
|
||||
await load();
|
||||
if (saved && saved.id) selectFile(saved.id);
|
||||
})
|
||||
.catch((error) => toast(error.message || String(error), "bad"));
|
||||
return;
|
||||
}
|
||||
const del = event.target.closest("[data-delete]");
|
||||
if (del) {
|
||||
event.stopPropagation();
|
||||
|
||||
Reference in new issue
Block a user