diff --git a/src/PowderCoating.Web/wwwroot/js/company-settings-custom-formulas.js b/src/PowderCoating.Web/wwwroot/js/company-settings-custom-formulas.js
index b5b58ff..b594450 100644
--- a/src/PowderCoating.Web/wwwroot/js/company-settings-custom-formulas.js
+++ b/src/PowderCoating.Web/wwwroot/js/company-settings-custom-formulas.js
@@ -4,6 +4,7 @@
(function () {
let cfFields = [];
let cfEditing = false;
+ let cfFormDirty = false;
// ── Load & Render ─────────────────────────────────────────────────────────
@@ -221,9 +222,11 @@
document.getElementById('cfDiagramImg').src = `/CompanySettings/TemplateDiagram?templateId=${t.id}`;
document.getElementById('cfDiagramPreview').style.display = '';
}
+ cfFormDirty = false;
}
function cfResetForm() {
+ cfFormDirty = false;
document.getElementById('cfId').value = '0';
document.getElementById('cfName').value = '';
document.getElementById('cfDescription').value = '';
@@ -528,6 +531,7 @@
});
}
+ cfFormDirty = false;
bootstrap.Modal.getInstance(document.getElementById('cfModal'))?.hide();
cfLoadTemplates();
} catch (e) {
@@ -862,4 +866,103 @@
cfWtStep = i;
cfRenderWtStep();
};
+
+ // ── Import ────────────────────────────────────────────────────────────────
+
+ window.cfShowImport = function () {
+ document.getElementById('cfImportFile').value = '';
+ document.getElementById('cfImportResults').classList.add('d-none');
+ document.getElementById('cfImportSummary').innerHTML = '';
+ const btn = document.getElementById('cfImportBtn');
+ btn.disabled = false;
+ btn.innerHTML = '
Import';
+ new bootstrap.Modal(document.getElementById('cfImportModal')).show();
+ };
+
+ window.cfSubmitImport = async function () {
+ const fileInput = document.getElementById('cfImportFile');
+ if (!fileInput.files.length) {
+ showCfError('Please select a .json export file first.');
+ return;
+ }
+
+ const btn = document.getElementById('cfImportBtn');
+ btn.disabled = true;
+ btn.innerHTML = '
Importing…';
+
+ const form = new FormData();
+ form.append('file', fileInput.files[0]);
+ form.append('__RequestVerificationToken', getAntiForgeryToken());
+
+ try {
+ const res = await fetch('/CompanySettings/ImportCustomItemTemplates', { method: 'POST', body: form });
+ const data = await res.json();
+
+ const resultsEl = document.getElementById('cfImportResults');
+ const summaryEl = document.getElementById('cfImportSummary');
+ resultsEl.classList.remove('d-none');
+
+ if (!data.success) {
+ summaryEl.innerHTML = `
${escHtml(data.message)}
`;
+ btn.disabled = false;
+ btn.innerHTML = '
Import';
+ return;
+ }
+
+ let html = '';
+
+ if (data.imported > 0)
+ html += `
${data.imported} template${data.imported !== 1 ? 's' : ''} imported successfully.
`;
+
+ if (data.skipped > 0) {
+ const names = (data.skippedNames || []).map(n => `
${escHtml(n)}`).join('');
+ html += `
+
${data.skipped} skipped — name already exists:
+
+
`;
+ }
+
+ if (data.errors && data.errors.length) {
+ const items = data.errors.map(e => `
${escHtml(e)}`).join('');
+ html += `
+
${data.errors.length} error${data.errors.length !== 1 ? 's' : ''}:
+
+
`;
+ }
+
+ if (data.imported === 0 && data.skipped === 0 && (!data.errors || !data.errors.length))
+ html = '
The file contained no templates to import.
';
+
+ summaryEl.innerHTML = html;
+ btn.disabled = true;
+ btn.innerHTML = '
Done';
+
+ if (data.imported > 0) cfLoadTemplates();
+ } catch (e) {
+ showCfError('Import request failed: ' + e.message);
+ btn.disabled = false;
+ btn.innerHTML = '
Import';
+ }
+ };
+
+ // ── Unsaved-changes guard ─────────────────────────────────────────────────
+
+ document.addEventListener('DOMContentLoaded', function () {
+ const modal = document.getElementById('cfModal');
+ if (!modal) return;
+
+ // Any user interaction inside the modal marks the form dirty
+ modal.addEventListener('input', function () { cfFormDirty = true; });
+ modal.addEventListener('change', function () { cfFormDirty = true; });
+
+ // Intercept backdrop click, ESC, and the X button when there is unsaved work
+ modal.addEventListener('hide.bs.modal', function (e) {
+ if (!cfFormDirty) return;
+ e.preventDefault();
+ if (confirm('You have unsaved changes. Close anyway and lose your work?')) {
+ cfFormDirty = false;
+ bootstrap.Modal.getInstance(modal)?.hide();
+ }
+ });
+ });
})();