Add formula template walkthrough and UX improvements

- 7-step guided walkthrough modal (concept, output modes, fields, formula,
  testing, box example, cylinder example); auto-shown first time the tab
  opens with no templates; always accessible via "How it works" button
- Variable pill badges below formula input showing all valid field names + rate;
  update live as fields are added/renamed; clickable to insert at cursor
- Fix: Add Field no longer shows validation error on blank new rows; validation
  only fires once the user has typed something
- Help article: added Common Formula Patterns section with box, cylinder, and
  flat panel worked examples (fields table + formula + expected output)
- HelpKnowledgeBase updated with pattern examples and walkthrough note

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-24 11:40:54 -04:00
parent 4650ba3d4d
commit d28e639d1b
4 changed files with 415 additions and 17 deletions
@@ -2064,9 +2064,14 @@
<div class="card shadow-sm mt-3">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="mb-0"><i class="bi bi-calculator me-2"></i>Custom Formula Item Templates</h5>
<button type="button" class="btn btn-primary btn-sm" onclick="cfShowCreate()">
<i class="bi bi-plus-circle me-1"></i>New Template
</button>
<div class="d-flex gap-2">
<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>
<button type="button" class="btn btn-primary btn-sm" onclick="cfShowCreate()">
<i class="bi bi-plus-circle me-1"></i>New Template
</button>
</div>
</div>
<div class="card-body">
<p class="text-muted small mb-3">
@@ -2097,6 +2102,34 @@
</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">
<div class="modal-content">
<div class="modal-header border-0 pb-0">
<h5 class="modal-title" id="cfWalkthroughLabel">
<i class="bi bi-calculator text-info me-2"></i>Custom Formula Templates &mdash; How It Works
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body pt-2">
<!-- Step progress dots -->
<div class="d-flex justify-content-center gap-2 mb-4" id="cfWalkthroughDots"></div>
<!-- Step content -->
<div id="cfWalkthroughContent"></div>
</div>
<div class="modal-footer border-0">
<button type="button" class="btn btn-outline-secondary" id="cfWtPrevBtn" onclick="cfWalkthroughNav(-1)">
<i class="bi bi-arrow-left me-1"></i>Back
</button>
<button type="button" class="btn btn-primary" id="cfWtNextBtn" onclick="cfWalkthroughNav(1)">
Next<i class="bi bi-arrow-right ms-1"></i>
</button>
</div>
</div>
</div>
</div>
<!-- Custom Formula Template Modal -->
<div class="modal fade" id="cfModal" tabindex="-1" aria-labelledby="cfModalLabel" aria-hidden="true">
<div class="modal-dialog modal-xl modal-dialog-scrollable">
@@ -2138,7 +2171,10 @@
<div class="mb-3">
<label class="form-label">Formula <span class="text-danger">*</span></label>
<input type="text" id="cfFormula" class="form-control font-monospace" placeholder="e.g. 2*(L*W + L*H + W*H)/144 * rate" />
<div class="form-text">NCalc expression. Available variables: field names + <code>rate</code>.</div>
<div class="form-text mt-1">
<span class="me-1">Available variables for this formula:</span>
<span id="cfVariablePills"></span>
</div>
</div>
<div class="mb-3">
<label class="form-label">Notes</label>
@@ -3438,9 +3474,16 @@
</script>
<script src="~/js/company-settings-custom-formulas.js" asp-append-version="true"></script>
<script>
// Load formula templates when the tab is first shown
document.querySelector('[data-bs-target="#custom-formulas"]').addEventListener('shown.bs.tab', () => {
if (!window._cfLoaded) { cfLoadTemplates(); window._cfLoaded = true; }
// Load formula templates when the tab is first shown; auto-show walkthrough if no templates yet
document.querySelector('[data-bs-target="#custom-formulas"]').addEventListener('shown.bs.tab', async () => {
if (!window._cfLoaded) {
await cfLoadTemplates();
window._cfLoaded = true;
if (!localStorage.getItem('cfWalkthroughSeen')) {
const hasTemplates = document.querySelectorAll('#cfTemplatesBody tr[data-id]').length > 0;
if (!hasTemplates) cfShowWalkthrough();
}
}
});
</script>