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:
@@ -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