(function (window, document) { "use strict"; const endpoint = "/matrix/ver/checkdedupe"; const operations = [ { id: 1, field: "earlier", label: "Earlier" }, { id: 2, field: "negative", label: "Negative" } ]; function expandList(id) { const child = document.getElementById(`${id}child`); if (child) child.style.display = child.style.display === "none" ? "table-row" : "none"; } function notify(type, code, message) { window.CygnusNotifications?.show({ type, code, message, duration: 5000 }); } function createProgress(label) { const group = document.createElement("div"); group.className = "mb-3"; group.innerHTML = `
${label}Waiting
`; return group; } function createDialog() { document.getElementById("dedupe-run-modal")?.remove(); const root = document.createElement("div"); root.id = "dedupe-run-modal"; root.className = "modal fade"; root.tabIndex = -1; root.innerHTML = ``; const body = root.querySelector(".modal-body"); operations.forEach(operation => body.append(createProgress(operation.label))); document.body.append(root); return root; } function updateProgress(container, processed, total, counters) { const percent = total === 0 ? 100 : Math.round((processed / total) * 100); container.querySelector(".progress-bar").style.width = `${percent}%`; container.querySelector("span").textContent = `${processed}/${total} | Success ${counters.success} | Failed ${counters.failed} | Skipped ${counters.skipped}`; } async function check(row, operation) { const response = await fetch(endpoint, { method: "POST", headers: { "Content-Type": "application/json", "X-CSRF-TOKEN": document.getElementById("dedupe-csrf-token")?.value || "" }, body: JSON.stringify({ documentCaseId: row.dataset.documentCaseId, operation: operation.id }) }); const payload = await response.json().catch(() => null); if (!response.ok || !payload?.success) { throw new Error(payload?.message?.message || "Dedupe check failed"); } } async function runOperation(rows, operation, progress) { const counters = { success: 0, failed: 0, skipped: 0 }; for (let index = 0; index < rows.length; index += 1) { const row = rows[index]; const statusCell = row.querySelector(`td[id$="${operation.field === "earlier" ? "ear" : "neg"}"]`); if (row.dataset[operation.field] !== "Y") { counters.skipped += 1; } else { try { await check(row, operation); counters.success += 1; row.dataset[operation.field] = "D"; if (statusCell) { statusCell.textContent = "D"; statusCell.classList.add("table-success"); } } catch (error) { counters.failed += 1; if (statusCell) { statusCell.textContent = "F"; statusCell.title = error.message; statusCell.classList.add("table-danger"); } } } updateProgress(progress, index + 1, rows.length, counters); } return counters; } async function run(tableId, modalRoot) { const rows = Array.from(document.querySelectorAll(`#${CSS.escape(tableId)} tbody tr[data-document-case-id]`)); if (rows.length === 0) { notify("info", "DDP-2002", "The selected list has no records to process."); return; } const start = modalRoot.querySelector(".js-start"); start.disabled = true; const progress = modalRoot.querySelectorAll(".modal-body > div"); for (let index = 0; index < operations.length; index += 1) { await runOperation(rows, operations[index], progress[index]); } start.disabled = false; notify("success", "DDP-2001", "Earlier and negative dedupe checks completed."); } document.addEventListener("click", event => { const runButton = event.target.closest(".js-run-dedupe"); if (!runButton) return; const modalRoot = createDialog(); modalRoot.querySelector(".js-start").addEventListener("click", () => run(runButton.dataset.table, modalRoot)); window.bootstrap.Modal.getOrCreateInstance(modalRoot).show(); }); window.ExpandList = expandList; }(window, document));