feat: add admin menu configuration and sidebar improvements
- Add AdminMenuConfig model for per-platform menu customization - Add menu registry for centralized menu configuration - Add my-menu-config and platform-menu-config admin pages - Update sidebar with improved layout and Alpine.js interactions - Add FrontendType enum for admin/vendor menu separation - Document self-contained module patterns in session note Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -212,6 +212,69 @@ function data() {
|
||||
|
||||
get isSuperAdmin() {
|
||||
return this.adminProfile?.is_super_admin === true;
|
||||
},
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────
|
||||
// Dynamic menu visibility (loaded from API)
|
||||
// ─────────────────────────────────────────────────────────────────
|
||||
menuData: null,
|
||||
menuLoading: false,
|
||||
visibleMenuItems: new Set(),
|
||||
|
||||
async loadMenuConfig(forceReload = false) {
|
||||
// Don't reload if already loaded (unless forced)
|
||||
if (!forceReload && (this.menuData || this.menuLoading)) return;
|
||||
|
||||
// Skip if apiClient is not available (e.g., on login page)
|
||||
if (typeof apiClient === 'undefined') {
|
||||
console.debug('Menu config: apiClient not available');
|
||||
return;
|
||||
}
|
||||
|
||||
// Skip if not authenticated
|
||||
if (!localStorage.getItem('admin_token')) {
|
||||
console.debug('Menu config: no admin_token, skipping');
|
||||
return;
|
||||
}
|
||||
|
||||
this.menuLoading = true;
|
||||
try {
|
||||
this.menuData = await apiClient.get('/admin/menu-config/render/admin');
|
||||
// Build a set of visible menu item IDs for quick lookup
|
||||
this.visibleMenuItems = new Set();
|
||||
for (const section of (this.menuData?.sections || [])) {
|
||||
for (const item of (section.items || [])) {
|
||||
this.visibleMenuItems.add(item.id);
|
||||
}
|
||||
}
|
||||
console.debug('Menu config loaded:', this.visibleMenuItems.size, 'items');
|
||||
} catch (e) {
|
||||
// Silently fail - menu will show all items as fallback
|
||||
console.debug('Menu config not loaded, using defaults:', e?.message || e);
|
||||
} finally {
|
||||
this.menuLoading = false;
|
||||
}
|
||||
},
|
||||
|
||||
async reloadSidebarMenu() {
|
||||
// Force reload the sidebar menu config
|
||||
this.menuData = null;
|
||||
this.visibleMenuItems = new Set();
|
||||
await this.loadMenuConfig(true);
|
||||
},
|
||||
|
||||
isMenuItemVisible(menuItemId) {
|
||||
// If menu not loaded yet, show all items (fallback to hardcoded)
|
||||
if (!this.menuData) return true;
|
||||
return this.visibleMenuItems.has(menuItemId);
|
||||
},
|
||||
|
||||
isSectionVisible(sectionId) {
|
||||
// If menu not loaded yet, show all sections
|
||||
if (!this.menuData) return true;
|
||||
// Check if any item in this section is visible
|
||||
const section = this.menuData?.sections?.find(s => s.id === sectionId);
|
||||
return section && section.items && section.items.length > 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user