mirror of
https://github.com/myronblair/novacpx
synced 2026-06-30 17:50:41 -05:00
- nova.js: _initCollapsibleNav() exposed as window._initCollapsibleNav - user.js + reseller.js: call _initCollapsibleNav after renderNav() - deploy/novacpx-post-restore.sh: fixes config.ini, pools, vhost, dashboard Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LP9Q4kfCAYAjJnsbHBrViZ
This commit is contained in:
@@ -222,15 +222,15 @@ window.Nova = (() => {
|
||||
})();
|
||||
|
||||
// #48 Collapsible sidebar nav — shared across all panels
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
// Exported as window.Nova.initCollapsibleNav so panel JS can call it after dynamic nav render
|
||||
function _initCollapsibleNav() {
|
||||
const STORE = 'ncpx_nav_collapsed';
|
||||
const state = JSON.parse(localStorage.getItem(STORE) || '{}');
|
||||
|
||||
document.querySelectorAll('.sidebar-section').forEach(section => {
|
||||
const label = section.querySelector('.sidebar-section-label');
|
||||
if (!label) return;
|
||||
if (!label || label.querySelector('.nav-chevron')) return; // already initialized
|
||||
|
||||
// Add chevron icon
|
||||
const chevron = document.createElement('i');
|
||||
chevron.className = 'nav-chevron';
|
||||
chevron.textContent = '▼';
|
||||
@@ -238,22 +238,22 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
|
||||
const key = label.textContent.replace('▼','').trim();
|
||||
|
||||
// Restore saved state — default Overview open, others open
|
||||
if (state[key]) section.classList.add('collapsed');
|
||||
|
||||
// Keep active page's section always open
|
||||
const hasActive = section.querySelector('.sidebar-link.active');
|
||||
if (hasActive) section.classList.remove('collapsed');
|
||||
|
||||
label.addEventListener('click', () => {
|
||||
// Don't collapse if it contains the active link
|
||||
if (section.querySelector('.sidebar-link.active')) return;
|
||||
section.classList.toggle('collapsed');
|
||||
state[key] = section.classList.contains('collapsed');
|
||||
localStorage.setItem(STORE, JSON.stringify(state));
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
// Run on DOMContentLoaded for admin panel (static nav), expose globally for dynamic panels
|
||||
document.addEventListener('DOMContentLoaded', _initCollapsibleNav);
|
||||
window._initCollapsibleNav = _initCollapsibleNav;
|
||||
|
||||
// #26 Mobile sidebar toggle — shared across all panels
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
|
||||
@@ -364,6 +364,7 @@ function renderRNav() {
|
||||
resellerNav(link.dataset.page);
|
||||
});
|
||||
});
|
||||
if (typeof _initCollapsibleNav === 'function') _initCollapsibleNav();
|
||||
}
|
||||
|
||||
window.resellerNav = (page) => {
|
||||
|
||||
@@ -985,7 +985,7 @@ function renderNav() {
|
||||
</a>`).join('')}
|
||||
</div>`).join('');
|
||||
|
||||
nav.querySelectorAll('[data-page]').forEach(link => {
|
||||
nav.querySelectorAll("[data-page]").forEach(link => {
|
||||
link.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
if (window.innerWidth <= 768) {
|
||||
@@ -996,6 +996,7 @@ function renderNav() {
|
||||
userNav(link.dataset.page);
|
||||
});
|
||||
});
|
||||
if (typeof _initCollapsibleNav === 'function') _initCollapsibleNav();
|
||||
}
|
||||
|
||||
window.userNav = (page) => {
|
||||
|
||||
Reference in New Issue
Block a user