167 lines
6.2 KiB
JavaScript
167 lines
6.2 KiB
JavaScript
/**
|
|
* saveAll.js — Save All functionality using gridData
|
|
*/
|
|
(function () {
|
|
"use strict";
|
|
|
|
let saveAllRunning = false;
|
|
|
|
function isBusy() {
|
|
return saveAllRunning || window.batchRunning;
|
|
}
|
|
|
|
// ── Save single row ──────────────────────────────────────────────────
|
|
$(document).on("click", ".save-btn", async function () {
|
|
const btn = this;
|
|
const rowIndex = parseInt(btn.dataset.row);
|
|
const row = window.gridData?.[rowIndex];
|
|
if (!row) return;
|
|
|
|
const origHtml = btn.innerHTML;
|
|
btn.innerHTML = '<i class="fas fa-spinner fa-spin"></i>';
|
|
btn.disabled = true;
|
|
|
|
try {
|
|
const formData = window.buildSavePayload(rowIndex);
|
|
const resp = await fetch("save_edited_row.php", {
|
|
method: "POST",
|
|
body: formData,
|
|
});
|
|
const result = await resp.json();
|
|
|
|
if (result.success) {
|
|
row._dirty = false;
|
|
if (window.gridRenderer?.clearDirty)
|
|
window.gridRenderer.clearDirty(rowIndex);
|
|
// Flash success on row without re-rendering (preserves Select2 state)
|
|
const gridRow = document.querySelector(
|
|
`.grid-row[data-id="${row.iddatadb}"]`,
|
|
);
|
|
if (gridRow) {
|
|
gridRow.classList.remove("row-dirty");
|
|
gridRow.querySelectorAll(".grid-cell").forEach((cell) => {
|
|
cell.classList.remove("cell-changed");
|
|
cell.classList.add("flash-success");
|
|
});
|
|
setTimeout(
|
|
() =>
|
|
gridRow
|
|
.querySelectorAll(".flash-success")
|
|
.forEach((c) =>
|
|
c.classList.remove("flash-success"),
|
|
),
|
|
500,
|
|
);
|
|
}
|
|
const toastEl = document.getElementById("saveSuccessToast");
|
|
if (toastEl)
|
|
bootstrap.Toast.getOrCreateInstance(toastEl).show();
|
|
} else {
|
|
alert("Errore: " + result.message);
|
|
}
|
|
} catch (e) {
|
|
alert("Errore: " + e.message);
|
|
} finally {
|
|
btn.innerHTML = origHtml;
|
|
btn.disabled = false;
|
|
}
|
|
});
|
|
|
|
// ── Save All ─────────────────────────────────────────────────────────
|
|
$(document).on("click", ".save-all-btn", function (e) {
|
|
e.preventDefault();
|
|
if (isBusy()) return;
|
|
const modalEl = document.getElementById("saveAllConfirmModal");
|
|
if (!modalEl) return;
|
|
new bootstrap.Modal(modalEl, { keyboard: false }).show();
|
|
});
|
|
|
|
$(document).on("click", "#saveAllConfirmBtn", async function () {
|
|
const confirmModal = bootstrap.Modal.getInstance(
|
|
document.getElementById("saveAllConfirmModal"),
|
|
);
|
|
if (confirmModal) confirmModal.hide();
|
|
saveAllRunning = true;
|
|
|
|
const bar = document.getElementById("batchExportBar");
|
|
const statusEl = document.getElementById("batchExportStatus");
|
|
const cancelBtn = document.getElementById("exportBatchCancelBtn");
|
|
if (bar) bar.style.display = "";
|
|
if (cancelBtn) cancelBtn.style.display = "none";
|
|
if (statusEl) statusEl.textContent = "Saving...";
|
|
|
|
const data = window.gridData || [];
|
|
const target =
|
|
typeof window.getTargetGridIds === "function"
|
|
? window.getTargetGridIds()
|
|
: null;
|
|
const dirtyRows = data
|
|
.map((r, i) => (r._dirty ? i : -1))
|
|
.filter((i) => i >= 0)
|
|
.filter(
|
|
(i) => !target || target.has(parseInt(data[i].iddatadb, 10)),
|
|
);
|
|
|
|
if (dirtyRows.length === 0) {
|
|
saveAllRunning = false;
|
|
if (bar) bar.style.display = "none";
|
|
const msgEl = document.getElementById("saveAllResultMessage");
|
|
if (msgEl) msgEl.textContent = "No changes to save.";
|
|
new bootstrap.Modal(
|
|
document.getElementById("saveAllResultModal"),
|
|
).show();
|
|
return;
|
|
}
|
|
|
|
let success = 0,
|
|
fail = 0;
|
|
|
|
for (const idx of dirtyRows) {
|
|
if (statusEl)
|
|
statusEl.textContent = `Saving ${success + fail + 1} / ${dirtyRows.length}...`;
|
|
try {
|
|
const formData = window.buildSavePayload(idx);
|
|
const resp = await fetch("save_edited_row.php", {
|
|
method: "POST",
|
|
body: formData,
|
|
});
|
|
const result = await resp.json();
|
|
if (result.success) {
|
|
data[idx]._dirty = false;
|
|
if (window.gridRenderer?.clearDirty)
|
|
window.gridRenderer.clearDirty(idx);
|
|
success++;
|
|
} else {
|
|
fail++;
|
|
}
|
|
} catch (e) {
|
|
fail++;
|
|
}
|
|
}
|
|
|
|
saveAllRunning = false;
|
|
if (bar) bar.style.display = "none";
|
|
|
|
const gr = window.gridRenderer;
|
|
if (gr) gr.renderVisibleRows();
|
|
|
|
const msg = `Saved: ${success}` + (fail > 0 ? `, Errors: ${fail}` : "");
|
|
const msgEl = document.getElementById("saveAllResultMessage");
|
|
if (msgEl) msgEl.textContent = msg;
|
|
new bootstrap.Modal(
|
|
document.getElementById("saveAllResultModal"),
|
|
).show();
|
|
});
|
|
|
|
// ── beforeunload ─────────────────────────────────────────────────────
|
|
window.addEventListener("beforeunload", function (e) {
|
|
if (window.gridData && window.gridData.some((r) => r._dirty)) {
|
|
e.preventDefault();
|
|
e.returnValue = "";
|
|
}
|
|
});
|
|
|
|
// Public
|
|
window.saveAllRunning = () => saveAllRunning;
|
|
})();
|