add(ui/ux): clear finished rows after 15s and select just the visible page
This commit is contained in:
+39
-1
@@ -666,6 +666,7 @@ $("#scan-btn").addEventListener("click", async () => {
|
||||
api("/api/requests?status=missing"),
|
||||
api("/api/requests?status=imported"),
|
||||
]);
|
||||
clearTimeout(cleanupTimer);
|
||||
scanItems = scan.items;
|
||||
// selection state lives here, not in the DOM, so it survives paging/filtering
|
||||
scanItems.forEach((item) => {
|
||||
@@ -841,6 +842,25 @@ $("#import-select-suggested").addEventListener("click", () => {
|
||||
renderImportTable();
|
||||
});
|
||||
|
||||
$("#import-select-page").addEventListener("click", () => {
|
||||
applyImportView();
|
||||
const start = importPage * IMPORT_PAGE_SIZE;
|
||||
const pageIdx = viewIdx.slice(start, start + IMPORT_PAGE_SIZE);
|
||||
// exclusive on purpose: "import what I see", not "add to what was selected"
|
||||
scanItems.forEach((it) => (it.checked = false));
|
||||
let n = 0;
|
||||
pageIdx.forEach((i) => {
|
||||
const item = scanItems[i];
|
||||
const req = item.request_id || item.suggested_request_id;
|
||||
if (!req) return;
|
||||
item.request_id = req;
|
||||
item.checked = true;
|
||||
n += 1;
|
||||
});
|
||||
renderImportTable();
|
||||
toast(n ? `${n} Einträge dieser Seite ausgewählt` : "Auf dieser Seite gibt es keine Zuordnung", !n);
|
||||
});
|
||||
|
||||
$("#import-deselect-all").addEventListener("click", () => {
|
||||
applyImportView();
|
||||
viewIdx.forEach((i) => (scanItems[i].checked = false));
|
||||
@@ -1141,6 +1161,10 @@ $("#quick-m-submit").addEventListener("click", () => {
|
||||
|
||||
// ---- import execution (batched, with progress) ----
|
||||
const IMPORT_BATCH_SIZE = 20;
|
||||
// finished rows disappear after a while: the result list below keeps the record,
|
||||
// and a shrinking table makes the remaining work obvious
|
||||
const IMPORT_DONE_CLEANUP_MS = 15000;
|
||||
let cleanupTimer = null;
|
||||
|
||||
// several entries on one request means one audiobook split across folders:
|
||||
// importing them one by one only imports the first and fails the rest
|
||||
@@ -1294,6 +1318,19 @@ $("#import-btn").addEventListener("click", async () => {
|
||||
.join("");
|
||||
toast(failed.length ? `Import fertig, ${failed.length} Fehler` : "Import fertig", failed.length > 0);
|
||||
refreshMissingBadge();
|
||||
clearTimeout(cleanupTimer);
|
||||
cleanupTimer = setTimeout(() => {
|
||||
// only the successful ones go; failures and conflicts stay to be dealt with
|
||||
const before = scanItems.length;
|
||||
scanItems = scanItems.filter((it) => it.importState !== "done");
|
||||
if (scanItems.length !== before) {
|
||||
importPage = 0;
|
||||
setImportProgress(0, 0);
|
||||
renderImportTable();
|
||||
$("#scan-info").textContent =
|
||||
`${scanItems.length} Kandidat(en) übrig — für den aktuellen Stand erneut scannen`;
|
||||
}
|
||||
}, IMPORT_DONE_CLEANUP_MS);
|
||||
// the list stays as it is, with its green and red rows - rescanning would
|
||||
// wipe exactly the feedback the user just waited for
|
||||
} finally {
|
||||
@@ -1304,7 +1341,8 @@ $("#import-btn").addEventListener("click", async () => {
|
||||
|
||||
function setImportProgress(done, total) {
|
||||
const box = $("#import-progress");
|
||||
if (!total || done >= total) {
|
||||
if (!total) { box.hidden = true; return; }
|
||||
if (done >= total) {
|
||||
box.hidden = done < total;
|
||||
if (done >= total) {
|
||||
box.querySelector("progress").value = total;
|
||||
|
||||
@@ -165,6 +165,10 @@
|
||||
<button id="import-select-suggested" class="secondary">
|
||||
Alle mit Vorschlag auswählen
|
||||
</button>
|
||||
<button id="import-select-page" class="secondary"
|
||||
title="Nur die Einträge dieser Seite auswählen, alle anderen abwählen">
|
||||
Diese Seite auswählen
|
||||
</button>
|
||||
<button id="import-deselect-all" class="secondary">
|
||||
Alle abwählen
|
||||
</button>
|
||||
|
||||
Reference in New Issue
Block a user