Add Operations/Finance mode switcher to sidebar nav
Two-tab strip between Dashboard and the Operations section lets users toggle between the shop-management view and the accounting view. FOUC-prevention: server-side controller detection stamps data-nav-mode on <html> before first paint; CSS hides the inactive side instantly. JS (nav-mode.js) auto-switches to Finance when navigating to an accounting controller, restores saved preference everywhere else. Vendors appears in both modes; all 39 nav items carry data-nav tags. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -32,6 +32,15 @@
|
|||||||
_ => "#374151" // gray-700 for anything else
|
_ => "#374151" // gray-700 for anything else
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Nav mode: used by FOUC-prevention inline script + nav-mode.js
|
||||||
|
var _finCtrlSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase) {
|
||||||
|
"bills", "accounts", "journalentries", "vendorcredits",
|
||||||
|
"bankreconciliations", "fixedassets", "budgets", "recurringtemplates",
|
||||||
|
"accountingexport", "taxrates"
|
||||||
|
};
|
||||||
|
var _navController = ViewContext.RouteData.Values["controller"]?.ToString() ?? "";
|
||||||
|
var _serverNavMode = _finCtrlSet.Contains(_navController) ? "fin" : "ops";
|
||||||
|
|
||||||
if (User.Identity?.IsAuthenticated == true)
|
if (User.Identity?.IsAuthenticated == true)
|
||||||
{
|
{
|
||||||
if (isImpersonating)
|
if (isImpersonating)
|
||||||
@@ -319,6 +328,54 @@
|
|||||||
width: 1.5rem;
|
width: 1.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ── Nav mode: FOUC prevention — CSS wins before JS runs ─────── */
|
||||||
|
html[data-nav-mode="ops"] [data-nav="fin"] { display: none !important; }
|
||||||
|
html[data-nav-mode="fin"] [data-nav="ops"] { display: none !important; }
|
||||||
|
|
||||||
|
/* ── Nav mode strip (Operations | Finance tab switcher) ──────── */
|
||||||
|
.nav-mode-strip {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 3px;
|
||||||
|
padding: 8px 12px 10px;
|
||||||
|
border-bottom: 1px solid rgba(255,255,255,0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-mode-btn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 5px;
|
||||||
|
padding: 7px 6px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 5px;
|
||||||
|
font-family: var(--font-mono, 'IBM Plex Mono', ui-monospace, monospace);
|
||||||
|
font-size: 0.64rem;
|
||||||
|
font-weight: 500;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.08em;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background 0.15s, color 0.15s;
|
||||||
|
background: transparent;
|
||||||
|
color: rgba(255,255,255,0.38);
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-mode-btn i {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-mode-btn:hover {
|
||||||
|
background: rgba(255,255,255,0.08);
|
||||||
|
color: rgba(255,255,255,0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-mode-btn.active {
|
||||||
|
background: var(--pcl-ember, #d97706);
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
/* Main Content */
|
/* Main Content */
|
||||||
.main-content {
|
.main-content {
|
||||||
margin-left: var(--sidebar-width);
|
margin-left: var(--sidebar-width);
|
||||||
@@ -878,7 +935,10 @@
|
|||||||
@* Page-specific styles *@
|
@* Page-specific styles *@
|
||||||
@await RenderSectionAsync("Styles", required: false)
|
@await RenderSectionAsync("Styles", required: false)
|
||||||
</head>
|
</head>
|
||||||
<body style="padding-top: var(--env-banner-height);">
|
<body style="padding-top: var(--env-banner-height);" data-controller="@_navController.ToLower()">
|
||||||
|
<script>
|
||||||
|
(function(){var s='@_serverNavMode',p=localStorage.getItem('pcl-nav-mode')||'ops';document.documentElement.dataset.navMode=s==='fin'?'fin':p;})();
|
||||||
|
</script>
|
||||||
@if (_isNonProd)
|
@if (_isNonProd)
|
||||||
{
|
{
|
||||||
<div style="position:fixed;top:0;left:0;width:100%;height:var(--env-banner-height);z-index:2000;
|
<div style="position:fixed;top:0;left:0;width:100%;height:var(--env-banner-height);z-index:2000;
|
||||||
@@ -1010,56 +1070,66 @@
|
|||||||
var showInventorySection = hasInventory || hasVendors;
|
var showInventorySection = hasInventory || hasVendors;
|
||||||
var showEquipmentSection = hasEquipment || hasMaintenance;
|
var showEquipmentSection = hasEquipment || hasMaintenance;
|
||||||
|
|
||||||
<div class="nav-section-title">Main Menu</div>
|
<div class="nav-section-title" data-nav="both">Main Menu</div>
|
||||||
<a asp-controller="Dashboard" asp-action="Index" class="nav-link">
|
<a asp-controller="Dashboard" asp-action="Index" class="nav-link" data-nav="both">
|
||||||
<i class="bi bi-house-door"></i>
|
<i class="bi bi-house-door"></i>
|
||||||
<span>Dashboard</span>
|
<span>Dashboard</span>
|
||||||
</a>
|
</a>
|
||||||
@if (!isPlatformAdmin)
|
@if (!isPlatformAdmin)
|
||||||
{
|
{
|
||||||
|
<div class="nav-mode-strip" role="tablist" aria-label="Navigation mode">
|
||||||
|
<button class="nav-mode-btn" data-mode="ops" role="tab" aria-selected="true" title="Operations">
|
||||||
|
<i class="bi bi-tools"></i>
|
||||||
|
<span>Operations</span>
|
||||||
|
</button>
|
||||||
|
<button class="nav-mode-btn" data-mode="fin" role="tab" aria-selected="false" title="Finance">
|
||||||
|
<i class="bi bi-journal-bookmark"></i>
|
||||||
|
<span>Finance</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
@* ── Operations ───────────────────────────────────────────── *@
|
@* ── Operations ───────────────────────────────────────────── *@
|
||||||
@if (showOperations)
|
@if (showOperations)
|
||||||
{
|
{
|
||||||
<div class="nav-section-title">Operations</div>
|
<div class="nav-section-title" data-nav="ops">Operations</div>
|
||||||
}
|
}
|
||||||
@if (hasCustomers)
|
@if (hasCustomers)
|
||||||
{
|
{
|
||||||
<a asp-controller="Customers" asp-action="Index" class="nav-link">
|
<a asp-controller="Customers" asp-action="Index" class="nav-link" data-nav="ops">
|
||||||
<i class="bi bi-people"></i>
|
<i class="bi bi-people"></i>
|
||||||
<span>Customers</span>
|
<span>Customers</span>
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
@if (hasQuotes)
|
@if (hasQuotes)
|
||||||
{
|
{
|
||||||
<a asp-controller="Quotes" asp-action="Index" class="nav-link">
|
<a asp-controller="Quotes" asp-action="Index" class="nav-link" data-nav="ops">
|
||||||
<i class="bi bi-file-text"></i>
|
<i class="bi bi-file-text"></i>
|
||||||
<span>Quotes</span>
|
<span>Quotes</span>
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
@if (hasJobs)
|
@if (hasJobs)
|
||||||
{
|
{
|
||||||
<a asp-controller="Jobs" asp-action="Index" class="nav-link">
|
<a asp-controller="Jobs" asp-action="Index" class="nav-link" data-nav="ops">
|
||||||
<i class="bi bi-briefcase"></i>
|
<i class="bi bi-briefcase"></i>
|
||||||
<span>Jobs</span>
|
<span>Jobs</span>
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
@if (hasInvoices)
|
@if (hasInvoices)
|
||||||
{
|
{
|
||||||
<a asp-controller="Invoices" asp-action="Index" class="nav-link">
|
<a asp-controller="Invoices" asp-action="Index" class="nav-link" data-nav="ops">
|
||||||
<i class="bi bi-receipt"></i>
|
<i class="bi bi-receipt"></i>
|
||||||
<span>Invoices</span>
|
<span>Invoices</span>
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
@if (hasCalendar)
|
@if (hasCalendar)
|
||||||
{
|
{
|
||||||
<a asp-controller="Appointments" asp-action="Calendar" asp-route-view="month" class="nav-link">
|
<a asp-controller="Appointments" asp-action="Calendar" asp-route-view="month" class="nav-link" data-nav="ops">
|
||||||
<i class="bi bi-calendar-event"></i>
|
<i class="bi bi-calendar-event"></i>
|
||||||
<span>Appointments</span>
|
<span>Appointments</span>
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
@if (hasJobs)
|
@if (hasJobs)
|
||||||
{
|
{
|
||||||
<a asp-controller="JobsPriority" asp-action="Index" class="nav-link">
|
<a asp-controller="JobsPriority" asp-action="Index" class="nav-link" data-nav="ops">
|
||||||
<i class="bi bi-clipboard2-check"></i>
|
<i class="bi bi-clipboard2-check"></i>
|
||||||
<span>Daily Board</span>
|
<span>Daily Board</span>
|
||||||
</a>
|
</a>
|
||||||
@@ -1069,19 +1139,19 @@
|
|||||||
@if (hasInvoices)
|
@if (hasInvoices)
|
||||||
{
|
{
|
||||||
var _allowOnlinePayments = Context.Items["AllowOnlinePayments"] as bool? ?? false;
|
var _allowOnlinePayments = Context.Items["AllowOnlinePayments"] as bool? ?? false;
|
||||||
<div class="nav-section-title">Billing & Payments</div>
|
<div class="nav-section-title" data-nav="ops">Billing & Payments</div>
|
||||||
@if (_allowOnlinePayments)
|
@if (_allowOnlinePayments)
|
||||||
{
|
{
|
||||||
<a asp-controller="Invoices" asp-action="OnlinePayments" class="nav-link">
|
<a asp-controller="Invoices" asp-action="OnlinePayments" class="nav-link" data-nav="ops">
|
||||||
<i class="bi bi-credit-card"></i>
|
<i class="bi bi-credit-card"></i>
|
||||||
<span>Online Payments</span>
|
<span>Online Payments</span>
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
<a asp-controller="CreditMemos" asp-action="Index" class="nav-link">
|
<a asp-controller="CreditMemos" asp-action="Index" class="nav-link" data-nav="ops">
|
||||||
<i class="bi bi-journal-minus"></i>
|
<i class="bi bi-journal-minus"></i>
|
||||||
<span>Credit Memos</span>
|
<span>Credit Memos</span>
|
||||||
</a>
|
</a>
|
||||||
<a asp-controller="GiftCertificates" asp-action="Index" class="nav-link">
|
<a asp-controller="GiftCertificates" asp-action="Index" class="nav-link" data-nav="ops">
|
||||||
<i class="bi bi-gift"></i>
|
<i class="bi bi-gift"></i>
|
||||||
<span>Gift Certificates</span>
|
<span>Gift Certificates</span>
|
||||||
</a>
|
</a>
|
||||||
@@ -1090,18 +1160,18 @@
|
|||||||
@* ── Inventory & Purchasing ───────────────────────────────── *@
|
@* ── Inventory & Purchasing ───────────────────────────────── *@
|
||||||
@if (hasProducts || showInventorySection)
|
@if (hasProducts || showInventorySection)
|
||||||
{
|
{
|
||||||
<div class="nav-section-title">Inventory & Purchasing</div>
|
<div class="nav-section-title" data-nav="ops">Inventory & Purchasing</div>
|
||||||
}
|
}
|
||||||
@if (hasProducts)
|
@if (hasProducts)
|
||||||
{
|
{
|
||||||
<a asp-controller="CatalogItems" asp-action="Index" class="nav-link">
|
<a asp-controller="CatalogItems" asp-action="Index" class="nav-link" data-nav="ops">
|
||||||
<i class="bi bi-book"></i>
|
<i class="bi bi-book"></i>
|
||||||
<span>Product Catalog</span>
|
<span>Product Catalog</span>
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
@if (hasInventory)
|
@if (hasInventory)
|
||||||
{
|
{
|
||||||
<a asp-controller="Inventory" asp-action="Index" class="nav-link">
|
<a asp-controller="Inventory" asp-action="Index" class="nav-link" data-nav="ops">
|
||||||
<i class="bi bi-box-seam"></i>
|
<i class="bi bi-box-seam"></i>
|
||||||
<span>Inventory</span>
|
<span>Inventory</span>
|
||||||
</a>
|
</a>
|
||||||
@@ -1109,11 +1179,11 @@
|
|||||||
}
|
}
|
||||||
@if (hasVendors)
|
@if (hasVendors)
|
||||||
{
|
{
|
||||||
<a asp-controller="Vendors" asp-action="Index" class="nav-link">
|
<a asp-controller="Vendors" asp-action="Index" class="nav-link" data-nav="ops">
|
||||||
<i class="bi bi-truck"></i>
|
<i class="bi bi-truck"></i>
|
||||||
<span>Vendors</span>
|
<span>Vendors</span>
|
||||||
</a>
|
</a>
|
||||||
<a asp-controller="PurchaseOrders" asp-action="Index" class="nav-link">
|
<a asp-controller="PurchaseOrders" asp-action="Index" class="nav-link" data-nav="ops">
|
||||||
<i class="bi bi-cart-check"></i>
|
<i class="bi bi-cart-check"></i>
|
||||||
<span>Purchase Orders</span>
|
<span>Purchase Orders</span>
|
||||||
</a>
|
</a>
|
||||||
@@ -1125,46 +1195,50 @@
|
|||||||
var _allowAccounting = Context.Items["AllowAccounting"] as bool? ?? false;
|
var _allowAccounting = Context.Items["AllowAccounting"] as bool? ?? false;
|
||||||
if (_allowAccounting)
|
if (_allowAccounting)
|
||||||
{
|
{
|
||||||
<div class="nav-section-title">Finance</div>
|
<div class="nav-section-title" data-nav="fin">Finance</div>
|
||||||
<a asp-controller="Bills" asp-action="Index" class="nav-link">
|
<a asp-controller="Bills" asp-action="Index" class="nav-link" data-nav="fin">
|
||||||
<i class="bi bi-receipt-cutoff"></i>
|
<i class="bi bi-receipt-cutoff"></i>
|
||||||
<span>Bills / Expenses</span>
|
<span>Bills / Expenses</span>
|
||||||
</a>
|
</a>
|
||||||
<a asp-controller="Accounts" asp-action="Index" class="nav-link">
|
<a asp-controller="Vendors" asp-action="Index" class="nav-link" data-nav="fin">
|
||||||
|
<i class="bi bi-truck"></i>
|
||||||
|
<span>Vendors</span>
|
||||||
|
</a>
|
||||||
|
<a asp-controller="Accounts" asp-action="Index" class="nav-link" data-nav="fin">
|
||||||
<i class="bi bi-journal-bookmark"></i>
|
<i class="bi bi-journal-bookmark"></i>
|
||||||
<span>Chart of Accounts</span>
|
<span>Chart of Accounts</span>
|
||||||
</a>
|
</a>
|
||||||
<a asp-controller="JournalEntries" asp-action="Index" class="nav-link">
|
<a asp-controller="JournalEntries" asp-action="Index" class="nav-link" data-nav="fin">
|
||||||
<i class="bi bi-journal-text"></i>
|
<i class="bi bi-journal-text"></i>
|
||||||
<span>Journal Entries</span>
|
<span>Journal Entries</span>
|
||||||
</a>
|
</a>
|
||||||
<a asp-controller="VendorCredits" asp-action="Index" class="nav-link">
|
<a asp-controller="VendorCredits" asp-action="Index" class="nav-link" data-nav="fin">
|
||||||
<i class="bi bi-arrow-return-left"></i>
|
<i class="bi bi-arrow-return-left"></i>
|
||||||
<span>Vendor Credits</span>
|
<span>Vendor Credits</span>
|
||||||
</a>
|
</a>
|
||||||
<a asp-controller="BankReconciliations" asp-action="Index" class="nav-link">
|
<a asp-controller="BankReconciliations" asp-action="Index" class="nav-link" data-nav="fin">
|
||||||
<i class="bi bi-bank2"></i>
|
<i class="bi bi-bank2"></i>
|
||||||
<span>Bank Reconciliation</span>
|
<span>Bank Reconciliation</span>
|
||||||
</a>
|
</a>
|
||||||
<a asp-controller="FixedAssets" asp-action="Index" class="nav-link">
|
<a asp-controller="FixedAssets" asp-action="Index" class="nav-link" data-nav="fin">
|
||||||
<i class="bi bi-building-gear"></i>
|
<i class="bi bi-building-gear"></i>
|
||||||
<span>Fixed Assets</span>
|
<span>Fixed Assets</span>
|
||||||
</a>
|
</a>
|
||||||
<a asp-controller="Budgets" asp-action="Index" class="nav-link">
|
<a asp-controller="Budgets" asp-action="Index" class="nav-link" data-nav="fin">
|
||||||
<i class="bi bi-pie-chart"></i>
|
<i class="bi bi-pie-chart"></i>
|
||||||
<span>Budgets</span>
|
<span>Budgets</span>
|
||||||
</a>
|
</a>
|
||||||
<a asp-controller="Accounts" asp-action="YearEndClose" class="nav-link">
|
<a asp-controller="Accounts" asp-action="YearEndClose" class="nav-link" data-nav="fin">
|
||||||
<i class="bi bi-calendar-check"></i>
|
<i class="bi bi-calendar-check"></i>
|
||||||
<span>Year-End Close</span>
|
<span>Year-End Close</span>
|
||||||
</a>
|
</a>
|
||||||
<a asp-controller="RecurringTemplates" asp-action="Index" class="nav-link">
|
<a asp-controller="RecurringTemplates" asp-action="Index" class="nav-link" data-nav="fin">
|
||||||
<i class="bi bi-arrow-repeat"></i>
|
<i class="bi bi-arrow-repeat"></i>
|
||||||
<span>Recurring Transactions</span>
|
<span>Recurring Transactions</span>
|
||||||
</a>
|
</a>
|
||||||
if (hasReports)
|
if (hasReports)
|
||||||
{
|
{
|
||||||
<a asp-controller="AccountingExport" asp-action="Index" class="nav-link">
|
<a asp-controller="AccountingExport" asp-action="Index" class="nav-link" data-nav="fin">
|
||||||
<i class="bi bi-box-arrow-up"></i>
|
<i class="bi bi-box-arrow-up"></i>
|
||||||
<span>Accounting Export</span>
|
<span>Accounting Export</span>
|
||||||
</a>
|
</a>
|
||||||
@@ -1173,33 +1247,33 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@* ── Shop Floor ───────────────────────────────────────────── *@
|
@* ── Shop Floor ───────────────────────────────────────────── *@
|
||||||
<div class="nav-section-title">Shop Floor</div>
|
<div class="nav-section-title" data-nav="ops">Shop Floor</div>
|
||||||
@if (hasEquipment)
|
@if (hasEquipment)
|
||||||
{
|
{
|
||||||
<a asp-controller="Equipment" asp-action="Index" class="nav-link">
|
<a asp-controller="Equipment" asp-action="Index" class="nav-link" data-nav="ops">
|
||||||
<i class="bi bi-gear"></i>
|
<i class="bi bi-gear"></i>
|
||||||
<span>Equipment</span>
|
<span>Equipment</span>
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
@if (hasMaintenance)
|
@if (hasMaintenance)
|
||||||
{
|
{
|
||||||
<a asp-controller="Maintenance" asp-action="Index" class="nav-link">
|
<a asp-controller="Maintenance" asp-action="Index" class="nav-link" data-nav="ops">
|
||||||
<i class="bi bi-tools"></i>
|
<i class="bi bi-tools"></i>
|
||||||
<span>Maintenance</span>
|
<span>Maintenance</span>
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
@if (hasInventory || _isAdminOrManager)
|
@if (hasInventory || _isAdminOrManager)
|
||||||
{
|
{
|
||||||
<a asp-controller="PowderInsights" asp-action="Index" class="nav-link">
|
<a asp-controller="PowderInsights" asp-action="Index" class="nav-link" data-nav="ops">
|
||||||
<i class="bi bi-graph-up"></i>
|
<i class="bi bi-graph-up"></i>
|
||||||
<span>Powder Insights</span>
|
<span>Powder Insights</span>
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
<a asp-controller="Jobs" asp-action="ShopDisplay" class="nav-link" target="_blank">
|
<a asp-controller="Jobs" asp-action="ShopDisplay" class="nav-link" data-nav="ops" target="_blank">
|
||||||
<i class="bi bi-display"></i>
|
<i class="bi bi-display"></i>
|
||||||
<span>Shop Display</span>
|
<span>Shop Display</span>
|
||||||
</a>
|
</a>
|
||||||
<a asp-controller="Jobs" asp-action="ShopMobile" class="nav-link">
|
<a asp-controller="Jobs" asp-action="ShopMobile" class="nav-link" data-nav="ops">
|
||||||
<i class="bi bi-phone"></i>
|
<i class="bi bi-phone"></i>
|
||||||
<span>Shop Mobile</span>
|
<span>Shop Mobile</span>
|
||||||
</a>
|
</a>
|
||||||
@@ -1207,17 +1281,17 @@
|
|||||||
@* ── Reports & Templates ──────────────────────────────────── *@
|
@* ── Reports & Templates ──────────────────────────────────── *@
|
||||||
@if (hasReports || hasJobs)
|
@if (hasReports || hasJobs)
|
||||||
{
|
{
|
||||||
<div class="nav-section-title">Reports & Templates</div>
|
<div class="nav-section-title" data-nav="both">Reports & Templates</div>
|
||||||
@if (hasReports)
|
@if (hasReports)
|
||||||
{
|
{
|
||||||
<a asp-controller="Reports" asp-action="Landing" class="nav-link">
|
<a asp-controller="Reports" asp-action="Landing" class="nav-link" data-nav="both">
|
||||||
<i class="bi bi-bar-chart-line"></i>
|
<i class="bi bi-bar-chart-line"></i>
|
||||||
<span>Reports</span>
|
<span>Reports</span>
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
@if (hasJobs)
|
@if (hasJobs)
|
||||||
{
|
{
|
||||||
<a asp-controller="JobTemplates" asp-action="Index" class="nav-link">
|
<a asp-controller="JobTemplates" asp-action="Index" class="nav-link" data-nav="ops">
|
||||||
<i class="bi bi-layout-text-window-reverse"></i>
|
<i class="bi bi-layout-text-window-reverse"></i>
|
||||||
<span>Job Templates</span>
|
<span>Job Templates</span>
|
||||||
</a>
|
</a>
|
||||||
@@ -1680,6 +1754,9 @@
|
|||||||
<!-- Bootstrap 5 JS Bundle -->
|
<!-- Bootstrap 5 JS Bundle -->
|
||||||
<script src="~/lib/bootstrap/js/bootstrap.bundle.min.js"></script>
|
<script src="~/lib/bootstrap/js/bootstrap.bundle.min.js"></script>
|
||||||
|
|
||||||
|
<!-- Nav mode switcher (Operations / Finance) -->
|
||||||
|
<script src="~/js/nav-mode.js" asp-append-version="true"></script>
|
||||||
|
|
||||||
<!-- Custom Scripts -->
|
<!-- Custom Scripts -->
|
||||||
<script>
|
<script>
|
||||||
// Add active class to current nav item
|
// Add active class to current nav item
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
(function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const STORAGE_KEY = 'pcl-nav-mode';
|
||||||
|
|
||||||
|
// Controllers that live exclusively in the Finance side.
|
||||||
|
// When navigating to one of these, the sidebar auto-switches to Finance.
|
||||||
|
const FINANCE_CONTROLLERS = new Set([
|
||||||
|
'bills', 'accounts', 'journalentries', 'vendorcredits',
|
||||||
|
'bankreconciliations', 'fixedassets', 'budgets', 'recurringtemplates',
|
||||||
|
'accountingexport', 'taxrates'
|
||||||
|
]);
|
||||||
|
|
||||||
|
/** Returns 'fin' if the current page belongs to Finance; null otherwise (use saved pref). */
|
||||||
|
function detectMode() {
|
||||||
|
const ctrl = (document.body.dataset.controller || '').toLowerCase();
|
||||||
|
return FINANCE_CONTROLLERS.has(ctrl) ? 'fin' : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function applyMode(mode) {
|
||||||
|
// CSS uses [data-nav-mode] on <html> to show/hide items — update it first.
|
||||||
|
document.documentElement.dataset.navMode = mode;
|
||||||
|
|
||||||
|
// Sync button states.
|
||||||
|
document.querySelectorAll('.nav-mode-btn').forEach(btn => {
|
||||||
|
const active = btn.dataset.mode === mode;
|
||||||
|
btn.classList.toggle('active', active);
|
||||||
|
btn.setAttribute('aria-selected', active ? 'true' : 'false');
|
||||||
|
});
|
||||||
|
|
||||||
|
localStorage.setItem(STORAGE_KEY, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
const forced = detectMode();
|
||||||
|
const saved = localStorage.getItem(STORAGE_KEY) || 'ops';
|
||||||
|
applyMode(forced || saved);
|
||||||
|
|
||||||
|
document.querySelectorAll('.nav-mode-btn').forEach(btn => {
|
||||||
|
btn.addEventListener('click', () => applyMode(btn.dataset.mode));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (document.readyState === 'loading') {
|
||||||
|
document.addEventListener('DOMContentLoaded', init);
|
||||||
|
} else {
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
})();
|
||||||
Reference in New Issue
Block a user