add(ui/ux): show the target library in the import row, trim the scissors
This commit is contained in:
+45
-1
@@ -764,10 +764,11 @@ function renderImportTable() {
|
||||
${appendOpts ? `<optgroup label="Bereits importiert — Teile anhängen">${appendOpts}</optgroup>` : ""}
|
||||
</select>
|
||||
<button class="secondary" data-quick="${i}" title="Metadaten suchen und Anfrage direkt verbinden">🔍</button>
|
||||
${item.parts || (item.is_dir && item.files.length > 1)
|
||||
${item.parts || item.maybe_separate
|
||||
? `<button class="secondary" data-split="${i}" title="${item.parts ? "Zusammenfassung wieder auflösen" : "Ordner in einzelne Titel aufteilen"}">✂️</button>`
|
||||
: ""}
|
||||
</td>
|
||||
<td>${libraryCell(item, i)}</td>
|
||||
${item.importState ? importStateCell(item)
|
||||
: item.conflict ? '<td class="state conflict" title="Mehrere Einträge zeigen auf dieselbe Anfrage">⚠ Konflikt</td>'
|
||||
: scoreCell(item)}
|
||||
@@ -782,6 +783,32 @@ function renderImportTable() {
|
||||
tbody.querySelectorAll("[data-quick]").forEach((b) =>
|
||||
b.addEventListener("click", () => openQuickDialog(parseInt(b.dataset.quick)))
|
||||
);
|
||||
tbody.querySelectorAll("[data-lib-for]").forEach((sel) =>
|
||||
sel.addEventListener("change", async () => {
|
||||
const item = scanItems[sel.dataset.libFor];
|
||||
const req = requestById(item.request_id);
|
||||
if (!req) return;
|
||||
const previous = req.library_id;
|
||||
req.library_id = parseInt(sel.value);
|
||||
try {
|
||||
const saved = await api("/api/requests/" + req.id, {
|
||||
method: "PUT",
|
||||
body: JSON.stringify({
|
||||
library_id: req.library_id, title: req.title, authors: req.authors,
|
||||
narrator: req.narrator || "", series: req.series, volume: req.volume,
|
||||
year: req.year, external_id: req.external_id, cover_url: req.cover_url,
|
||||
}),
|
||||
});
|
||||
Object.assign(req, saved);
|
||||
toast(`„${req.title}" → ${saved.library_name}`);
|
||||
} catch (err) {
|
||||
req.library_id = previous;
|
||||
sel.value = String(previous);
|
||||
toast(err.message, true);
|
||||
}
|
||||
renderImportTable();
|
||||
})
|
||||
);
|
||||
tbody.querySelectorAll("[data-split]").forEach((b) =>
|
||||
b.addEventListener("click", () => splitItem(parseInt(b.dataset.split)))
|
||||
);
|
||||
@@ -808,6 +835,23 @@ function renderImportTable() {
|
||||
updateImportPageInfo(pages);
|
||||
}
|
||||
|
||||
// which library the assigned request writes to - visible in the row, because the
|
||||
// select inside the search dialog is easy to miss
|
||||
function libraryCell(item, i) {
|
||||
const req = requestById(item.request_id);
|
||||
if (!req) return '<span class="muted">—</span>';
|
||||
const opts = libraries
|
||||
.filter((l) => l.media_type === req.media_type)
|
||||
.map((l) => `<option value="${l.id}" ${l.id === req.library_id ? "selected" : ""}>${esc(l.name)}</option>`)
|
||||
.join("");
|
||||
return `<select data-lib-for="${i}" title="Ziel-Library dieser Anfrage ändern">${opts}</select>`;
|
||||
}
|
||||
|
||||
function requestById(id) {
|
||||
if (!id) return null;
|
||||
return missingReqs.find((r) => r.id === id) || importedReqs.find((r) => r.id === id) || null;
|
||||
}
|
||||
|
||||
function importStateCell(item) {
|
||||
if (item.importState === "running") {
|
||||
return '<td class="state running"><span class="spinner"></span> läuft…</td>';
|
||||
|
||||
@@ -184,6 +184,7 @@
|
||||
<th>Datei/Ordner</th>
|
||||
<th>Typ</th>
|
||||
<th>Zuordnung</th>
|
||||
<th>Library</th>
|
||||
<th>Score</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
+3
-1
@@ -57,7 +57,9 @@ button:disabled { opacity: 0.6; cursor: default; }
|
||||
.tag.warn { background: #8a6d1f; }
|
||||
|
||||
/* per-entry import feedback */
|
||||
#import-progress { display: flex; align-items: center; gap: 0.6rem; flex: 1; }
|
||||
/* :not([hidden]) matters: a plain "display: flex" would beat the hidden
|
||||
attribute and leave an empty bar sitting there (same trap as a <dialog>) */
|
||||
#import-progress:not([hidden]) { display: flex; align-items: center; gap: 0.6rem; flex: 1; }
|
||||
#import-progress progress { flex: 1; max-width: 26rem; height: 0.7rem; }
|
||||
tr.row-running { background: rgba(90, 140, 220, 0.12); }
|
||||
tr.row-done { background: rgba(80, 170, 110, 0.12); }
|
||||
|
||||
Reference in New Issue
Block a user