Restructure formula template modal for correct mobile flow

Reorganises the Add/Edit Formula Template modal into four logical rows
so that on mobile the sections stack in the natural authoring order:
  1. Name / Description | Output Mode / Rate
  2. Fields (left) | Formula + Test (right)
  3. Diagram | AI Generator
  4. Notes + Active (full width)

Previously, Fields appeared after the Formula on mobile because the left
column (containing Formula) stacked before the right column (containing
Fields). Also compacted Default Rate and Rate Label into a 2-column
mini-row so they sit side by side on all screen sizes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-27 23:00:39 -04:00
parent 0deef574c3
commit 81119035c7
@@ -2319,16 +2319,20 @@
</div> </div>
<div class="modal-body"> <div class="modal-body">
<input type="hidden" id="cfId" value="0" /> <input type="hidden" id="cfId" value="0" />
<div class="row g-3">
<!-- Row 1: basic info -->
<div class="row g-3 mb-2">
<div class="col-md-6"> <div class="col-md-6">
<div class="mb-3"> <div class="mb-3">
<label class="form-label">Name <span class="text-danger">*</span></label> <label class="form-label">Name <span class="text-danger">*</span></label>
<input type="text" id="cfName" class="form-control" placeholder="e.g. Roof Curb" maxlength="100" /> <input type="text" id="cfName" class="form-control" placeholder="e.g. Roof Curb" maxlength="100" />
</div> </div>
<div class="mb-3"> <div class="mb-3 mb-md-0">
<label class="form-label">Description</label> <label class="form-label">Description</label>
<input type="text" id="cfDescription" class="form-control" maxlength="500" /> <input type="text" id="cfDescription" class="form-control" maxlength="500" />
</div> </div>
</div>
<div class="col-md-6">
<div class="mb-3"> <div class="mb-3">
<label class="form-label">Output Mode <span class="text-danger">*</span></label> <label class="form-label">Output Mode <span class="text-danger">*</span></label>
<select id="cfOutputMode" class="form-select" onchange="cfToggleRateFields()"> <select id="cfOutputMode" class="form-select" onchange="cfToggleRateFields()">
@@ -2337,16 +2341,36 @@
</select> </select>
</div> </div>
<div id="cfRateFields"> <div id="cfRateFields">
<div class="mb-3"> <div class="row g-2">
<label class="form-label">Default Rate</label> <div class="col-6">
<input type="number" id="cfDefaultRate" class="form-control" step="0.01" placeholder="e.g. 0.85" /> <label class="form-label">Default Rate</label>
<div class="form-text">Used as the <code>rate</code> variable if not overridden per-quote.</div> <input type="number" id="cfDefaultRate" class="form-control" step="0.01" placeholder="e.g. 0.85" />
</div> <div class="form-text">Pre-fills the <code>rate</code> variable.</div>
<div class="mb-3"> </div>
<label class="form-label">Rate Label</label> <div class="col-6">
<input type="text" id="cfRateLabel" class="form-control" maxlength="50" placeholder="e.g. $/sq ft" /> <label class="form-label">Rate Label</label>
<input type="text" id="cfRateLabel" class="form-control" maxlength="50" placeholder="e.g. $/sq ft" />
</div>
</div> </div>
</div> </div>
</div>
</div>
<hr class="my-2" />
<!-- Row 2: fields (left) + formula (right) — on mobile, fields come first -->
<div class="row g-3 mb-2">
<div class="col-md-6">
<div class="mb-3">
<label class="form-label">Fields</label>
<div class="form-text mb-2">Define the measurement inputs users will fill in.</div>
<div id="cfFieldsList"></div>
<button type="button" class="btn btn-outline-secondary btn-sm mt-2" onclick="cfAddField()">
<i class="bi bi-plus"></i> Add Field
</button>
</div>
</div>
<div class="col-md-6">
<div class="mb-3"> <div class="mb-3">
<label class="form-label">Formula <span class="text-danger">*</span></label> <label class="form-label">Formula <span class="text-danger">*</span></label>
<textarea id="cfFormula" class="form-control font-monospace" rows="3" <textarea id="cfFormula" class="form-control font-monospace" rows="3"
@@ -2391,24 +2415,6 @@
</div> </div>
</div> </div>
</div> </div>
<div class="mb-3">
<label class="form-label">Notes</label>
<textarea id="cfNotes" class="form-control" rows="2" maxlength="1000"></textarea>
</div>
<div class="form-check mb-3">
<input type="checkbox" id="cfIsActive" class="form-check-input" checked />
<label class="form-check-label" for="cfIsActive">Active (show in quote/job wizard)</label>
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label class="form-label">Fields</label>
<div class="form-text mb-2">Define the measurement inputs users will fill in.</div>
<div id="cfFieldsList"></div>
<button type="button" class="btn btn-outline-secondary btn-sm mt-2" onclick="cfAddField()">
<i class="bi bi-plus"></i> Add Field
</button>
</div>
<div class="mb-3"> <div class="mb-3">
<label class="form-label">Formula Test</label> <label class="form-label">Formula Test</label>
<div class="d-flex gap-2 align-items-center"> <div class="d-flex gap-2 align-items-center">
@@ -2419,7 +2425,15 @@
</div> </div>
<div class="form-text">Uses the default values from your field list.</div> <div class="form-text">Uses the default values from your field list.</div>
</div> </div>
<div class="mb-3"> </div>
</div>
<hr class="my-2" />
<!-- Row 3: diagram + AI generator -->
<div class="row g-3 mb-2">
<div class="col-md-6">
<div class="mb-3 mb-md-0">
<label class="form-label">Diagram / Shop Drawing</label> <label class="form-label">Diagram / Shop Drawing</label>
<div id="cfDiagramPreview" class="mb-2" style="display:none;"> <div id="cfDiagramPreview" class="mb-2" style="display:none;">
<img id="cfDiagramImg" src="" alt="Diagram" class="img-fluid rounded border" style="max-height:180px;" /> <img id="cfDiagramImg" src="" alt="Diagram" class="img-fluid rounded border" style="max-height:180px;" />
@@ -2427,7 +2441,9 @@
<input type="file" id="cfDiagramFile" class="form-control form-control-sm" accept="image/*" onchange="cfPreviewDiagram(event)" /> <input type="file" id="cfDiagramFile" class="form-control form-control-sm" accept="image/*" onchange="cfPreviewDiagram(event)" />
<div class="form-text">Optional. Upload a shop drawing or photo to help users recognize this item.</div> <div class="form-text">Optional. Upload a shop drawing or photo to help users recognize this item.</div>
</div> </div>
<div class="mb-3"> </div>
<div class="col-md-6">
<div class="mb-3 mb-md-0">
<label class="form-label">AI Formula Generator</label> <label class="form-label">AI Formula Generator</label>
<div class="input-group"> <div class="input-group">
<input type="text" id="cfAiPrompt" class="form-control" placeholder="Describe the item, e.g. 'Rectangular roof curb with flanged base'" /> <input type="text" id="cfAiPrompt" class="form-control" placeholder="Describe the item, e.g. 'Rectangular roof curb with flanged base'" />
@@ -2439,6 +2455,23 @@
</div> </div>
</div> </div>
</div> </div>
<hr class="my-2" />
<!-- Row 4: notes + active -->
<div class="row g-3">
<div class="col-12">
<label class="form-label">Notes</label>
<textarea id="cfNotes" class="form-control" rows="2" maxlength="1000"></textarea>
</div>
<div class="col-12">
<div class="form-check">
<input type="checkbox" id="cfIsActive" class="form-check-input" checked />
<label class="form-check-label" for="cfIsActive">Active (show in quote/job wizard)</label>
</div>
</div>
</div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Cancel</button> <button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Cancel</button>