Add formula template export/import and unsaved-changes guard

- Export: GET /CompanySettings/ExportCustomItemTemplates downloads all
  company templates as an indented JSON backup (strips internal IDs/paths)
- Import: POST /CompanySettings/ImportCustomItemTemplates restores from
  that file; runs full field + formula validation, skips name duplicates,
  returns per-item results (imported / skipped / errors)
- Unsaved-changes guard: cfModal now intercepts backdrop/ESC/X when the
  form is dirty and prompts before discarding work
- Export and Import buttons added to the Custom Formulas card header

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-02 09:24:02 -04:00
parent cf07356147
commit b23bea6db0
3 changed files with 277 additions and 0 deletions
@@ -2197,6 +2197,15 @@
<button type="button" class="btn btn-outline-secondary btn-sm" onclick="cfShowWalkthrough()">
<i class="bi bi-question-circle me-1"></i>How it works
</button>
<a href="/CompanySettings/ExportCustomItemTemplates"
class="btn btn-outline-secondary btn-sm"
title="Download all templates as a JSON backup file">
<i class="bi bi-download me-1"></i>Export
</a>
<button type="button" class="btn btn-outline-secondary btn-sm" onclick="cfShowImport()"
title="Restore templates from a JSON backup file">
<i class="bi bi-upload me-1"></i>Import
</button>
<button type="button" class="btn btn-primary btn-sm" onclick="cfShowCreate()">
<i class="bi bi-plus-circle me-1"></i>New Template
</button>
@@ -2281,6 +2290,40 @@
</div>
</div>
<!-- Custom Formula Import Modal -->
<div class="modal fade" id="cfImportModal" tabindex="-1" aria-labelledby="cfImportModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="cfImportModalLabel">
<i class="bi bi-upload me-2"></i>Import Formula Templates
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<p class="text-muted small mb-3">
Select a <code>.json</code> file previously exported from this page.
Templates whose name already exists in your account will be skipped.
</p>
<div class="mb-3">
<label class="form-label fw-semibold">Backup file <span class="text-danger">*</span></label>
<input type="file" id="cfImportFile" class="form-control" accept=".json" />
</div>
<div id="cfImportResults" class="d-none">
<hr />
<div id="cfImportSummary"></div>
</div>
</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" id="cfImportBtn" onclick="cfSubmitImport()">
<i class="bi bi-upload me-1"></i>Import
</button>
</div>
</div>
</div>
</div>
<!-- Custom Formula Walkthrough Modal -->
<div class="modal fade" id="cfWalkthroughModal" tabindex="-1" aria-labelledby="cfWalkthroughLabel" aria-hidden="true">
<div class="modal-dialog modal-lg modal-dialog-centered modal-dialog-scrollable">