Add Community Formula Library feature

Companies can now share their custom formula templates to a platform-wide
community library. Other tenants can browse, preview, and import formulas
as independent local copies. Includes attribution (source company name),
"Inspired by" lineage for re-contributed formulas, import counts, own-formula
badge, cascade diagram nullification, and AI assistant + help docs updates.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-27 21:54:51 -04:00
parent 32d09b38f1
commit ca7e905832
24 changed files with 12959 additions and 10 deletions
@@ -2177,6 +2177,10 @@
<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>
<div class="d-flex gap-2">
<a asp-controller="FormulaLibrary" asp-action="Index"
class="btn btn-outline-info btn-sm">
<i class="bi bi-collection me-1"></i>Community Library
</a>
<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>
@@ -2190,6 +2194,8 @@
Define reusable pricing formulas for complex fabricated items (roof curbs, enclosures, frames).
When a user adds a formula item to a quote or job, they fill in the measurements and the formula
calculates the price automatically.
Browse the <a asp-controller="FormulaLibrary" asp-action="Index">Community Library</a> to import
formulas shared by other shops.
</p>
<div class="table-responsive">
<table class="table table-sm table-hover align-middle" id="cfTemplatesTable">
@@ -2199,11 +2205,12 @@
<th>Output Mode</th>
<th>Fields</th>
<th>Active</th>
<th>Library</th>
<th></th>
</tr>
</thead>
<tbody id="cfTemplatesBody">
<tr><td colspan="5" class="text-muted text-center py-3">Loading&hellip;</td></tr>
<tr><td colspan="6" class="text-muted text-center py-3">Loading&hellip;</td></tr>
</tbody>
</table>
</div>
@@ -2212,6 +2219,52 @@
</div>
}
@* Share modal lives inside the AllowCustomFormulas block so it is always in the DOM
when the Share button can appear — prevents stale-cache mismatches. *@
@if (ViewBag.AllowCustomFormulas == true)
{
<div class="modal fade" id="cfShareModal" tabindex="-1" aria-labelledby="cfShareModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="cfShareModalLabel">
<i class="bi bi-collection me-2 text-info"></i>Share to Community Library
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<input type="hidden" id="cfShareTemplateId" value="0" />
<p class="text-muted small mb-3">
Your formula will be visible to all Powder Coating Logix users and can be imported
into their local library. You can remove it from the community library at any time &mdash;
anyone who has already imported it will keep their copy.
</p>
<div class="mb-3">
<label class="form-label fw-semibold">Tags <small class="text-muted">(optional, comma-separated)</small></label>
<input type="text" class="form-control" id="cfShareTags"
placeholder="e.g. HVAC, Sheet Metal, Enclosures" />
</div>
<div class="mb-3">
<label class="form-label fw-semibold">Industry Hint <small class="text-muted">(optional)</small></label>
<input type="text" class="form-control" id="cfShareIndustryHint"
placeholder="e.g. HVAC, Automotive, Structural" />
</div>
<div id="cfShareInspiredBy" class="alert alert-light border fst-italic small py-2" style="display:none">
<i class="bi bi-diagram-2 me-1"></i>
This formula will be listed as &ldquo;Inspired by&rdquo; the original community entry.
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-info text-white" id="cfShareConfirmBtn" onclick="cfConfirmShare()">
<i class="bi bi-collection me-1"></i>Share to Library
</button>
</div>
</div>
</div>
</div>
}
</div>
</div>
@@ -2283,7 +2336,9 @@
</div>
<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" />
<textarea id="cfFormula" class="form-control font-monospace" rows="3"
style="resize:vertical;min-height:4rem"
placeholder="e.g. 2*(L*W + L*H + W*H)/144 * rate"></textarea>
<div class="form-text mt-1">
<span class="me-1">Variables (click to insert):</span>
<span id="cfVariablePills"></span>