VisualLimsApiClientMock: fake data for all LIMS endpoints; getInstance() branches on SIMULATE_EXPORT_LIMS
get_clienti.php, get_fixed_field_data.php: simulate mode support CustomField dropdown values mock added (get_customfield_values.php) exportUnsavedModal: prompt save before export, MutationObserver waits for save, then proceeds to confirm Removed old jQuery .export-lims-btn handler that bypassed confirm modal Fix false "Unsaved changes" on page load: data-restoring guard in all programmatic trigger/dispatchEvent calls (populateSelect, populateClientDropdowns, populateDropdowns) Fix ConsegnaRichiesta not shown on refresh: add to PHP $fixedAliasMap Add step5_2_photos, step9_1_importa
This commit is contained in:
@@ -192,6 +192,16 @@ foreach ($tempMap as $f) {
|
||||
$fixedFields[] = $f;
|
||||
}
|
||||
|
||||
// Maps logical fixed_field_key → real datadb column name (mirrors JS fixedAliasMap)
|
||||
$fixedAliasMap = [
|
||||
'ClienteResponsabile' => 'cliente_responsabile_id',
|
||||
'MoltiplicatorePrezzo' => 'moltiplicatore_prezzo_id',
|
||||
'AnagraficaCertestObject' => 'anagrafica_certest_object_id',
|
||||
'AnagraficaCertestService' => 'anagrafica_certest_service_id',
|
||||
'ClienteFornitore' => 'cliente_fornitore_id',
|
||||
'ConsegnaRichiesta' => 'consegna_richiesta',
|
||||
];
|
||||
|
||||
// helper default (DATE can use 'today' if you already use it elsewhere)
|
||||
function fixedDefaultValue(array $f): string
|
||||
{
|
||||
@@ -638,12 +648,14 @@ function fixedDefaultValue(array $f): string
|
||||
}
|
||||
|
||||
#exportConfirmModal,
|
||||
#exportResponseModal {
|
||||
#exportResponseModal,
|
||||
#exportUnsavedModal {
|
||||
z-index: 1300 !important;
|
||||
}
|
||||
|
||||
#exportConfirmModal .modal-backdrop,
|
||||
#exportResponseModal .modal-backdrop {
|
||||
#exportResponseModal .modal-backdrop,
|
||||
#exportUnsavedModal .modal-backdrop {
|
||||
z-index: 1299 !important;
|
||||
}
|
||||
|
||||
@@ -1055,6 +1067,9 @@ function fixedDefaultValue(array $f): string
|
||||
<span class="status-badge status-<?= htmlspecialchars($row['status'] ?? 'i') ?>">
|
||||
<?= htmlspecialchars($row['status'] === 'i' ? 'Imported' : ($row['status'] === 'P' ? 'In Progress' : 'To LIMS')) ?>
|
||||
</span>
|
||||
<?php if (!empty($row['commessaweb'])): ?>
|
||||
<span class="commessaweb-code" style="display:block; font-size:0.75em; color:#555; margin-top:2px;" title="CommessaWeb"><?= htmlspecialchars($row['commessaweb']) ?></span>
|
||||
<?php endif; ?>
|
||||
<input type="hidden" name="rows[<?= $index ?>][status]" value="<?= htmlspecialchars($row['status'] ?? 'i') ?>">
|
||||
</div>
|
||||
<?php
|
||||
@@ -1159,7 +1174,8 @@ function fixedDefaultValue(array $f): string
|
||||
if (!empty($fixedFields)) {
|
||||
foreach ($fixedFields as $f) {
|
||||
$key = $f['fixed_field_key'];
|
||||
$val = $row[$key] ?? '';
|
||||
$dbCol = $fixedAliasMap[$key] ?? $key;
|
||||
$val = $row[$dbCol] ?? '';
|
||||
if ($val === '' || $val === null) {
|
||||
$val = fixedDefaultValue($f);
|
||||
}
|
||||
@@ -1290,32 +1306,6 @@ function fixedDefaultValue(array $f): string
|
||||
});
|
||||
});
|
||||
|
||||
$(document).on("click", ".export-lims-btn", function() {
|
||||
let rowId = $(this).data("row");
|
||||
let idDataDb = $(this).data("iddatadb");
|
||||
|
||||
$.ajax({
|
||||
url: "export_to_lims.php",
|
||||
method: "POST",
|
||||
data: {
|
||||
iddatadb: idDataDb
|
||||
},
|
||||
dataType: "json",
|
||||
beforeSend: function() {
|
||||
alert("Export started in background for row " + rowId);
|
||||
},
|
||||
success: function(response) {
|
||||
if (response.success) {
|
||||
alert(response.message);
|
||||
} else {
|
||||
alert("❌ Error: " + response.message);
|
||||
}
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
alert("❌ AJAX error: " + error);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
const inputs = document.querySelectorAll(".cell-input, .dropdown-select, .carrier-select, .awb-input, .date-picker");
|
||||
@@ -1345,6 +1335,7 @@ function fixedDefaultValue(array $f): string
|
||||
|
||||
inputs.forEach(el => {
|
||||
el.addEventListener("change", () => {
|
||||
if (el.hasAttribute('data-restoring')) return;
|
||||
hasChanges = true;
|
||||
|
||||
const gridCell = el.closest(".grid-cell");
|
||||
@@ -1443,7 +1434,8 @@ function fixedDefaultValue(array $f): string
|
||||
hasChanges = changedRows.size > 0;
|
||||
|
||||
|
||||
alert('Salvataggio riga avvenuto con successo!');
|
||||
const toastEl = document.getElementById('saveSuccessToast');
|
||||
if (toastEl) bootstrap.Toast.getOrCreateInstance(toastEl).show();
|
||||
} else {
|
||||
alert('Errore durante il salvataggio: ' + data.message);
|
||||
}
|
||||
@@ -1561,7 +1553,7 @@ function fixedDefaultValue(array $f): string
|
||||
});
|
||||
|
||||
// Gestisci la chiusura dei modali per rimuovere i backdrop
|
||||
document.querySelectorAll('#exportConfirmModal, #exportResponseModal').forEach(modal => {
|
||||
document.querySelectorAll('#exportConfirmModal, #exportResponseModal, #exportUnsavedModal').forEach(modal => {
|
||||
modal.addEventListener('hidden.bs.modal', () => {
|
||||
// Rimuovi tutti i backdrop residui
|
||||
document.querySelectorAll('.modal-backdrop').forEach(backdrop => {
|
||||
@@ -1657,10 +1649,12 @@ function fixedDefaultValue(array $f): string
|
||||
// Ripristina il valore corrente
|
||||
if (currentValue) {
|
||||
dropdown.value = currentValue;
|
||||
dropdown.setAttribute('data-restoring', '');
|
||||
const event = new Event('change', {
|
||||
bubbles: true
|
||||
});
|
||||
dropdown.dispatchEvent(event);
|
||||
dropdown.removeAttribute('data-restoring');
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1969,7 +1963,9 @@ function fixedDefaultValue(array $f): string
|
||||
s2container.after(dropdown);
|
||||
}
|
||||
if (valToSelect) {
|
||||
dropdown.setAttribute('data-restoring', '');
|
||||
$(dropdown).val(valToSelect).trigger('change');
|
||||
dropdown.removeAttribute('data-restoring');
|
||||
}
|
||||
} else {
|
||||
// Select nativa
|
||||
@@ -1988,9 +1984,11 @@ function fixedDefaultValue(array $f): string
|
||||
});
|
||||
if (valToSelect) {
|
||||
dropdown.value = valToSelect;
|
||||
dropdown.setAttribute('data-restoring', '');
|
||||
dropdown.dispatchEvent(new Event('change', {
|
||||
bubbles: true
|
||||
}));
|
||||
dropdown.removeAttribute('data-restoring');
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -2083,10 +2081,12 @@ function fixedDefaultValue(array $f): string
|
||||
// Ripristina il valore corrente
|
||||
if (currentValue) {
|
||||
dropdown.value = currentValue;
|
||||
dropdown.setAttribute('data-restoring', '');
|
||||
const event = new Event('change', {
|
||||
bubbles: true
|
||||
});
|
||||
dropdown.dispatchEvent(event);
|
||||
dropdown.removeAttribute('data-restoring');
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -2528,7 +2528,9 @@ function fixedDefaultValue(array $f): string
|
||||
if (currentVal) {
|
||||
const found = results.find(r => String(r.id) === String(currentVal));
|
||||
if (found) {
|
||||
$select[0].setAttribute('data-restoring', '');
|
||||
$select.val(currentVal).trigger('change');
|
||||
$select[0].removeAttribute('data-restoring');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2715,6 +2717,35 @@ function fixedDefaultValue(array $f): string
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modal: unsaved changes before export -->
|
||||
<div class="modal fade" id="exportUnsavedModal" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Modifiche non salvate</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
La riga contiene modifiche non salvate. Salvare prima di procedere con l'esportazione?
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary btn-sm" data-bs-dismiss="modal">Annulla</button>
|
||||
<button type="button" class="btn btn-primary btn-sm" id="saveAndExportBtn">Salva ed Esporta</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Toast: row saved successfully -->
|
||||
<div class="position-fixed bottom-0 end-0 p-3" style="z-index:9999">
|
||||
<div id="saveSuccessToast" class="toast align-items-center text-bg-success border-0" role="alert" data-bs-delay="2500">
|
||||
<div class="d-flex">
|
||||
<div class="toast-body"><i class="fas fa-check-circle me-2"></i>Riga salvata con successo.</div>
|
||||
<button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast"></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user