/* Sage Modern UI Shell Theme & Layout Controller Handles: theme switching (dark/light), sidebar collapse, localStorage persistence */ (function() { 'use strict'; var THEME_KEY = 'sage_ui_theme'; var SIDEBAR_KEY = 'sage_sidebar_collapsed'; // Initialize theme on page load function initTheme() { var saved = null; try { saved = localStorage.getItem(THEME_KEY); } catch(e) {} var theme = saved || 'dark'; document.documentElement.setAttribute('data-theme', theme); updateThemeIcon(theme); } // Toggle between dark and light function toggleTheme() { var current = document.documentElement.getAttribute('data-theme') || 'dark'; var next = current === 'dark' ? 'light' : 'dark'; document.documentElement.setAttribute('data-theme', next); try { localStorage.setItem(THEME_KEY, next); } catch(e) {} updateThemeIcon(next); } // Update the theme toggle icon based on current theme function updateThemeIcon(theme) { var btn = document.getElementById('theme_toggle_btn'); if (!btn) return; if (theme === 'light') { // Show moon icon (switch to dark) btn.innerHTML = ''; } else { // Show sun icon (switch to light) btn.innerHTML = ''; } } // Initialize sidebar state function initSidebar() { var collapsed = false; try { collapsed = localStorage.getItem(SIDEBAR_KEY) === 'true'; } catch(e) {} // Auto-collapse on mobile if (isMobile()) { collapsed = true; } var sidebar = document.getElementById('sage_sidebar'); if (sidebar && collapsed) { sidebar.classList.add('collapsed'); sidebar.style.width = '64px'; } } // Handle window resize - auto-collapse on mobile function handleResize() { var sidebar = document.getElementById('sage_sidebar'); if (!sidebar) return; if (isMobile() && !sidebar.classList.contains('collapsed')) { sidebar.classList.add('collapsed'); sidebar.style.width = '64px'; try { localStorage.setItem(SIDEBAR_KEY, 'true'); } catch(e) {} updateSidebarIcon(true); } } // Check if we're on mobile viewport function isMobile() { return window.innerWidth <= 768; } // Close sidebar when clicking outside on mobile function setupMobileOverlay() { document.addEventListener('click', function(e) { if (!isMobile()) return; var sidebar = document.getElementById('sage_sidebar'); var toggleBtn = document.getElementById('sidebar_toggle_btn'); if (!sidebar || sidebar.classList.contains('collapsed')) return; // If click is outside sidebar and toggle button, close sidebar if (!sidebar.contains(e.target) && (!toggleBtn || !toggleBtn.contains(e.target))) { sidebar.classList.add('collapsed'); sidebar.style.width = '64px'; try { localStorage.setItem(SIDEBAR_KEY, 'true'); } catch(ex) {} updateSidebarIcon(true); } }); } function updateSidebarIcon(isCollapsed) { var btn = document.getElementById('sidebar_toggle_btn'); if (!btn) return; if (isCollapsed) { btn.innerHTML = ''; } else { btn.innerHTML = ''; } } // Toggle sidebar collapse function toggleSidebar() { var sidebar = document.getElementById('sage_sidebar'); if (!sidebar) return; sidebar.classList.toggle('collapsed'); var isCollapsed = sidebar.classList.contains('collapsed'); try { localStorage.setItem(SIDEBAR_KEY, isCollapsed); } catch(e) {} updateSidebarIcon(isCollapsed); // Override inline width style (bricks sets inline style which beats CSS class) sidebar.style.width = isCollapsed ? '64px' : '240px'; // Toggle Menu widget collapse state if (typeof bricks !== 'undefined') { var menu = bricks.getWidgetById('global_nav_menu', bricks.app); if (menu && menu.toggle_collapse) { menu.toggle_collapse(); } } } // Initialize SPA Router function initRouter() { if (typeof bricks === 'undefined' || !bricks.Router) { console.log('[Shell] Router not available'); return; } bricks.Router.init({ targets: [ { id: 'sage_main_content', param: 'page' } ] }); } // Called by user_logined event — skip dashboard if Router has a saved route window.sageOnLogin = async function(dashboardUrl) { var target = bricks.getWidgetById('sage_main_content', bricks.app); if (!target) return; var hasRoute = false; if (bricks.Router && bricks.Router._enabled) { hasRoute = bricks.Router.current('sage_main_content') || new URLSearchParams(window.location.search).has('page'); } if (hasRoute) { console.log('[Shell] Router has route, skip dashboard load'); return; } // No route — load dashboard via Router if (dashboardUrl && bricks.Router && bricks.Router._enabled) { bricks.Router.navigate('sage_main_content', dashboardUrl); } else if (dashboardUrl) { var desc = { widgettype: 'urlwidget', options: { url: dashboardUrl } }; var w = await bricks.widgetBuild(desc, bricks.app); if (w) { target.clear_widgets(); target.add_widget(w); } } }; // Reload global menu after login/logout window.sageReloadMenu = async function() { if (typeof bricks === 'undefined') return; var sidebar = bricks.getWidgetById('sage_sidebar', bricks.app); if (!sidebar) { console.log('[Shell] sage_sidebar not found'); return; } // Check if sidebar is currently collapsed before clearing var isCollapsed = sidebar.el && sidebar.el.classList.contains('collapsed'); // Clear existing children sidebar.subwidgets.forEach(function(w) { w.destroy && w.destroy(); }); sidebar.subwidgets = []; sidebar.el.innerHTML = ''; // Rebuild menu urlwidget var menuUrl = bricks.app.baseUrl + '/global_menu.ui?_webbricks_=1'; var desc = { "widgettype": "urlwidget", "options": { "url": menuUrl } }; try { var w = await bricks.widgetBuild(desc, sidebar); if (w) { sidebar.addSubWidget(w); // Re-apply collapsed state and inline width to newly built menu if (isCollapsed) { sidebar.el.style.width = '64px'; var menu = bricks.getWidgetById('global_nav_menu', bricks.app); if (menu && menu.collapse) { menu.collapse(); } } console.log('[Shell] Menu reloaded'); } } catch(e) { console.log('[Shell] Menu reload error:', e); } }; // Run on DOM ready if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', function() { initTheme(); initSidebar(); initRouter(); setupMobileOverlay(); window.addEventListener('resize', handleResize); }); } else { initTheme(); initSidebar(); initRouter(); setupMobileOverlay(); window.addEventListener('resize', handleResize); } // Bricks widgets render asynchronously after DOMContentLoaded. // Retry updateThemeIcon until the button element exists. (function retryThemeIcon() { var btn = document.getElementById('theme_toggle_btn'); if (btn) { var theme = document.documentElement.getAttribute('data-theme') || 'dark'; updateThemeIcon(theme); } else { setTimeout(retryThemeIcon, 200); } })(); // Retry sidebar icon init until the button element exists (function retrySidebarIcon() { var sidebar = document.getElementById('sage_sidebar'); var btn = document.getElementById('sidebar_toggle_btn'); if (btn && sidebar) { var isCollapsed = sidebar.classList.contains('collapsed'); updateSidebarIcon(isCollapsed); // Sync inline width with collapsed state (bricks may have overridden it) sidebar.style.width = isCollapsed ? '64px' : '240px'; // Apply collapsed state to Menu if sidebar was already collapsed if (isCollapsed && typeof bricks !== 'undefined') { var menu = bricks.getWidgetById('global_nav_menu', bricks.app); if (menu && menu.collapse) { menu.collapse(); } else { setTimeout(retrySidebarIcon, 200); return; } } } else { setTimeout(retrySidebarIcon, 200); } })(); // Expose global functions for bricks bind access window.sageToggleTheme = toggleTheme; window.sageToggleSidebar = toggleSidebar; window.sageInitTheme = initTheme; window.sageInitSidebar = initSidebar; })();