// static/admin/js/my-menu-config.js // Personal menu configuration for super admins // // TODO: BUG - Sidebar menu doesn't update immediately after changes. // User must navigate to another page to see the updated menu. // The issue is that Alpine.js doesn't properly track reactivity for the // visibleMenuItems Set in init-alpine.js. Attempted fixes with reloadSidebarMenu() // and window.location.reload() didn't work reliably. // Possible solutions: // 1. Convert visibleMenuItems from Set to plain object for better Alpine reactivity // 2. Use Alpine.store() for shared state between components // 3. Dispatch a custom event that the sidebar listens for // 4. Force re-render of sidebar component after changes const myMenuConfigLog = window.LogConfig?.loggers?.myMenuConfig || window.LogConfig?.createLogger?.('myMenuConfig') || console; function adminMyMenuConfig() { return { // Inherit base layout functionality from init-alpine.js ...data(), // Page-specific state currentPage: 'my-menu', loading: true, error: null, successMessage: null, saving: false, // Data menuConfig: null, // Computed grouped items get groupedItems() { if (!this.menuConfig?.items) return []; // Group items by section const sections = {}; for (const item of this.menuConfig.items) { const sectionId = item.section_id; if (!sections[sectionId]) { sections[sectionId] = { id: sectionId, label: item.section_label, isSuperAdminOnly: item.is_super_admin_only, items: [], visibleCount: 0 }; } sections[sectionId].items.push(item); if (item.is_visible) { sections[sectionId].visibleCount++; } } // Convert to array and maintain order return Object.values(sections); }, async init() { // Guard against multiple initialization if (window._adminMyMenuConfigInitialized) { myMenuConfigLog.warn('Already initialized, skipping'); return; } window._adminMyMenuConfigInitialized = true; myMenuConfigLog.info('=== MY MENU CONFIG PAGE INITIALIZING ==='); try { await this.loadMenuConfig(); myMenuConfigLog.info('=== MY MENU CONFIG PAGE INITIALIZED ==='); } catch (error) { myMenuConfigLog.error('Failed to initialize my menu config page:', error); this.error = 'Failed to load page data. Please refresh.'; } }, async refresh() { this.error = null; this.successMessage = null; await this.loadMenuConfig(); }, async loadMenuConfig() { this.loading = true; this.error = null; try { this.menuConfig = await apiClient.get('/admin/menu-config/user'); myMenuConfigLog.info('Loaded menu config:', { totalItems: this.menuConfig?.total_items, visibleItems: this.menuConfig?.visible_items }); } catch (error) { myMenuConfigLog.error('Failed to load menu config:', error); this.error = error.message || 'Failed to load menu configuration'; } finally { this.loading = false; } }, async toggleVisibility(item) { if (item.is_mandatory) { myMenuConfigLog.warn('Cannot toggle mandatory item:', item.id); return; } this.saving = true; this.error = null; this.successMessage = null; const newVisibility = !item.is_visible; try { await apiClient.put('/admin/menu-config/user', { menu_item_id: item.id, is_visible: newVisibility }); // Update local state item.is_visible = newVisibility; // Update counts if (newVisibility) { this.menuConfig.visible_items++; this.menuConfig.hidden_items--; } else { this.menuConfig.visible_items--; this.menuConfig.hidden_items++; } myMenuConfigLog.info('Toggled visibility:', item.id, newVisibility); // Reload the page to refresh sidebar window.location.reload(); } catch (error) { myMenuConfigLog.error('Failed to toggle visibility:', error); this.error = error.message || 'Failed to update menu visibility'; this.saving = false; } }, async showAll() { if (!confirm('This will show all menu items. Continue?')) { return; } this.saving = true; this.error = null; this.successMessage = null; try { await apiClient.post('/admin/menu-config/user/show-all'); myMenuConfigLog.info('Showed all menu items'); // Reload the page to refresh sidebar window.location.reload(); } catch (error) { myMenuConfigLog.error('Failed to show all menu items:', error); this.error = error.message || 'Failed to show all menu items'; this.saving = false; } }, async resetToDefaults() { if (!confirm('This will hide all menu items (except mandatory ones). You can then enable the ones you want. Continue?')) { return; } this.saving = true; this.error = null; this.successMessage = null; try { await apiClient.post('/admin/menu-config/user/reset'); myMenuConfigLog.info('Reset menu config to defaults'); // Reload the page to refresh sidebar window.location.reload(); } catch (error) { myMenuConfigLog.error('Failed to reset menu config:', error); this.error = error.message || 'Failed to reset menu configuration'; this.saving = false; } } }; }