128 lines
5.5 KiB
JavaScript
128 lines
5.5 KiB
JavaScript
(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 = `<div class="d-flex justify-content-between mb-1"><strong>${label}</strong><span>Waiting</span></div>
|
|
<div class="progress" role="progressbar" aria-valuemin="0" aria-valuemax="100">
|
|
<div class="progress-bar" style="width:0%"></div>
|
|
</div>`;
|
|
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 = `<div class="modal-dialog modal-dialog-centered"><div class="modal-content">
|
|
<div class="modal-header"><h5 class="modal-title">Checking Earlier and Negative</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button></div>
|
|
<div class="modal-body"></div><div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
|
<button type="button" class="btn btn-primary js-start">Start</button></div></div></div>`;
|
|
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));
|