add(ui/ux): bulk delete

This commit is contained in:
Steppenstreuner
2026-08-28 18:11:15 +02:00
parent f809bbcc40
commit 034ecad644
3 changed files with 80 additions and 26 deletions
+51 -26
View File
@@ -261,6 +261,26 @@ $("#manual-form").addEventListener("submit", async (e) => {
// ---- missing / imported lists ----
let currentRequests = { missing: [], imported: [] };
// view mode (Liste / kleine / große Symbole), shared by both lists
function getViewMode() {
try { return localStorage.getItem("wordarr.viewMode") || "small"; } catch { return "small"; }
}
function applyViewMode(mode) {
try { localStorage.setItem("wordarr.viewMode", mode); } catch {}
["#missing-list", "#imported-list"].forEach((sel) => {
const box = $(sel);
box.classList.remove("view-list", "view-small", "view-large");
box.classList.add("view-" + mode);
});
$$(".view-toggle button").forEach((b) =>
b.classList.toggle("active", b.dataset.viewmode === mode)
);
}
$$(".view-toggle button").forEach((b) =>
b.addEventListener("click", () => applyViewMode(b.dataset.viewmode))
);
applyViewMode(getViewMode());
function requestMatchesFilter(r, text) {
if (!text) return true;
const hay = `${r.title} ${r.authors} ${r.series} ${r.narrator}`.toLowerCase();
@@ -284,9 +304,10 @@ function renderRequests(status) {
const text = status === "missing" ? $("#missing-search").value : $("#imported-search").value;
const reqs = currentRequests[status].filter((r) => requestMatchesFilter(r, text));
const box = status === "missing" ? $("#missing-list") : $("#imported-list");
const bulkBtn = status === "missing" ? $("#missing-bulk-delete") : $("#imported-bulk-delete");
if (!reqs.length) {
box.innerHTML = "<p class='muted'>Nichts hier.</p>";
if (status === "missing") $("#missing-bulk-delete").hidden = true;
bulkBtn.hidden = true;
return;
}
box.innerHTML = reqs
@@ -300,7 +321,7 @@ function renderRequests(status) {
<span class="muted">${esc(r.media_type)}${esc(r.library_name)}</span>
${status === "imported" ? `<span class="muted mono">${esc(r.imported_path)}</span>` : ""}
</div>
${status === "missing" ? `<input type="checkbox" class="card-check" data-sel-req="${r.id}">` : ""}
<input type="checkbox" class="card-check" data-sel-req="${r.id}">
</div>`
)
.join("");
@@ -310,37 +331,41 @@ function renderRequests(status) {
openDetail(parseInt(card.dataset.detail), status);
})
);
if (status === "missing") {
const updateBulkBtn = () => {
const n = box.querySelectorAll("[data-sel-req]:checked").length;
const btn = $("#missing-bulk-delete");
btn.hidden = n === 0;
btn.textContent = `Ausgewählte entfernen (${n})`;
};
box.querySelectorAll("[data-sel-req]").forEach((c) =>
c.addEventListener("change", updateBulkBtn)
);
updateBulkBtn();
}
const updateBulkBtn = () => {
const n = box.querySelectorAll("[data-sel-req]:checked").length;
bulkBtn.hidden = n === 0;
bulkBtn.textContent = `Ausgewählte entfernen (${n})`;
};
box.querySelectorAll("[data-sel-req]").forEach((c) =>
c.addEventListener("change", updateBulkBtn)
);
updateBulkBtn();
}
async function bulkDeleteRequests(status) {
const box = status === "missing" ? $("#missing-list") : $("#imported-list");
const ids = [...box.querySelectorAll("[data-sel-req]:checked")].map((c) => c.dataset.selReq);
if (!ids.length) return;
const hint = status === "imported"
? `${ids.length} Eintrag/Einträge entfernen? Die importierten Dateien in der Library bleiben erhalten.`
: `${ids.length} Anfrage(n) entfernen?`;
if (!confirm(hint)) return;
for (const id of ids) {
try { await api("/api/requests/" + id, { method: "DELETE" }); }
catch (err) { toast(err.message, true); }
}
toast(`${ids.length} entfernt`);
loadRequests(status);
}
$("#imported-bulk-delete").addEventListener("click", () => bulkDeleteRequests("imported"));
$("#missing-filter-type").addEventListener("change", () => loadRequests("missing"));
$("#missing-filter-library").addEventListener("change", () => loadRequests("missing"));
$("#missing-search").addEventListener("input", () => renderRequests("missing"));
$("#imported-search").addEventListener("input", () => renderRequests("imported"));
$("#missing-bulk-delete").addEventListener("click", async () => {
const ids = [...$("#missing-list").querySelectorAll("[data-sel-req]:checked")]
.map((c) => c.dataset.selReq);
if (!ids.length) return;
if (!confirm(`${ids.length} Anfrage(n) entfernen?`)) return;
for (const id of ids) {
try { await api("/api/requests/" + id, { method: "DELETE" }); }
catch (err) { toast(err.message, true); }
}
toast(`${ids.length} Anfrage(n) entfernt`);
loadRequests("missing");
});
$("#missing-bulk-delete").addEventListener("click", () => bulkDeleteRequests("missing"));
// ---- request detail dialog ----
let detailRequest = null;