add(ui/ux): search all open requests from the import dialog
This commit is contained in:
+37
-14
@@ -1037,6 +1037,7 @@ function openQuickDialog(i) {
|
||||
$("#quick-episode").textContent = number != null ? `Folge ${number} — nicht mitgesucht` : "";
|
||||
$("#quick-q").value = cleanFileName(rest);
|
||||
quickPicked = null;
|
||||
$("#quick-req-filter").value = "";
|
||||
$("#quick-m-title").value = cleanFileName(rest);
|
||||
$("#quick-m-authors").value = "";
|
||||
$("#quick-m-volume").value = number ?? "";
|
||||
@@ -1052,31 +1053,49 @@ function openQuickDialog(i) {
|
||||
runQuickSearch();
|
||||
}
|
||||
|
||||
// offer linking to similar already-open requests instead of creating a duplicate
|
||||
// offer linking to an already-open request instead of creating a duplicate.
|
||||
// Without a filter these are the best guesses from the file name; typing turns
|
||||
// the box into a search over every open request, because the guess can be wrong.
|
||||
const QUICK_OPEN_LIMIT = 20;
|
||||
|
||||
function renderQuickOpenRequests(item) {
|
||||
const box = $("#quick-open-requests");
|
||||
const tokens = cleanFileName(item.name).toLowerCase().split(" ").filter((t) => t.length > 2);
|
||||
const matches = missingReqs
|
||||
.filter((r) => r.media_type === item.media_type)
|
||||
.map((r) => {
|
||||
const hay = `${r.title} ${r.authors} ${r.series} ${r.narrator}`.toLowerCase();
|
||||
return { r, hits: tokens.filter((t) => hay.includes(t)).length };
|
||||
})
|
||||
.filter((m) => m.hits >= 2)
|
||||
.sort((a, b) => b.hits - a.hits)
|
||||
.slice(0, 3);
|
||||
if (!matches.length) { box.innerHTML = ""; return; }
|
||||
const query = $("#quick-req-filter").value.trim().toLowerCase();
|
||||
const open = missingReqs.filter((r) => r.media_type === item.media_type);
|
||||
const hay = (r) => `${r.title} ${r.authors} ${r.series} ${r.narrator} ${r.volume ?? ""}`.toLowerCase();
|
||||
|
||||
let matches;
|
||||
let heading;
|
||||
if (query) {
|
||||
const terms = query.split(/\s+/);
|
||||
matches = open.filter((r) => terms.every((t) => hay(r).includes(t)));
|
||||
heading = matches.length
|
||||
? `${Math.min(matches.length, QUICK_OPEN_LIMIT)} von ${matches.length} Treffern (${open.length} offen)`
|
||||
: `Kein Treffer unter ${open.length} offenen Anfragen`;
|
||||
matches = matches.slice(0, QUICK_OPEN_LIMIT);
|
||||
} else {
|
||||
const tokens = cleanFileName(item.name).toLowerCase().split(" ").filter((t) => t.length > 2);
|
||||
matches = open
|
||||
.map((r) => ({ r, hits: tokens.filter((t) => hay(r).includes(t)).length }))
|
||||
.filter((m) => m.hits >= 2)
|
||||
.sort((a, b) => b.hits - a.hits)
|
||||
.slice(0, 3)
|
||||
.map((m) => m.r);
|
||||
heading = matches.length ? "Passende offene Requests:" : "";
|
||||
}
|
||||
|
||||
box.innerHTML =
|
||||
'<p class="muted">Passende offene Requests:</p>' +
|
||||
(heading ? `<p class="muted">${esc(heading)}</p>` : "") +
|
||||
matches
|
||||
.map(
|
||||
({ r }) => `<div class="row open-req">
|
||||
(r) => `<div class="row open-req">
|
||||
<span>${esc(r.title)}${r.volume != null ? " · Band " + r.volume : ""} — ${esc(r.authors)} (${esc(r.library_name)})</span>
|
||||
<button class="secondary" data-link-req="${r.id}">Verbinden</button>
|
||||
</div>`
|
||||
)
|
||||
.join("");
|
||||
box.querySelectorAll("[data-link-req]").forEach((b) =>
|
||||
|
||||
b.addEventListener("click", () => {
|
||||
const i = quickItemIndex;
|
||||
scanItems[i].request_id = parseInt(b.dataset.linkReq);
|
||||
@@ -1137,6 +1156,10 @@ async function runQuickSearch() {
|
||||
}
|
||||
}
|
||||
|
||||
$("#quick-req-filter").addEventListener("input", () => {
|
||||
if (quickItemIndex != null) renderQuickOpenRequests(scanItems[quickItemIndex]);
|
||||
});
|
||||
|
||||
$("#quick-search-form").addEventListener("submit", (e) => {
|
||||
e.preventDefault();
|
||||
runQuickSearch();
|
||||
|
||||
@@ -232,6 +232,10 @@
|
||||
<label class="muted"
|
||||
>Ziel-Library <select id="quick-library"></select
|
||||
></label>
|
||||
<label class="muted"
|
||||
>Offene Anfragen
|
||||
<input id="quick-req-filter" placeholder="nach Titel, Autor, Serie filtern…" />
|
||||
</label>
|
||||
<div id="quick-scroll">
|
||||
<div id="quick-open-requests"></div>
|
||||
<div id="quick-results" class="cards view-list"></div>
|
||||
|
||||
Reference in New Issue
Block a user