admin-panel: render sidebar icons, fix openKeys, persist collapse state

- VerticalNavMenu.vue now renders the icon: values that navMenuItems.ts
  already carried on 33 nodes but were never displayed, via the shared
  resolveIcon() map. Sub-menus and leaf items get a #icon slot each; ADV4's
  Menu shows icons only (labels hidden) once :inline-collapsed is true, which
  is now wired to the collapsed prop.
- Fixed openKeys: it previously started at [] and was only ever updated by
  user clicks, so a direct link or page refresh landed with the active
  item's parent submenu collapsed. It's now derived from the current route
  on load and on every navigation.
- Sidebar collapse state moves from a local ref in Main.vue to
  stores/layout.ts's existing (previously unused) sidebarCollapsed, persisted
  to localStorage so it survives a reload.

Verified: pnpm build passes.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
s.esmaeili
2026-09-14 15:20:47 +03:30
co-authored by Claude Sonnet 5
parent 02d92fc465
commit a6d8993d01
3 changed files with 72 additions and 5 deletions
+22 -1
View File
@@ -5,6 +5,20 @@
import { defineStore } from 'pinia';
import themeConfig, { type ThemeMode } from '../themeConfig';
const SIDEBAR_COLLAPSED_KEY = 'admin-panel:sidebarCollapsed';
/** Reads the persisted collapse state, falling back to themeConfig's default
* when localStorage is unavailable or has never been set. */
function readPersistedCollapsed(): boolean {
if (typeof window === 'undefined') return themeConfig.sidebarCollapsed;
try {
const raw = window.localStorage.getItem(SIDEBAR_COLLAPSED_KEY);
return raw === null ? themeConfig.sidebarCollapsed : raw === '1';
} catch {
return themeConfig.sidebarCollapsed;
}
}
export const useLayoutStore = defineStore('layout', {
state: () => ({
windowWidth: typeof window !== 'undefined' ? window.innerWidth : 0,
@@ -12,7 +26,7 @@ export const useLayoutStore = defineStore('layout', {
theme: themeConfig.theme as ThemeMode,
// legacy state.js: sidebar visibility for the vertical nav menu
isSidebarActive: true,
sidebarCollapsed: themeConfig.sidebarCollapsed,
sidebarCollapsed: readPersistedCollapsed(),
}),
getters: {
// legacy used breakpoints of 1200 (theme tour) and 992 (nav menu collapse)
@@ -32,6 +46,13 @@ export const useLayoutStore = defineStore('layout', {
},
setSidebarCollapsed(value: boolean) {
this.sidebarCollapsed = value;
if (typeof window === 'undefined') return;
try {
window.localStorage.setItem(SIDEBAR_COLLAPSED_KEY, value ? '1' : '0');
} catch {
// localStorage unavailable (private mode, disabled site data, ...) —
// collapse state just won't persist across reloads.
}
},
},
});