131 lines
5.4 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 dirtyRows = data.map((r, i) => r._dirty ? i : -1).filter(i => i >= 0);
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;
})();