web-mojo 2.2.6 → 2.2.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin.cjs.js +1 -1
- package/dist/admin.cjs.js.map +1 -1
- package/dist/admin.es.js +26 -7
- package/dist/admin.es.js.map +1 -1
- package/dist/auth.cjs.js +1 -1
- package/dist/auth.es.js +1 -1
- package/dist/charts.cjs.js +1 -1
- package/dist/charts.es.js +3 -3
- package/dist/chunks/{ChatView-BcPvM8jM.js → ChatView-2mFEGsXL.js} +283 -97
- package/dist/chunks/ChatView-2mFEGsXL.js.map +1 -0
- package/dist/chunks/ChatView-DfKH7ep8.js +2 -0
- package/dist/chunks/ChatView-DfKH7ep8.js.map +1 -0
- package/dist/chunks/{Dialog-C-Xl4SYW.js → Dialog-BBZUgBbz.js} +2 -2
- package/dist/chunks/{Dialog-C-Xl4SYW.js.map → Dialog-BBZUgBbz.js.map} +1 -1
- package/dist/chunks/{Dialog-D_TcKXUc.js → Dialog-DrCs-ex1.js} +3 -3
- package/dist/chunks/{Dialog-D_TcKXUc.js.map → Dialog-DrCs-ex1.js.map} +1 -1
- package/dist/chunks/FormView-CNkSOc2U.js +3 -0
- package/dist/chunks/FormView-CNkSOc2U.js.map +1 -0
- package/dist/chunks/{FormView-UtTgxKhq.js → FormView-CwYt4vH3.js} +406 -3
- package/dist/chunks/FormView-CwYt4vH3.js.map +1 -0
- package/dist/chunks/{ListView-C9OoIPfC.js → ListView-DoF-Sr56.js} +4 -1
- package/dist/chunks/ListView-DoF-Sr56.js.map +1 -0
- package/dist/chunks/ListView-OWwlcGGg.js +2 -0
- package/dist/chunks/ListView-OWwlcGGg.js.map +1 -0
- package/dist/chunks/{MetricsMiniChartWidget-DDDtbxVu.js → MetricsMiniChartWidget-B3PHrgkn.js} +2 -2
- package/dist/chunks/{MetricsMiniChartWidget-DDDtbxVu.js.map → MetricsMiniChartWidget-B3PHrgkn.js.map} +1 -1
- package/dist/chunks/{MetricsMiniChartWidget-CJZo6Mzi.js → MetricsMiniChartWidget-DdZ3zNve.js} +2 -2
- package/dist/chunks/{MetricsMiniChartWidget-CJZo6Mzi.js.map → MetricsMiniChartWidget-DdZ3zNve.js.map} +1 -1
- package/dist/chunks/{PDFViewer-BGvS4SV2.js → PDFViewer-CkKC_E0G.js} +2 -2
- package/dist/chunks/{PDFViewer-BGvS4SV2.js.map → PDFViewer-CkKC_E0G.js.map} +1 -1
- package/dist/chunks/{PDFViewer-CBMSMWI8.js → PDFViewer-DaiTPsQH.js} +2 -2
- package/dist/chunks/{PDFViewer-CBMSMWI8.js.map → PDFViewer-DaiTPsQH.js.map} +1 -1
- package/dist/chunks/{TokenManager-sw1FUivr.js → TokenManager-D9z35vwT.js} +2 -2
- package/dist/chunks/{TokenManager-sw1FUivr.js.map → TokenManager-D9z35vwT.js.map} +1 -1
- package/dist/chunks/{TokenManager-BCgqjJTM.js → TokenManager-XwKaWaKd.js} +2 -2
- package/dist/chunks/{TokenManager-BCgqjJTM.js.map → TokenManager-XwKaWaKd.js.map} +1 -1
- package/dist/chunks/{version-Cg90gIP7.js → version-BQcvJscT.js} +4 -4
- package/dist/chunks/{version-Cg90gIP7.js.map → version-BQcvJscT.js.map} +1 -1
- package/dist/chunks/{version-e45B_7me.js → version-DhSPKHUm.js} +2 -2
- package/dist/chunks/{version-e45B_7me.js.map → version-DhSPKHUm.js.map} +1 -1
- package/dist/core.css +118 -0
- package/dist/css/web-mojo.css +1 -1
- package/dist/docit.cjs.js +1 -1
- package/dist/docit.es.js +3 -3
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +96 -92
- package/dist/index.es.js.map +1 -1
- package/dist/lightbox.cjs.js +1 -1
- package/dist/lightbox.es.js +4 -4
- package/dist/timeline.cjs.js +1 -1
- package/dist/timeline.es.js +1 -1
- package/package.json +1 -1
- package/dist/chunks/ChatView-BLe7SAMj.js +0 -2
- package/dist/chunks/ChatView-BLe7SAMj.js.map +0 -1
- package/dist/chunks/ChatView-BcPvM8jM.js.map +0 -1
- package/dist/chunks/FormView-DCtLjTmF.js +0 -3
- package/dist/chunks/FormView-DCtLjTmF.js.map +0 -1
- package/dist/chunks/FormView-UtTgxKhq.js.map +0 -1
- package/dist/chunks/ListView-9b-jQTQZ.js +0 -2
- package/dist/chunks/ListView-9b-jQTQZ.js.map +0 -1
- package/dist/chunks/ListView-C9OoIPfC.js.map +0 -1
package/dist/index.es.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.es.js","sources":["../src/core/utils/ConsoleSilencer.js","../src/core/views/navigation/GroupSearchView.js","../src/core/views/navigation/Sidebar.js","../src/core/views/navigation/PageHeader.js","../src/core/pages/DeniedPage.js","../src/core/pages/NotFoundPage.js","../src/core/PortalApp.js","../src/core/utils/MustacheFormatter.js","../src/index.js"],"sourcesContent":["/**\n * ConsoleSilencer\n * \n * Purpose:\n * - Reduce console noise by filtering out non-critical logs in production.\n * - Keep critical logs (warn, error) by default in production.\n * - Allow runtime override via API, URL params, or localStorage without rebuilding.\n *\n * Usage:\n * import ConsoleSilencer from '@core/utils/ConsoleSilencer.js';\n * ConsoleSilencer.install(); // defaults to 'warn' in production, 'debug' in dev\n *\n * // Optional: set level at install-time\n * ConsoleSilencer.install({ level: 'error' });\n *\n * // Change level at runtime (optionally persist to localStorage)\n * ConsoleSilencer.setLevel('debug', { persist: true });\n *\n * // Temporarily change level around a block\n * ConsoleSilencer.withTemporaryLevel('debug', () => {\n * // noisy diagnostics here\n * });\n *\n * Runtime overrides (no code changes needed):\n * - URL: ?logLevel=debug|info|warn|error|silent\n * also accepts mojoLog and loglevel as param names\n * - localStorage: localStorage.setItem('MOJO_LOG_LEVEL', 'debug')\n *\n * Notes:\n * - This module is side-effect free until install() is called.\n * - Idempotent: calling install() multiple times won't double-wrap console.\n */\n\nconst LEVELS = Object.freeze({\n silent: 0,\n error: 1,\n warn: 2,\n info: 3,\n log: 3, // alias to info\n debug: 4,\n trace: 5,\n all: 5, // alias\n});\n\n// Resolve environment in a bundler/browser-safe way\n// __DEV__ can be injected by bundlers (e.g., Vite define)\nconst isDev = (() => {\n // Vite/ESM: import.meta.env.DEV if available\n try {\n /* eslint-disable-next-line no-undef */\n if (typeof import.meta !== 'undefined' && import.meta && import.meta.env && typeof import.meta.env.DEV !== 'undefined') {\n return !!import.meta.env.DEV;\n }\n } catch {\n // ignore\n }\n\n // Prefer global __DEV__ if present (e.g., defined via bundler define)\n if (typeof globalThis !== 'undefined' && typeof globalThis.__DEV__ !== 'undefined') {\n try {\n return !!globalThis.__DEV__;\n } catch {\n // fall through if __DEV__ is not directly evaluable\n }\n }\n\n // Fallback detection (best effort)\n const hasProcess = typeof process !== 'undefined' && process && typeof process.env === 'object';\n if (hasProcess && typeof process.env.NODE_ENV === 'string') {\n return process.env.NODE_ENV !== 'production';\n }\n // Default conservative behavior: assume production if unknown\n return false;\n})();\n\nconst isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined';\nconst GLOBAL = typeof globalThis !== 'undefined' ? globalThis : (typeof window !== 'undefined' ? window : global);\n\n// Capture the original console just once\nconst ORIGINAL_CONSOLE = GLOBAL.console || {};\nconst ORIGINALS = {};\nlet INSTALLED = false;\nlet CURRENT_LEVEL = null;\n\n// Default levels\nconst DEFAULT_DEV_LEVEL = 'debug';\nconst DEFAULT_PROD_LEVEL = 'warn'; // keep warn + error by default\n\n// Helper: normalize/parse level\nfunction parseLevel(level) {\n if (typeof level === 'number') {\n // Clamp to bounds\n const min = LEVELS.silent;\n const max = LEVELS.trace;\n return Math.min(Math.max(level, min), max);\n }\n if (typeof level === 'string') {\n const key = level.toLowerCase();\n if (Object.prototype.hasOwnProperty.call(LEVELS, key)) {\n return LEVELS[key];\n }\n }\n return null;\n}\n\n// Helper: detect override via URLSearchParams\nfunction getUrlLogLevel() {\n if (!isBrowser || typeof location === 'undefined' || !location.search) return null;\n try {\n const params = new URLSearchParams(location.search);\n const keys = ['logLevel', 'loglevel', 'mojoLog'];\n for (const k of keys) {\n const v = params.get(k);\n if (v != null) {\n const parsed = parseLevel(v);\n if (parsed !== null) return parsed;\n }\n }\n } catch {\n // ignore\n }\n return null;\n}\n\n// Helper: detect override via localStorage\nfunction getStoredLogLevel() {\n if (!isBrowser || !('localStorage' in GLOBAL)) return null;\n try {\n const v = GLOBAL.localStorage.getItem('MOJO_LOG_LEVEL');\n if (v != null) {\n const parsed = parseLevel(v);\n if (parsed !== null) return parsed;\n }\n } catch {\n // ignore storage errors\n }\n return null;\n}\n\nfunction storeLogLevel(levelNumberOrName) {\n if (!isBrowser || !('localStorage' in GLOBAL)) return;\n try {\n const key = typeof levelNumberOrName === 'string'\n ? levelNumberOrName\n : levelNumberOrName === null\n ? null\n : Object.entries(LEVELS).find(([, num]) => num === levelNumberOrName)?.[0] ?? null;\n if (key) {\n GLOBAL.localStorage.setItem('MOJO_LOG_LEVEL', key);\n } else {\n GLOBAL.localStorage.removeItem('MOJO_LOG_LEVEL');\n }\n } catch {\n // ignore storage errors\n }\n}\n\n// Build a wrapped method that checks the current level before calling through\nfunction makeWrapper(methodName, methodLevel) {\n const original = ORIGINALS[methodName] || ORIGINAL_CONSOLE[methodName] || (() => {});\n return function wrappedConsoleMethod(...args) {\n // If the method is allowed at the current level, call through\n if (CURRENT_LEVEL >= methodLevel) {\n return original.apply(ORIGINAL_CONSOLE, args);\n }\n // Otherwise, noop\n return undefined;\n };\n}\n\n// Special wrapper for assert: only logs when assertion fails\nfunction makeAssertWrapper() {\n const original = ORIGINALS.assert || ORIGINAL_CONSOLE.assert || (() => {});\n return function wrappedAssert(condition, ...args) {\n // Only logs when condition is falsy; treat failed assert like error-level\n if (!condition) {\n if (CURRENT_LEVEL >= LEVELS.error) {\n return original.apply(ORIGINAL_CONSOLE, [condition, ...args]);\n }\n return undefined;\n }\n // When assertion passes, no-op\n return undefined;\n };\n}\n\nfunction determineInitialLevel(explicitLevel) {\n // 1) Explicit install option\n const explicit = parseLevel(explicitLevel);\n if (explicit !== null) return explicit;\n\n // 2) URL override\n const urlLevel = getUrlLogLevel();\n if (urlLevel !== null) return urlLevel;\n\n // 3) localStorage override\n const storedLevel = getStoredLogLevel();\n if (storedLevel !== null) return storedLevel;\n\n // 4) Environment default\n return parseLevel(isDev ? DEFAULT_DEV_LEVEL : DEFAULT_PROD_LEVEL);\n}\n\n// Construct a patched console that respects CURRENT_LEVEL\nfunction buildPatchedConsole() {\n const patched = { ...ORIGINAL_CONSOLE };\n\n // Save originals once\n const methodLevels = {\n // Critical\n error: LEVELS.error,\n warn: LEVELS.warn,\n\n // Informational\n info: LEVELS.info,\n log: LEVELS.info,\n dir: LEVELS.info,\n table: LEVELS.info,\n\n // Verbose / Debug\n debug: LEVELS.debug,\n group: LEVELS.debug,\n groupCollapsed: LEVELS.debug,\n groupEnd: LEVELS.debug,\n time: LEVELS.debug,\n timeEnd: LEVELS.debug,\n timeLog: LEVELS.debug,\n trace: LEVELS.trace,\n };\n\n // Capture originals and build wrappers\n for (const name of Object.keys(methodLevels)) {\n ORIGINALS[name] = ORIGINAL_CONSOLE[name] || (() => {});\n patched[name] = makeWrapper(name, methodLevels[name]);\n }\n\n // Special-case assert\n ORIGINALS.assert = ORIGINAL_CONSOLE.assert || (() => {});\n patched.assert = makeAssertWrapper();\n\n // Preserve any other console methods as-is (clear, profile, count, etc.)\n return patched;\n}\n\nconst ConsoleSilencer = {\n // Install the silencer (idempotent)\n install(options = {}) {\n if (INSTALLED) {\n // Already installed; update level if provided\n if (options && typeof options.level !== 'undefined') {\n this.setLevel(options.level, { persist: !!options.persist });\n }\n return this;\n }\n\n if (!GLOBAL || !ORIGINAL_CONSOLE) {\n // No console available; nothing to do\n INSTALLED = true; // Prevent re-entry\n return this;\n }\n\n CURRENT_LEVEL = determineInitialLevel(options.level);\n\n const patched = buildPatchedConsole();\n // Replace the global console\n GLOBAL.console = patched;\n\n INSTALLED = true;\n\n // Expose for quick manual access if desired\n GLOBAL.MOJOConsoleSilencer = this;\n\n return this;\n },\n\n // Uninstall and restore the original console\n uninstall() {\n if (!INSTALLED) return this;\n\n try {\n GLOBAL.console = ORIGINAL_CONSOLE;\n } catch {\n // ignore\n }\n INSTALLED = false;\n return this;\n },\n\n // Set current level at runtime; accepts string or number\n // levels: 'silent' | 'error' | 'warn' | 'info' | 'debug' | 'trace'\n setLevel(level, { persist = false } = {}) {\n const parsed = parseLevel(level);\n if (parsed === null) return this; // ignore invalid level\n CURRENT_LEVEL = parsed;\n if (persist) {\n storeLogLevel(level);\n }\n return this;\n },\n\n // Get the current numeric level\n getLevel() {\n return CURRENT_LEVEL;\n },\n\n // Get the current level name (best-effort)\n getLevelName() {\n const entry = Object.entries(LEVELS).find(([, num]) => num === CURRENT_LEVEL);\n return entry ? entry[0] : null;\n },\n\n // Convenience helpers\n criticalOnly({ persist = false } = {}) {\n return this.setLevel('warn', { persist });\n },\n\n errorsOnly({ persist = false } = {}) {\n return this.setLevel('error', { persist });\n },\n\n silent({ persist = false } = {}) {\n return this.setLevel('silent', { persist });\n },\n\n verbose({ persist = false } = {}) {\n return this.setLevel(isDev ? 'debug' : 'info', { persist });\n },\n\n allowAll({ persist = false } = {}) {\n return this.setLevel('trace', { persist });\n },\n\n // Run a block with a temporary level, then restore\n withTemporaryLevel(level, fn) {\n const prev = CURRENT_LEVEL;\n const parsed = parseLevel(level);\n if (parsed === null || typeof fn !== 'function') return fn?.();\n CURRENT_LEVEL = parsed;\n try {\n return fn();\n } finally {\n CURRENT_LEVEL = prev;\n }\n },\n\n // Expose levels map for consumers\n LEVELS,\n};\n\n// Optional: convenience named export alias\nexport default ConsoleSilencer;\nexport const installConsoleSilencer = (options) => ConsoleSilencer.install(options);","/**\n * GroupSearchView - Hierarchical tree-view search component\n * Extends SimpleSearchView to support parent/child relationships\n * Displays items in a tree structure based on parent property\n */\n\nimport SimpleSearchView from './SimpleSearchView.js';\n\nclass GroupSearchView extends SimpleSearchView {\n constructor(options = {}) {\n super({\n ...options,\n className: `group-search-view ${options.className || ''}`.trim()\n });\n\n // Tree-specific configuration\n this.showKind = options.showKind !== undefined ? options.showKind : true;\n this.parentField = options.parentField || 'parent';\n this.kindField = options.kindField || 'kind';\n this.treeData = []; // Processed hierarchical data\n this.flattenedItems = []; // Flattened tree for display\n \n // Visual customization\n this.showLines = options.showLines !== undefined ? options.showLines : true;\n }\n\n /**\n * Build tree hierarchy from flat list\n */\n buildTreeHierarchy(items) {\n if (!items || items.length === 0) {\n return [];\n }\n\n // Create a map of items by ID for quick lookup\n const itemsById = new Map();\n \n // First pass: add all items and extract parent objects\n items.forEach(item => {\n if (!itemsById.has(item.id)) {\n itemsById.set(item.id, {\n ...item,\n children: [],\n level: 0,\n hasChildren: false\n });\n }\n \n // If this item has a parent object, add the parent too\n const parentObj = item[this.parentField];\n if (parentObj && parentObj.id && !itemsById.has(parentObj.id)) {\n itemsById.set(parentObj.id, {\n ...parentObj,\n children: [],\n level: 0,\n hasChildren: false\n });\n }\n });\n\n const rootItems = [];\n\n // Build parent-child relationships\n itemsById.forEach((treeItem, itemId) => {\n const originalItem = items.find(i => i.id === itemId) || treeItem;\n const parentId = originalItem[this.parentField]?.id;\n\n if (parentId && itemsById.has(parentId)) {\n const parent = itemsById.get(parentId);\n parent.children.push(treeItem);\n parent.hasChildren = true;\n } else {\n rootItems.push(treeItem);\n }\n });\n\n // Calculate levels recursively\n const calculateLevels = (nodes, level = 0) => {\n nodes.forEach(node => {\n node.level = level;\n if (node.children.length > 0) {\n node.children.sort((a, b) => (a.name || '').localeCompare(b.name || ''));\n calculateLevels(node.children, level + 1);\n }\n });\n };\n\n rootItems.sort((a, b) => (a.name || '').localeCompare(b.name || ''));\n calculateLevels(rootItems);\n\n return rootItems;\n }\n\n /**\n * Flatten tree structure for rendering\n * Tracks ancestor \"last child\" flags for proper line rendering\n */\n flattenTree(nodes, result = [], ancestorLastFlags = []) {\n nodes.forEach((node, index) => {\n node._isLastChild = index === nodes.length - 1;\n node._ancestorLastFlags = [...ancestorLastFlags];\n \n // Check if this node is the last descendant in its branch\n // (all ancestors are last children AND this node is last child with no children)\n const allAncestorsLast = ancestorLastFlags.every(flag => flag);\n node._isLastDescendant = allAncestorsLast && node._isLastChild && \n (!node.children || node.children.length === 0);\n \n result.push(node);\n \n if (node.children && node.children.length > 0) {\n const newFlags = [...ancestorLastFlags, node._isLastChild];\n this.flattenTree(node.children, result, newFlags);\n }\n });\n \n return result;\n }\n\n /**\n * Second pass: compute which vertical lines should continue for each item\n * \n * Vertical line at segment s shows if there are more siblings coming at level s+1\n * We need to look ahead until we find an item at level s+1 or shallower\n */\n computeVerticalLines(flatList) {\n for (let i = 0; i < flatList.length; i++) {\n const item = flatList[i];\n item._continueVertical = [];\n \n for (let s = 0; s < item.level; s++) {\n // Look ahead to find next item at level s+1 or shallower\n let foundSibling = false;\n for (let j = i + 1; j < flatList.length; j++) {\n const futureItem = flatList[j];\n if (futureItem.level === s + 1) {\n // Found a sibling at this level - vertical should continue\n foundSibling = true;\n break;\n } else if (futureItem.level <= s) {\n // Went back to ancestor level or shallower - no more siblings\n break;\n }\n // Keep searching if futureItem.level > s+1 (still in deeper subtree)\n }\n item._continueVertical[s] = foundSibling;\n }\n }\n }\n\n /**\n * Update filtered items with tree structure\n */\n updateFilteredItems() {\n if (!this.collection) {\n this.filteredItems = [];\n this.treeData = [];\n this.flattenedItems = [];\n return;\n }\n\n // Server-side filtering is handled in performSearch() (from parent class)\n const items = this.collection.toJSON();\n this.treeData = this.buildTreeHierarchy(items);\n this.flattenedItems = this.flattenTree(this.treeData);\n \n // Second pass: compute vertical line continuation\n this.computeVerticalLines(this.flattenedItems);\n \n // Set filteredItems to flattened tree for parent class compatibility\n this.filteredItems = this.flattenedItems;\n\n this.updateResultsView();\n }\n\n /**\n * Get tree-specific item template\n */\n getDefaultItemTemplate() {\n return `\n <div class=\"tree-item-content\">\n <div class=\"tree-item-name\">{{name}}</div>\n {{#showKind}}\n <div class=\"tree-item-kind\">{{kind}}</div>\n {{/showKind}}\n </div>\n `;\n }\n\n /**\n * Process item template with tree structure\n */\n processItemTemplate(item) {\n // Process the base template\n let content = this.itemTemplate;\n content = content.replace(/\\{\\{(\\w+)\\}\\}/g, (match, prop) => {\n if (prop === 'showKind') {\n return this.showKind ? 'true' : '';\n }\n return this.getNestedValue(item, prop) || '';\n });\n\n // Handle conditional sections for kind\n if (this.showKind) {\n content = content.replace(/\\{\\{#showKind\\}\\}(.*?)\\{\\{\\/showKind\\}\\}/gs, '$1');\n } else {\n content = content.replace(/\\{\\{#showKind\\}\\}.*?\\{\\{\\/showKind\\}\\}/gs, '');\n }\n\n // Build tree line segments\n // For an item at level N, we need N segments (one for each ancestor level)\n let lineSegments = '';\n if (this.showLines && item.level > 0) {\n for (let i = 0; i < item.level; i++) {\n const isLastSegment = (i === item.level - 1);\n \n if (isLastSegment) {\n // This segment connects directly to this item\n // Use _isLastChild to determine if this is └ or ├\n const segClass = item._isLastChild ? 'tree-seg tree-seg-last' : 'tree-seg tree-seg-mid';\n lineSegments += `<span class=\"${segClass}\"></span>`;\n } else {\n // Ancestor segment - vertical line continues if next item is deeper than this level\n const continueVertical = item._continueVertical && item._continueVertical[i];\n if (continueVertical) {\n lineSegments += `<span class=\"tree-seg tree-seg-vert\"></span>`;\n } else {\n lineSegments += `<span class=\"tree-seg\"></span>`;\n }\n }\n }\n }\n\n // Classes for the wrapper\n const hasChildren = item.hasChildren ? ' has-children' : '';\n const isLastChild = item._isLastChild ? ' is-last-child' : '';\n\n // Wrap in tree structure\n return `\n <div class=\"tree-item-wrapper${hasChildren}${isLastChild}\" data-tree-level=\"${item.level}\">\n <div class=\"tree-lines\">\n ${lineSegments}\n </div>\n <div class=\"tree-item-body flex-grow-1\">\n ${content}\n </div>\n </div>\n `;\n }\n\n /**\n * Get all root items\n */\n getRootItems() {\n return this.treeData;\n }\n\n /**\n * Get children of a specific node\n */\n getNodeChildren(nodeId) {\n const findNode = (nodes, targetId) => {\n for (const node of nodes) {\n if (node.id === targetId) {\n return node.children;\n }\n if (node.children.length > 0) {\n const found = findNode(node.children, targetId);\n if (found) return found;\n }\n }\n return null;\n };\n\n return findNode(this.treeData, nodeId) || [];\n }\n}\n\nexport default GroupSearchView;\n","/**\n * Sidebar - Simple sidebar navigation component for MOJO framework\n * Provides easy menu switching and dynamic configuration\n */\n\nimport View from '@core/View.js';\nimport GroupSearchView from './GroupSearchView.js';\nimport {GroupList, Group} from '@core/models/Group.js';\nimport Dialog from '@core/views/feedback/Dialog.js';\n\n\nclass Sidebar extends View {\n constructor(options = {}) {\n super({\n tagName: 'nav',\n className: 'sidebar',\n id: 'sidebar',\n ...options\n });\n\n this.menus = new Map();\n this.activeMenuName = null;\n this.currentRoute = null;\n this.showToggle = options.showToggle; // Default to true\n this.isCollapsed = false;\n this.sidebarTheme = options.theme || 'sidebar-light';\n this.customView = null;\n if (this.options.groupHeader) this.groupHeader = this.options.groupHeader;\n\n // Group selector configuration\n // 'inline' (default) - replaces sidebar view\n // 'dialog' - opens in a modal dialog like TopNav\n this.groupSelectorMode = options.groupSelectorMode || 'inline';\n this.groupSelectorDialog = null;\n // Apply sidebar theme\n if (this.sidebarTheme) {\n this.addClass(this.sidebarTheme);\n }\n\n // Initialize menus\n this.initializeMenus(options);\n\n // Setup route change listeners like TopNav\n this.setupRouteListeners();\n\n // Auto-collapse on mobile if specified\n if (options.autoCollapseMobile !== false) {\n this.setupResponsiveBehavior();\n }\n }\n\n groupHeader = `\n {{#group.parent}}\n <div class=\"sidebar-parent-bar\" data-action=\"select-group-parent\">\n <div class=\"parent-info\">\n <span class=\"parent-label\">{{group.parent.kind}}:</span>\n <span class=\"parent-name collapsed-hidden\">{{group.parent.name}}</span>\n </div>\n <i class=\"bi bi-chevron-down parent-expand collapsed-hidden\"></i>\n </div>\n {{/group.parent}}\n <div class=\"sidebar-selected-group-row\" data-action=\"show-group-search\">\n <div class=\"selected-group-info\">\n <div class='selected-group-name collapsed-hidden'>{{group.name}}</div>\n <div class='selected-group-meta collapsed-hidden'>\n <span class=\"selected-group-kind\">{{group.kind}}</span>\n </div>\n </div>\n <i class=\"bi bi-chevron-down selected-group-chevron collapsed-hidden\"></i>\n </div>\n `;\n\n /**\n * Initialize sidebar and auto-switch to correct menu based on current route\n */\n async onInit() {\n await super.onInit();\n\n // Get current route from router\n const app = this.getApp();\n const router = app?.router;\n\n if (router) {\n const currentPath = router.getCurrentPath();\n if (currentPath) {\n this.autoSwitchToMenuForRoute(currentPath);\n }\n }\n\n // Initialize tooltips for nav items\n this.initializeTooltips();\n\n this.searchView = new GroupSearchView({\n noAppend: true,\n showExitButton: true,\n headerText: \"Select Group\",\n containerId: \"sidebar-search-container\",\n Collection: GroupList,\n itemTemplate: `\n <div class=\"p-3 border-bottom\">\n <div class=\"fw-semibold text-dark\">{{name}}</div>\n <small class=\"text-muted\">#{{id}} {{kind}}</small>\n </div>\n `\n });\n this.addChild(this.searchView);\n this.searchView.on(\"item:selected\", (evt) => {\n console.log(evt);\n this.getApp().setActiveGroup(evt.model);\n });\n this.searchView.on(\"exit\", (item) => {\n console.log(item);\n this.hideGroupSearch();\n });\n }\n\n showGroupSearch() {\n if (this.groupSelectorMode === 'dialog') {\n this.showGroupSearchDialog();\n } else {\n // Inline mode (default)\n this.setClass('sidebar');\n this.showSearch = true;\n this.render();\n }\n }\n\n hideGroupSearch() {\n if (this.groupSelectorMode === 'dialog') {\n if (this.groupSelectorDialog) {\n this.groupSelectorDialog.hide();\n }\n } else {\n // Inline mode\n this.setClass('sidebar');\n this.showSearch = false;\n this.render();\n }\n }\n\n onActionShowGroupSearch() {\n this.showGroupSearch();\n }\n\n async onActionSelectGroupParent() {\n // select-group-parent\n const group = this.getApp().activeGroup;\n const result = await Dialog.confirm(`Are you sure you want to navigate to the '${group.get(\"parent.name\")}'?`);\n if (result) {\n this.getApp().showLoading();\n let parent = new Group({id: group.get(\"parent.id\")});\n await parent.fetch();\n this.getApp().setActiveGroup(parent);\n this.getApp().hideLoading();\n }\n }\n\n /**\n * Show group selector in a dialog (like TopNav)\n */\n async showGroupSearchDialog() {\n // Create or reuse collection instance (like GroupSelectorButton does)\n const collection = new GroupList();\n\n // Create GroupSearchView instance matching GroupSelectorButton pattern\n const searchView = new GroupSearchView({\n Collection: GroupList,\n collection: collection, // Pass the collection instance\n searchFields: ['name'],\n headerText: null,\n searchPlaceholder: \"Search groups...\",\n headerIcon: null,\n maxHeight: Math.min(600, window.innerHeight - 200),\n showExitButton: false,\n showKind: true, // Show kind badges (default: true)\n parentField: 'parent', // Field containing parent object\n kindField: 'kind', // Field containing kind/type\n autoExpandRoot: true, // Auto-expand root items (default: true)\n autoExpandAll: false, // Auto-expand all nodes (default: false)\n indentSize: 20, // Pixels per level (default: 20)\n showLines: true,\n });\n\n // Create dialog\n this.groupSelectorDialog = new Dialog({\n body: searchView,\n size: 'md',\n header: null,\n noBodyPadding: true,\n scrollable: false,\n buttons: [],\n closeButton: true\n });\n\n // Listen for item selection\n searchView.on('item:selected', (evt) => {\n console.log(evt);\n this.getApp().setActiveGroup(evt.model);\n if (this.groupSelectorDialog) {\n this.groupSelectorDialog.hide();\n }\n });\n\n // Clean up dialog reference when closed\n this.groupSelectorDialog.on('hidden', () => {\n this.groupSelectorDialog.destroy();\n this.groupSelectorDialog = null;\n });\n\n // Render and show the dialog\n await this.groupSelectorDialog.render(true, document.body);\n this.groupSelectorDialog.show();\n }\n\n /**\n * Find and switch to the menu that contains the given route\n */\n autoSwitchToMenuForRoute(route) {\n // Search through all menus to find one that contains this route\n for (const [menuName, menuConfig] of this.menus) {\n if (menuConfig.groupKind && !this.getApp().activeGroup)\n continue;\n if (this.menuContainsRoute(menuConfig, route)) {\n // Switch to this menu\n this._setActiveMenu(menuName);\n this.currentRoute = route;\n\n // Clear all active states and set new active item\n this.clearAllActiveStates();\n this.setActiveItemByRoute(route);\n\n // Re-render to show changes\n this.render();\n\n console.log(`Auto-switched to menu '${menuName}' for route '${route}'`);\n\n // Emit event for any listeners\n this.emit('menu-auto-switched', {\n menuName,\n route,\n config: menuConfig,\n sidebar: this\n });\n\n return true;\n }\n }\n\n return false; // No menu found for this route\n }\n\n /**\n * Clear active state from all menu items in all menus\n */\n clearAllActiveStates() {\n for (const [menuName, menuConfig] of this.menus) {\n for (const item of menuConfig.items || []) {\n item.active = false;\n if (item.children) {\n for (const child of item.children) {\n child.active = false;\n }\n }\n }\n }\n }\n\n /**\n * Set active state for item matching the given route\n */\n setActiveItemByRoute(route) {\n const normalizeRoute = (r) => {\n if (!r) return '/';\n // Decode URL-encoded characters (like %2F -> /)\n const decoded = decodeURIComponent(r);\n return decoded.startsWith('/') ? decoded : `/${decoded}`;\n };\n\n const targetRoute = normalizeRoute(route);\n\n // Search through all menus\n for (const [menuName, menuConfig] of this.menus) {\n if (menuConfig.groupKind && !this.getApp().activeGroup)\n continue;\n for (const item of menuConfig.items || []) {\n // Check main item\n if (item.route) {\n const itemRoute = normalizeRoute(item.route);\n if (this.routesMatch(targetRoute, itemRoute)) {\n item.active = true;\n this.activeMenuItem = item;\n return true;\n }\n }\n\n // Check children\n if (item.children) {\n for (const child of item.children) {\n if (child.route) {\n const childRoute = normalizeRoute(child.route);\n if (this.routesMatch(targetRoute, childRoute)) {\n child.active = true;\n item.active = true; // Parent also active\n return true;\n }\n }\n }\n }\n }\n }\n\n return false;\n }\n\n /**\n * Check if a menu contains a specific route in its items or children\n */\n menuContainsRoute(menuConfig, route) {\n const normalizeRoute = (r) => {\n if (!r) return '/';\n // Decode URL-encoded characters (like %2F -> /)\n const decoded = decodeURIComponent(r);\n return decoded.startsWith('/') ? decoded : `/${decoded}`;\n };\n\n const targetRoute = normalizeRoute(route);\n\n // Check each item in the menu\n for (const item of menuConfig.items || []) {\n // Check main item\n if (item.route) {\n const itemRoute = normalizeRoute(item.route);\n if (this.routesMatch(targetRoute, itemRoute)) {\n return true;\n }\n }\n\n // Check children\n if (item.children) {\n for (const child of item.children) {\n if (child.route) {\n const childRoute = normalizeRoute(child.route);\n if (this.routesMatch(targetRoute, childRoute)) {\n return true;\n }\n }\n }\n }\n }\n\n return false;\n }\n\n /**\n * Check if two routes match (using same logic as isItemActive)\n */\n routesMatch(currentRoute, itemRoute) {\n return this.getApp().router.doRoutesMatch(currentRoute, itemRoute);\n }\n\n getTemplate() {\n if (this.customView) {\n return '<div class=\"sidebar-container\" id=\"sidebar-custom-view-container\"></div>';\n }\n if (this.showSearch) return this.getSearchTemplate();\n return this.getMenuTemplate();\n }\n\n getSearchTemplate() {\n return `\n <div class=\"sidebar-container\" id=\"sidebar-search-container\">\n </div>\n `;\n }\n\n getMenuTemplate() {\n return `\n <div class=\"sidebar-container\">\n {{#data.currentMenu}}\n <!-- Header -->\n {{#header}}\n <div class=\"sidebar-header\">\n {{{header}}}\n {{#showToggle}}\n <button class=\"sidebar-toggle\" data-action=\"toggle-sidebar\"\n aria-label=\"Toggle Sidebar\">\n <i class=\"bi bi-chevron-left toggle-icon\"></i>\n <i class=\"bi bi-chevron-right toggle-icon\"></i>\n </button>\n {{/showToggle}}\n </div>\n {{/header}}\n\n <!-- Navigation Items -->\n <div class=\"sidebar-body\">\n <ul class=\"nav nav-pills flex-column sidebar-nav\" id=\"sidebar-nav-menu\">\n {{#items}}\n {{>nav-item}}\n {{/items}}\n </ul>\n </div>\n\n <!-- Footer -->\n {{#footer}}\n <div class=\"sidebar-footer\">\n {{{footer}}}\n </div>\n {{/footer}}\n {{/data.currentMenu}}\n\n {{^data.currentMenu}}\n <div class=\"sidebar-empty\">\n <p class=\"text-danger text-center\">No menu configured</p>\n </div>\n {{/data.currentMenu}}\n </div>\n `;\n }\n\n /**\n * Get template partials for rendering\n */\n getPartials() {\n return {\n 'nav-item': `\n {{#isDivider}}\n {{>nav-divider}}\n {{/isDivider}}\n {{#isSpacer}}\n {{>nav-spacer}}\n {{/isSpacer}}\n {{#isLabel}}\n {{>nav-label}}\n {{/isLabel}}\n\n {{^isDivider}}\n {{^isSpacer}}\n {{^isLabel}}\n <li class=\"nav-item\">\n {{#hasChildren}}\n <!-- Item with submenu -->\n <a class=\"nav-link {{#active}}active{{/active}} has-children collapsed\"\n data-bs-toggle=\"collapse\"\n href=\"#collapse-{{id}}\"\n role=\"button\"\n aria-expanded=\"{{#active}}true{{/active}}{{^active}}false{{/active}}\"\n data-action=\"toggle-submenu\">\n {{#icon}}<i class=\"{{icon}} me-2\"></i>{{/icon}}\n <span class=\"nav-text\">{{text}}</span>\n {{#badge}}\n <span class=\"{{badge.class}} ms-auto\">{{badge.text}}</span>\n {{/badge}}\n <i class=\"bi bi-chevron-down nav-arrow ms-auto\"></i>\n </a>\n <div class=\"collapse {{#active}}show{{/active}}\" id=\"collapse-{{id}}\" data-bs-parent=\"#sidebar-nav-menu\">\n <ul class=\"nav flex-column nav-submenu\">\n {{#children}}\n <li class=\"nav-item\">\n <a class=\"nav-link {{#active}}active{{/active}}\"\n {{#action}}data-action=\"{{action}}\"{{/action}}\n {{#href}}href=\"{{href}}\"{{/href}}>\n {{#icon}}<i class=\"{{icon}} me-2\"></i>{{/icon}}\n <span class=\"nav-text\">{{text}}</span>\n {{#badge}}\n <span class=\"{{badge.class}} ms-auto\">{{badge.text}}</span>\n {{/badge}}\n </a>\n </li>\n {{/children}}\n </ul>\n </div>\n {{/hasChildren}}\n {{^hasChildren}}\n <!-- Simple item -->\n <a class=\"nav-link {{#active}}active{{/active}} {{#disabled}}disabled{{/disabled}}\"\n {{#action}}{{^disabled}}data-action=\"{{action}}\"{{/disabled}}{{/action}}\n {{#href}}{{^disabled}}href=\"{{href}}\"{{/disabled}}{{/href}}>\n {{#icon}}<i class=\"{{icon}} me-2\"></i>{{/icon}}\n <span class=\"nav-text\">{{text}}</span>\n {{#badge}}\n <span class=\"{{badge.class}} ms-auto\">{{badge.text}}</span>\n {{/badge}}\n </a>\n {{/hasChildren}}\n </li>\n {{/isLabel}}\n {{/isSpacer}}\n {{/isDivider}}\n `,\n 'nav-divider': `\n <li class=\"nav-divider-item\">\n <hr class=\"nav-divider-line\">\n </li>\n `,\n 'nav-spacer': `\n <li class=\"nav-spacer-item\"></li>\n `,\n 'nav-label': `\n <li class=\"nav-item {{className}}\">\n <div class=\"nav-text px-3\">{{text}}</div>\n </li>\n `\n };\n }\n\n getGroupHeader() {\n return this.groupHeader;\n }\n\n /**\n * Add a menu configuration\n */\n addMenu(name, config) {\n if (config.groupKind && !config.header) {\n config.header = this.getGroupHeader();\n }\n\n this.menus.set(name, {\n name,\n groupKind: config.groupKind || null,\n header: config.header || null,\n footer: config.footer || null,\n items: config.items || [],\n data: config.data || {},\n className: config.className || \"sidebar sidebar-dark\"\n });\n\n\n // Set as active if it's the first menu\n if (!this.activeMenuName) {\n this._setActiveMenu(name);\n }\n\n return this;\n }\n\n _setActiveMenu(name) {\n this.showSearch = false;\n this.activeMenuName = name;\n const config = this.getCurrentMenuConfig();\n if (config.className) {\n this.setClass(config.className);\n } else {\n this.setClass('sidebar');\n }\n }\n\n /**\n * Set the active menu\n */\n async setActiveMenu(name) {\n if (!this.menus.has(name)) {\n console.warn(`Menu '${name}' not found`);\n return this;\n }\n\n const menuConfig = this.menus.get(name);\n\n if (menuConfig.groupKind) {\n this.lastGroupMenu = menuConfig;\n // Handle group kind logic here\n if (!this.getApp().activeGroup) {\n this.showGroupSearch();\n return;\n }\n }\n\n this._setActiveMenu(name);\n await this.render();\n // Emit event\n this.emit('menu-changed', {\n menuName: name,\n config: menuConfig,\n sidebar: this\n });\n\n return this;\n }\n\n getGroupMenu(group) {\n if (!group) {\n console.warn('No group provided');\n return null;\n }\n // Find menu by group.kind\n let targetMenu = this.lastGroupMenu;\n let anyGroupMenu = null;\n if (group._.kind) {\n for (const [menuName, menuConfig] of this.menus) {\n // Check if groupKind matches\n const matches = this._groupKindMatches(menuConfig.groupKind, group._.kind);\n\n if (matches) {\n targetMenu = menuConfig;\n break;\n } else if (menuConfig.groupKind === 'any') {\n anyGroupMenu = menuConfig;\n }\n }\n }\n\n if (!targetMenu) {\n return anyGroupMenu;\n }\n return targetMenu;\n }\n\n /**\n * Check if a groupKind matches the group's kind\n * Supports both single string and array of strings\n * @param {string|string[]} groupKind - Single kind or array of kinds\n * @param {string} kind - The group's kind to match\n * @returns {boolean} True if matches\n */\n _groupKindMatches(groupKind, kind) {\n if (!groupKind || !kind) return false;\n\n // Handle array of kinds\n if (Array.isArray(groupKind)) {\n return groupKind.includes(kind);\n }\n\n // Handle single kind string\n return groupKind === kind;\n }\n\n showMenuForGroup(group) {\n if (!group) {\n console.warn('No group provided');\n return;\n }\n // Find menu by group.kind\n let targetMenu = this.getGroupMenu(group);\n\n if (!targetMenu) {\n console.warn(`No menu found for group kind: ${group.kind}`);\n return;\n }\n this._setActiveMenu(targetMenu.name);\n this.render();\n // Emit event\n this.emit('menu-changed', {\n menuName: targetMenu.name,\n config: targetMenu,\n sidebar: this\n });\n return this;\n }\n\n /**\n * Get menu configuration\n */\n getMenuConfig(name) {\n return this.menus.get(name) || null;\n }\n\n /**\n * Get current active menu configuration\n */\n getCurrentMenuConfig() {\n return this.activeMenuName ? this.menus.get(this.activeMenuName) : null;\n }\n\n /**\n * Update menu configuration\n */\n updateMenu(name, updates) {\n const menu = this.menus.get(name);\n if (!menu) {\n console.warn(`Menu '${name}' not found`);\n return this;\n }\n\n // Deep merge updates\n Object.assign(menu, updates);\n\n // Re-render if this is the active menu\n if (this.activeMenuName === name) {\n this.render();\n }\n\n return this;\n }\n\n /**\n * Remove a menu\n */\n removeMenu(name) {\n this.menus.delete(name);\n\n // If this was the active menu, switch to another or clear\n if (this.activeMenuName === name) {\n const remainingMenus = Array.from(this.menus.keys());\n this.activeMenuName = remainingMenus.length > 0 ? remainingMenus[0] : null;\n this.render();\n }\n\n return this;\n }\n\n /**\n * Get view data for template rendering\n */\n async onBeforeRender() {\n const currentMenu = this.getCurrentMenuConfig();\n\n if (!currentMenu) {\n return { currentMenu: null };\n }\n\n let subData = {\n version: this.getApp().version || null,\n group: this.getApp().activeGroup || null,\n user: this.getApp.activeUser || null\n };\n // Process menu data through template if it contains handlebars\n this.data = {\n currentMenu: {\n header: this.renderTemplateString(currentMenu.header || '', subData),\n footer: this.renderTemplateString(currentMenu.footer || '', subData),\n items: this.processNavItems(currentMenu.items, currentMenu.groupKind),\n data: currentMenu.data,\n showToggle: this.showToggle\n }\n\n };\n }\n\n async onAfterRender() {\n // Re-initialize tooltips after render, but only if collapsed\n if (this.isCollapsedState()) {\n // Small delay to ensure DOM is fully rendered\n setTimeout(() => this.initializeTooltips(), 50);\n } else {\n this.destroyTooltips();\n }\n }\n\n setCustomView(view) {\n if (this.customView) {\n this.removeChild(this.customView.id);\n }\n this.customView = view;\n if (view) {\n view.containerId = 'sidebar-custom-view-container';\n this.addChild(view);\n }\n this.render();\n return this;\n }\n\n clearCustomView() {\n if (this.customView) {\n this.removeChild(this.customView.id);\n this.customView = null;\n }\n this.render();\n return this;\n }\n\n /**\n * Process navigation items - add IDs, active states, and proper hrefs\n */\n processNavItems(items, groupKind) {\n const app = this.getApp();\n const activeUser = app?.activeUser;\n const activeGroup = app?.activeGroup;\n\n // Helper function to update route with group parameter\n const updateRouteWithGroup = (route) => {\n if (groupKind && activeGroup && activeGroup.id) {\n const separator = route.includes('?') ? '&' : '?';\n return `${route}${separator}group=${activeGroup.id}`;\n }\n return route;\n };\n\n return items.map((item, index) => {\n // Handle divider items\n if (item === \"\" || (typeof item === 'object' && item.divider)) {\n return {\n isDivider: true,\n id: `divider-${index}`\n };\n }\n\n // Handle spacer items\n if (typeof item === 'object' && item.spacer) {\n return {\n isSpacer: true,\n id: `spacer-${index}`\n };\n }\n\n const processedItem = { ...item };\n\n // Check permissions - skip item if user doesn't have required permissions\n if (processedItem.permissions) {\n if (!activeUser || !activeUser.hasPermission(processedItem.permissions)) {\n return null; // Will be filtered out\n }\n }\n\n // Check requiresGroupKind - skip item if group kind doesn't match\n if (processedItem.requiresGroupKind) {\n const groupKind = activeGroup?._.kind || activeGroup?.kind;\n if (!groupKind || !this._groupKindMatches(processedItem.requiresGroupKind, groupKind)) {\n return null; // Will be filtered out\n }\n }\n\n if (processedItem.kind === 'label') {\n processedItem.isLabel = true;\n if (!processedItem.id) {\n processedItem.id = `nav-label-${index}`;\n }\n return processedItem;\n }\n\n // Generate ID if not provided\n if (!processedItem.id) {\n processedItem.id = `nav-${index}`;\n }\n\n // Use route directly as href (like TopNav does)\n if (processedItem.route) {\n processedItem.href = updateRouteWithGroup(processedItem.route);\n } else if (processedItem.page) {\n // If only page is provided, convert to route format\n const baseRoute = processedItem.page.startsWith('/') ? processedItem.page : `/${processedItem.page}`;\n processedItem.href = updateRouteWithGroup(baseRoute);\n processedItem.route = processedItem.href; // Store for active matching\n }\n\n // Active state is already set on the item object, no need to calculate\n\n // Process children\n if (processedItem.children) {\n processedItem.children = processedItem.children.map(child => {\n const processedChild = { ...child };\n\n // Check permissions for child items\n if (processedChild.permissions && activeUser) {\n if (!activeUser.hasPermission(processedChild.permissions)) {\n return null; // Will be filtered out\n }\n }\n\n // Check requiresGroupKind for child items\n if (processedChild.requiresGroupKind) {\n const groupKind = activeGroup?._.kind || activeGroup?.kind;\n if (!groupKind || !this._groupKindMatches(processedChild.requiresGroupKind, groupKind)) {\n return null; // Will be filtered out\n }\n }\n\n // Use route directly as href\n if (processedChild.route) {\n processedChild.href = updateRouteWithGroup(processedChild.route);\n } else if (processedChild.page) {\n const baseRoute = processedChild.page.startsWith('/') ? processedChild.page : `/${processedChild.page}`;\n processedChild.href = updateRouteWithGroup(baseRoute);\n processedChild.route = processedChild.href;\n }\n\n // Active state is already set on the child object\n return processedChild;\n }).filter(child => child !== null); // Filter out permission-denied children\n\n // Update hasChildren flag after filtering children\n processedItem.hasChildren = !!(processedItem.children && processedItem.children.length > 0);\n } else {\n // Add hasChildren flag for template logic\n processedItem.hasChildren = false;\n }\n\n return processedItem;\n }).filter(item => item !== null); // Filter out permission-denied items\n }\n\n\n\n\n /**\n * Check if navigation item should be active (similar to TopNav)\n */\n isItemActive(item) {\n if (!item.route || !this.currentRoute) {\n return false;\n }\n\n const normalizeRoute = (route) => {\n if (!route) return '/';\n // Decode URL-encoded characters (like %2F -> /)\n const decoded = decodeURIComponent(route);\n return decoded.startsWith('/') ? decoded : `/${decoded}`;\n };\n\n const itemRoute = normalizeRoute(item.route);\n const currentRoute = normalizeRoute(this.currentRoute);\n\n if (itemRoute === '/' && currentRoute === '/') {\n return true;\n }\n\n if (itemRoute !== '/' && currentRoute !== '/') {\n return currentRoute.startsWith(itemRoute) || currentRoute === itemRoute;\n }\n\n return false;\n }\n\n /**\n * Update active item based on current route (like TopNav)\n */\n async updateActiveItem(route) {\n this.currentRoute = route;\n\n // Clear all active states and set new active item\n this.clearAllActiveStates();\n this.setActiveItemByRoute(route);\n\n await this.render();\n return this;\n }\n\n /**\n * Action handler: Toggle submenu\n */\n async handleActionToggleSubmenu(event, element) {\n const arrow = element.querySelector('.nav-arrow');\n if (arrow) {\n arrow.classList.toggle('rotated');\n }\n }\n\n /**\n * Action handler: Toggle sidebar collapsed/expanded state\n */\n async handleActionToggleSidebar(event, element) {\n this.toggleSidebar();\n }\n\n onActionShowGroupMenu(action, event, el) {\n this.setActiveMenu(\"group_default\");\n\n return false;\n }\n\n async onActionDefault(action, event, el) {\n const config = this.getCurrentMenuConfig();\n if (!config) return;\n\n for (const item of config.items) {\n if ((item.action == action) && item.handler) {\n item.handler(action, event, el);\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Get all menu names\n */\n getMenuNames() {\n return Array.from(this.menus.keys());\n }\n\n /**\n * Check if menu exists\n */\n hasMenu(name) {\n return this.menus.has(name);\n }\n\n /**\n * Clear all menus\n */\n clearMenus() {\n this.menus.clear();\n this.activeMenuName = null;\n this.render();\n return this;\n }\n\n /**\n * Set data for current menu\n */\n setMenuData(data) {\n const currentMenu = this.getCurrentMenuConfig();\n if (currentMenu) {\n currentMenu.data = { ...currentMenu.data, ...data };\n this.render();\n }\n return this;\n }\n\n /**\n * Get data for current menu\n */\n getMenuData() {\n const currentMenu = this.getCurrentMenuConfig();\n return currentMenu ? currentMenu.data : {};\n }\n\n /**\n * Setup listeners for route change events (like TopNav)\n */\n setupRouteListeners() {\n const app = this.getApp();\n if (app && app.events) {\n app.events.on([\"page:showing\"], (data) => {\n this.onRouteChanged(data);\n });\n app.events.on(\"group:changed\", (data) => {\n this.showMenuForGroup(data.group);\n });\n app.events.on(\"portal:user-changed\", (data) => {\n this.render();\n });\n }\n }\n\n /**\n * Handle route changed event - auto-switch menu and update active item\n */\n onRouteChanged(data) {\n if (data.page && data.page.route) {\n const route = data.page.route;\n if (this.activeMenuItem && this.routesMatch(route, this.activeMenuItem.route)) {\n return;\n }\n // First, try to auto-switch to correct menu for this route\n const switchedMenu = this.autoSwitchToMenuForRoute(route);\n\n // If no menu switch happened, still update active item\n if (!switchedMenu) {\n this.clearAllActiveStates();\n this.setActiveItemByRoute(route);\n this.updateActiveItem(route);\n }\n\n if (switchedMenu) {\n console.log(`Route changed to '${route}', auto-switched menu`);\n }\n }\n }\n\n /**\n * Toggle sidebar between collapsed and expanded states\n */\n toggleSidebar() {\n const portalContainer = document.querySelector('.portal-container');\n if (!portalContainer) return;\n\n // Hide any visible tooltips before state change\n this.hideAllTooltips();\n\n const isCurrentlyCollapsed = portalContainer.classList.contains('collapse-sidebar');\n const isCurrentlyHidden = portalContainer.classList.contains('hide-sidebar');\n\n if (isCurrentlyHidden) {\n // Hidden -> Normal\n portalContainer.classList.remove('hide-sidebar');\n this.isCollapsed = false;\n this.destroyTooltips();\n } else if (isCurrentlyCollapsed) {\n // Collapsed -> Normal\n portalContainer.classList.remove('collapse-sidebar');\n this.isCollapsed = false;\n this.destroyTooltips();\n } else {\n // Normal -> Collapsed\n portalContainer.classList.add('collapse-sidebar');\n this.isCollapsed = true;\n // Initialize tooltips with delay to ensure DOM is ready\n setTimeout(() => this.initializeTooltips(), 150);\n }\n\n return this;\n }\n\n /**\n * Set sidebar state programmatically\n */\n setSidebarState(state) {\n const portalContainer = document.querySelector('.portal-container');\n if (!portalContainer) return this;\n\n // Remove all state classes first\n portalContainer.classList.remove('collapse-sidebar', 'hide-sidebar');\n\n switch (state) {\n case 'collapsed':\n portalContainer.classList.add('collapse-sidebar');\n this.isCollapsed = true;\n break;\n case 'hidden':\n portalContainer.classList.add('hide-sidebar');\n this.isCollapsed = false;\n break;\n case 'normal':\n default:\n this.isCollapsed = false;\n break;\n }\n\n // Handle tooltips based on state\n if (this.isCollapsed) {\n // Hide any visible tooltips first\n this.hideAllTooltips();\n // Initialize tooltips when collapsed\n setTimeout(() => this.initializeTooltips(), 100);\n } else {\n // Destroy tooltips when not collapsed\n this.destroyTooltips();\n }\n\n return this;\n }\n\n /**\n * Initialize tooltips for nav items when sidebar is collapsed\n */\n initializeTooltips() {\n // Clean up existing tooltips first\n this.destroyTooltips();\n\n // Only initialize tooltips in collapsed state\n if (!this.isCollapsedState()) {\n return this;\n }\n\n // Auto-generate tooltips from nav-text content\n const navLinks = this.element.querySelectorAll('.sidebar-nav .nav-link');\n\n navLinks.forEach((link) => {\n const navText = link.querySelector('.nav-text');\n\n if (navText && navText.textContent.trim()) {\n const tooltipText = navText.textContent.trim();\n\n // Set Bootstrap tooltip attributes\n link.setAttribute('data-bs-toggle', 'tooltip');\n link.setAttribute('data-bs-placement', 'right');\n link.setAttribute('data-bs-title', tooltipText);\n link.setAttribute('data-bs-container', 'body');\n\n // Initialize Bootstrap tooltip with better config\n if (window.bootstrap && window.bootstrap.Tooltip) {\n // Extract custom theme/size if specified\n const theme = link.getAttribute('data-tooltip-theme');\n const size = link.getAttribute('data-tooltip-size');\n\n // Build custom class list\n let customClass = '';\n if (theme) customClass += `tooltip-${theme} `;\n if (size) customClass += `tooltip-${size}`;\n\n // Build options object\n const tooltipOptions = {\n placement: 'right',\n container: 'body',\n trigger: 'hover',\n delay: { show: 500, hide: 100 },\n fallbackPlacements: ['top', 'bottom', 'left']\n };\n\n // Only add customClass if it has a value\n const trimmedClass = customClass.trim();\n if (trimmedClass) {\n tooltipOptions.customClass = trimmedClass;\n }\n\n const tooltip = new window.bootstrap.Tooltip(link, tooltipOptions);\n\n // Store tooltip instance for better management\n link._tooltipInstance = tooltip;\n\n // Add event listeners to prevent stuck tooltips\n link.addEventListener('click', () => {\n tooltip.hide();\n });\n\n link.addEventListener('blur', () => {\n tooltip.hide();\n });\n }\n }\n });\n\n // Add global event listeners to hide tooltips\n this.addTooltipHideListeners();\n\n return this;\n }\n\n destroyTooltips() {\n // Remove global tooltip hide listeners\n this.removeTooltipHideListeners();\n\n const navLinks = this.element.querySelectorAll('.sidebar-nav .nav-link[data-bs-toggle=\"tooltip\"]');\n\n navLinks.forEach((link) => {\n // Use stored instance first, then try to get it\n const tooltipInstance = link._tooltipInstance || window.bootstrap?.Tooltip?.getInstance(link);\n if (tooltipInstance) {\n // Force hide before dispose\n tooltipInstance.hide();\n tooltipInstance.dispose();\n }\n\n // Clean up stored reference\n delete link._tooltipInstance;\n\n // Remove tooltip attributes\n link.removeAttribute('data-bs-toggle');\n link.removeAttribute('data-bs-placement');\n link.removeAttribute('data-bs-title');\n link.removeAttribute('data-bs-container');\n });\n\n return this;\n }\n\n /**\n * Get current sidebar state\n */\n getSidebarState() {\n const portalContainer = document.querySelector('.portal-container');\n if (!portalContainer) return 'normal';\n\n if (portalContainer.classList.contains('hide-sidebar')) {\n return 'hidden';\n } else if (portalContainer.classList.contains('collapse-sidebar')) {\n return 'collapsed';\n } else {\n return 'normal';\n }\n }\n\n /**\n * Check if sidebar is collapsed\n */\n isCollapsedState() {\n return this.getSidebarState() === 'collapsed';\n }\n\n /**\n * Enable/disable toggle button\n */\n setToggleEnabled(enabled) {\n this.showToggle = enabled;\n this.render();\n return this;\n }\n\n /**\n * Initialize menus from options\n */\n initializeMenus(options) {\n if (options.menus) {\n for (const menu of options.menus) {\n this.addMenu(menu.name, menu);\n }\n } else if (options.menu) {\n options.menu.name = options.menu.name || \"default\";\n this.addMenu(options.menu.name, options.menu);\n }\n }\n\n /**\n * Add global listeners to hide tooltips when needed\n */\n addTooltipHideListeners() {\n // Hide tooltips on scroll\n this._tooltipScrollHandler = () => this.hideAllTooltips();\n this.element.addEventListener('scroll', this._tooltipScrollHandler, { passive: true });\n\n // Hide tooltips on route change\n this._tooltipRouteHandler = () => this.hideAllTooltips();\n const app = this.getApp();\n\n\n // Hide tooltips on window blur\n this._tooltipBlurHandler = () => this.hideAllTooltips();\n window.addEventListener('blur', this._tooltipBlurHandler);\n\n // Hide tooltips on escape key\n this._tooltipEscapeHandler = (e) => {\n if (e.key === 'Escape') {\n this.hideAllTooltips();\n }\n };\n document.addEventListener('keydown', this._tooltipEscapeHandler);\n }\n\n /**\n * Remove global tooltip hide listeners\n */\n removeTooltipHideListeners() {\n if (this._tooltipScrollHandler) {\n this.element.removeEventListener('scroll', this._tooltipScrollHandler);\n delete this._tooltipScrollHandler;\n }\n\n if (this._tooltipBlurHandler) {\n window.removeEventListener('blur', this._tooltipBlurHandler);\n delete this._tooltipBlurHandler;\n }\n\n if (this._tooltipEscapeHandler) {\n document.removeEventListener('keydown', this._tooltipEscapeHandler);\n delete this._tooltipEscapeHandler;\n }\n }\n\n /**\n * Force hide all visible tooltips\n */\n hideAllTooltips() {\n const navLinks = this.element.querySelectorAll('.sidebar-nav .nav-link[data-bs-toggle=\"tooltip\"]');\n navLinks.forEach((link) => {\n const tooltip = link._tooltipInstance || window.bootstrap?.Tooltip?.getInstance(link);\n if (tooltip) {\n tooltip.hide();\n }\n });\n\n // Also hide any orphaned tooltips\n const visibleTooltips = document.querySelectorAll('.tooltip.show');\n visibleTooltips.forEach(tooltip => {\n tooltip.remove();\n });\n }\n\n /**\n * Cleanup on destroy\n */\n async onBeforeDestroy() {\n // Clean up tooltips\n this.destroyTooltips();\n\n // Call parent cleanup\n await super.onBeforeDestroy();\n }\n\n /**\n * Setup responsive behavior for mobile\n */\n setupResponsiveBehavior() {\n const checkMobile = () => {\n const isMobile = window.innerWidth <= 768;\n const portalContainer = document.querySelector('.portal-container');\n\n if (portalContainer) {\n if (isMobile) {\n portalContainer.classList.add('sidebar-mobile');\n } else {\n portalContainer.classList.remove('sidebar-mobile', 'sidebar-open');\n }\n }\n };\n\n // Check on load and resize\n checkMobile();\n window.addEventListener('resize', checkMobile);\n }\n\n /**\n * Static method to create a sidebar with common configuration\n */\n static createDefault(options = {}) {\n return new Sidebar({\n theme: 'sidebar-clean',\n showToggle: true,\n autoCollapseMobile: true,\n ...options\n });\n }\n\n /**\n * Static method to create a minimal sidebar\n */\n static createMinimal(options = {}) {\n return new Sidebar({\n theme: 'sidebar-clean',\n showToggle: false,\n autoCollapseMobile: false,\n ...options\n });\n }\n\n /**\n * Set sidebar theme\n */\n setSidebarTheme(theme) {\n // Remove existing theme classes\n this.removeClass('sidebar-light sidebar-dark sidebar-clean');\n\n // Add new theme\n this.sidebarTheme = theme;\n this.addClass(theme);\n\n return this;\n }\n\n /**\n * Quick method to show/hide the sidebar\n */\n show() {\n return this.setSidebarState('normal');\n }\n\n hide() {\n return this.setSidebarState('hidden');\n }\n\n collapse() {\n return this.setSidebarState('collapsed');\n }\n\n expand() {\n return this.setSidebarState('normal');\n }\n\n /**\n * Add pulse effect to toggle button\n */\n pulseToggle() {\n const toggleButton = this.element.querySelector('.sidebar-toggle');\n if (toggleButton) {\n toggleButton.classList.add('pulse');\n\n // Remove pulse after 3 seconds or first click\n const removePulse = () => {\n toggleButton.classList.remove('pulse');\n toggleButton.removeEventListener('click', removePulse);\n };\n\n toggleButton.addEventListener('click', removePulse, { once: true });\n setTimeout(removePulse, 3000);\n }\n return this;\n }\n\n /**\n * Utility method to quickly add a simple menu item\n */\n addSimpleMenuItem(menuName, text, route, icon = 'bi-circle') {\n const menu = this.menus.get(menuName);\n if (menu) {\n menu.items = menu.items || [];\n menu.items.push({\n text: text,\n route: route,\n icon: icon\n });\n\n if (this.activeMenuName === menuName) {\n this.render();\n }\n }\n return this;\n }\n\n /**\n * Utility method to quickly create and set a simple menu\n */\n setSimpleMenu(name, header, items) {\n const menu = {\n name: name,\n header: header,\n items: items\n };\n\n this.addMenu(name, menu);\n this.setActiveMenu(name);\n\n return this;\n }\n\n}\n\nexport default Sidebar;\n","/**\n * PageHeader - Displays page title, description, and actions above page content\n * Used by PortalApp to show consistent page headers\n */\n\nimport View from '@core/View.js';\n\nclass PageHeader extends View {\n constructor(options = {}) {\n super({\n tagName: 'div',\n className: 'page-header',\n ...options\n });\n\n // Configuration\n this.style = options.style || 'default'; // 'default' | 'minimal' | 'breadcrumb'\n this.size = options.size || 'md'; // 'sm' | 'md' | 'lg' | 'xl'\n this.showIcon = options.showIcon !== false;\n this.showDescription = options.showDescription !== false;\n this.showBreadcrumbs = options.showBreadcrumbs || false;\n \n // Current page reference\n this.currentPage = null;\n }\n\n async getTemplate() {\n if (this.style === 'minimal') {\n return this.getMinimalTemplate();\n } else if (this.style === 'breadcrumb') {\n return this.getBreadcrumbTemplate();\n }\n return this.getDefaultTemplate();\n }\n\n getDefaultTemplate() {\n return `\n {{#data.hasPage}}\n <div class=\"page-header-content page-header-{{data.size}}\">\n <div class=\"page-header-main\">\n <div class=\"page-header-info\">\n {{#data.showIcon}}\n {{#data.pageIcon}}\n <div class=\"page-icon\">\n <i class=\"{{data.pageIcon}}\"></i>\n </div>\n {{/data.pageIcon}}\n {{/data.showIcon}}\n \n <div class=\"page-title-group\">\n <h1 class=\"page-title\">{{data.pageTitle}}</h1>\n {{#data.showDescription}}\n {{#data.pageDescription}}\n <p class=\"page-description text-muted\">{{data.pageDescription}}</p>\n {{/data.pageDescription}}\n {{/data.showDescription}}\n </div>\n </div>\n\n {{#data.hasActions}}\n <div class=\"page-actions\">\n {{#data.actions}}\n <button class=\"btn {{buttonClass}}\" \n data-action=\"{{action}}\"\n type=\"button\">\n {{#icon}}<i class=\"{{icon}} me-1\"></i>{{/icon}}\n {{label}}\n </button>\n {{/data.actions}}\n </div>\n {{/data.hasActions}}\n </div>\n </div>\n {{/data.hasPage}}\n `;\n }\n\n getMinimalTemplate() {\n return `\n {{#data.hasPage}}\n <div class=\"page-header-content page-header-minimal\">\n <h1 class=\"page-title\">\n {{#data.showIcon}}\n {{#data.pageIcon}}<i class=\"{{data.pageIcon}} me-2\"></i>{{/data.pageIcon}}\n {{/data.showIcon}}\n {{data.pageTitle}}\n </h1>\n </div>\n {{/data.hasPage}}\n `;\n }\n\n getBreadcrumbTemplate() {\n return `\n {{#data.hasPage}}\n <div class=\"page-header-content page-header-breadcrumb\">\n {{#data.showBreadcrumbs}}\n <nav aria-label=\"breadcrumb\">\n <ol class=\"breadcrumb mb-2\">\n {{#data.breadcrumbs}}\n <li class=\"breadcrumb-item {{#active}}active{{/active}}\">\n {{#href}}<a href=\"{{href}}\">{{label}}</a>{{/href}}\n {{^href}}{{label}}{{/href}}\n </li>\n {{/data.breadcrumbs}}\n </ol>\n </nav>\n {{/data.showBreadcrumbs}}\n \n <div class=\"d-flex justify-content-between align-items-start\">\n <h1 class=\"page-title\">\n {{#data.showIcon}}\n {{#data.pageIcon}}<i class=\"{{data.pageIcon}} me-2\"></i>{{/data.pageIcon}}\n {{/data.showIcon}}\n {{data.pageTitle}}\n </h1>\n \n {{#data.hasActions}}\n <div class=\"page-actions\">\n {{#data.actions}}\n <button class=\"btn {{buttonClass}}\" \n data-action=\"{{action}}\"\n type=\"button\">\n {{#icon}}<i class=\"{{icon}} me-1\"></i>{{/icon}}\n {{label}}\n </button>\n {{/data.actions}}\n </div>\n {{/data.hasActions}}\n </div>\n \n {{#data.showDescription}}\n {{#data.pageDescription}}\n <p class=\"page-description text-muted mt-2\">{{data.pageDescription}}</p>\n {{/data.pageDescription}}\n {{/data.showDescription}}\n </div>\n {{/data.hasPage}}\n `;\n }\n\n async onBeforeRender() {\n await super.onBeforeRender();\n\n const page = this.currentPage;\n const hasPage = !!page;\n\n // Get headerActions from page options, instance, or constructor.prototype\n const headerActions = page?.options?.headerActions ||\n page?.headerActions || \n page?.constructor?.prototype?.headerActions || \n [];\n\n this.data = {\n hasPage,\n pageTitle: page?.title || page?.name || '',\n pageIcon: page?.icon || page?.pageIcon || '',\n pageDescription: page?.description || '',\n showIcon: this.showIcon,\n showDescription: this.showDescription,\n showBreadcrumbs: this.showBreadcrumbs,\n breadcrumbs: page?.options?.breadcrumbs || page?.breadcrumbs || [],\n actions: headerActions,\n hasActions: headerActions.length > 0,\n size: this.size\n };\n }\n\n /**\n * Set the current page to display\n */\n setPage(page) {\n this.currentPage = page;\n if (this.mounted) {\n this.render();\n }\n }\n\n /**\n * Get the current page\n */\n getPage() {\n return this.currentPage;\n }\n\n /**\n * Handle action clicks from page header buttons\n */\n async onActionDefault(action, event, element) {\n // Emit to page if it has a handler\n if (this.currentPage && typeof this.currentPage.onHeaderAction === 'function') {\n await this.currentPage.onHeaderAction(action, event, element);\n return true;\n }\n\n // Emit event for parent to handle\n this.emit('action', {\n action,\n event,\n element,\n page: this.currentPage\n });\n\n return false;\n }\n}\n\nexport default PageHeader;\n","/**\n * DeniedPage - Access Denied page for MOJO Framework\n * Displays when a user attempts to access a page without proper permissions\n */\n\nimport Page from '@core/Page.js';\n\nclass DeniedPage extends Page {\n constructor(options = {}) {\n super({\n pageName: 'Access Denied',\n route: '/denied',\n title: 'Access Denied',\n pageIcon: 'bi bi-shield-x',\n template: `\n <div class=\"container mt-5\">\n <div class=\"row justify-content-center\">\n <div class=\"col-md-8 col-lg-6\">\n <div class=\"text-center mb-4\">\n <i class=\"bi bi-shield-x text-muted\" style=\"font-size: 3rem;\"></i>\n <h2 class=\"mt-3 mb-2\">Access Denied</h2>\n <p class=\"text-muted\">You don't have permission to access this page.</p>\n </div>\n\n {{#deniedPage}}\n <div class=\"card border-0 shadow-sm mb-4\">\n <div class=\"card-body\">\n <h6 class=\"card-subtitle mb-2 text-muted\">Requested Page</h6>\n <h5 class=\"card-title\">\n <i class=\"{{pageIcon}} me-2\"></i>\n {{displayName}}\n </h5>\n {{#route}}\n <p class=\"card-text text-muted small\">{{route}}</p>\n {{/route}}\n {{#description}}\n <p class=\"card-text\">{{description}}</p>\n {{/description}}\n\n {{#requiredPermissions}}\n <div class=\"mt-3\">\n <h6 class=\"mb-2\">Required Permissions:</h6>\n {{#permissions}}\n <span class=\"badge bg-light text-dark me-1 mb-1\">{{.}}</span>\n {{/permissions}}\n {{^permissions}}\n <span class=\"text-muted small\">Authentication required</span>\n {{/permissions}}\n </div>\n {{/requiredPermissions}}\n </div>\n </div>\n {{/deniedPage}}\n\n <div class=\"d-grid gap-2 d-md-flex justify-content-md-center\">\n <button type=\"button\" class=\"btn btn-primary\" data-action=\"go-back\">\n <i class=\"bi bi-arrow-left me-1\"></i>\n Go Back\n </button>\n <button type=\"button\" class=\"btn btn-outline-secondary\" data-action=\"go-home\">\n <i class=\"bi bi-house me-1\"></i>\n Home\n </button>\n {{#showLogin}}\n <button type=\"button\" class=\"btn btn-outline-primary\" data-action=\"login\">\n <i class=\"bi bi-box-arrow-in-right me-1\"></i>\n Login\n </button>\n {{/showLogin}}\n </div>\n\n {{#currentUser}}\n <div class=\"text-center mt-4\">\n <small class=\"text-muted\">\n Logged in as <strong>{{username}}</strong>\n </small>\n </div>\n {{/currentUser}}\n </div>\n </div>\n </div>\n `,\n ...options\n });\n\n // Store the denied page instance\n this.deniedPage = null;\n this.deniedPageOptions = null;\n }\n\n /**\n * Handle route parameters - expect denied page info\n */\n async onParams(params = {}, query = {}) {\n await super.onParams(params, query);\n\n // If page info is passed in params\n if (params.page) {\n this.deniedPage = params.page;\n this.deniedPageOptions = params.page.options || params.page.pageOptions || {};\n } else if (query.page) {\n // Handle page name from query string\n this.deniedPageName = query.page;\n }\n }\n\n /**\n * Set the denied page instance\n */\n setDeniedPage(pageInstance) {\n this.deniedPage = pageInstance;\n this.deniedPageOptions = pageInstance?.options || pageInstance?.pageOptions || {};\n return this;\n }\n\n /**\n * Get view data for template rendering\n */\n async getViewData() {\n const app = this.getApp();\n\n // Get current user info\n const currentUser = app?.activeUser || app?.getCurrentUser?.() || null;\n\n // Process denied page info\n let deniedPageInfo = null;\n if (this.deniedPage) {\n const permissions = this.deniedPageOptions?.permissions ||\n this.deniedPage.options?.permissions ||\n this.deniedPage.pageOptions?.permissions;\n\n deniedPageInfo = {\n displayName: this.deniedPage.displayName || this.deniedPage.pageName || this.deniedPage.title || 'Unknown Page',\n pageName: this.deniedPage.pageName,\n route: this.deniedPage.route,\n description: this.deniedPage.pageDescription || this.deniedPage.description,\n pageIcon: this.deniedPage.pageIcon || 'bi bi-file-text',\n requiredPermissions: permissions ? {\n permissions: Array.isArray(permissions) ? permissions : [permissions]\n } : null\n };\n } else if (this.deniedPageName) {\n deniedPageInfo = {\n displayName: this.deniedPageName,\n pageName: this.deniedPageName,\n pageIcon: 'bi bi-file-text'\n };\n }\n\n return {\n deniedPage: deniedPageInfo,\n currentUser: currentUser ? {\n username: currentUser.username || currentUser.name || currentUser.email || 'Unknown User',\n name: currentUser.name,\n email: currentUser.email\n } : null,\n showLogin: !currentUser // Show login button if not authenticated\n };\n }\n\n /**\n * Handle going back to previous page\n */\n async handleActionGoBack(event, element) {\n event.preventDefault();\n\n // Try to go back in browser history\n if (window.history.length > 1) {\n window.history.back();\n } else {\n // Fallback to home page\n await this.handleActionGoHome(event, element);\n }\n }\n\n /**\n * Handle navigation to home page\n */\n async handleActionGoHome(event, element) {\n event.preventDefault();\n\n const app = this.getApp();\n if (app) {\n await app.navigateToDefault();\n } else {\n // Fallback navigation\n window.location.href = '/';\n }\n }\n\n /**\n * Handle login action\n */\n async handleActionLogin(event, element) {\n event.preventDefault();\n\n const app = this.getApp();\n\n // Try to navigate to login page\n if (app) {\n try {\n await app.showPage('login');\n } catch (error) {\n // If login page doesn't exist, try auth route\n try {\n await app.navigate('/login');\n } catch (navError) {\n // Fallback - emit login required event\n this.emit('login-required', {\n returnUrl: this.deniedPage?.route || window.location.pathname\n });\n\n // Show message if no handlers\n setTimeout(() => {\n app?.showInfo?.('Please contact your administrator for access.');\n }, 100);\n }\n }\n }\n }\n\n /**\n * Called when entering this page\n */\n async onEnter() {\n await super.onEnter();\n\n // Set appropriate page title\n const pageName = this.deniedPage?.pageName || this.deniedPageName;\n if (pageName) {\n this.setMeta({\n title: `Access Denied - ${pageName}`\n });\n }\n\n // Log access denial for security monitoring\n console.warn('Access denied to page:', {\n page: this.deniedPage?.pageName || this.deniedPageName,\n route: this.deniedPage?.route,\n permissions: this.deniedPageOptions?.permissions,\n timestamp: new Date().toISOString()\n });\n }\n\n /**\n * Static helper to show access denied for a specific page\n */\n static showForPage(app, pageInstance) {\n const deniedPage = new DeniedPage();\n deniedPage.setDeniedPage(pageInstance);\n return app.showPage(deniedPage);\n }\n}\n\nexport default DeniedPage;\n","/**\n * NotFoundPage - 404 Not Found page for MOJO Framework\n * Displays when a user attempts to access a non-existent page or route\n */\n\nimport Page from '@core/Page.js';\n\nclass NotFoundPage extends Page {\n constructor(options = {}) {\n super({\n pageName: '404',\n route: '/404',\n title: '404 - Page Not Found',\n pageIcon: 'bi bi-search',\n template: `\n <div class=\"container mt-5\">\n <div class=\"row justify-content-center\">\n <div class=\"col-md-8 col-lg-6\">\n <div class=\"text-center mb-4\">\n <i class=\"bi bi-search text-muted\" style=\"font-size: 3rem;\"></i>\n <h2 class=\"mt-3 mb-2\">Page Not Found</h2>\n <p class=\"text-muted\">The page you're looking for doesn't exist.</p>\n </div>\n\n {{#path}}\n <div class=\"card border-0 shadow-sm mb-4\">\n <div class=\"card-body text-center\">\n <h6 class=\"card-subtitle mb-2 text-muted\">Requested Path</h6>\n <code class=\"text-primary\">{{path}}</code>\n </div>\n </div>\n {{/path}}\n\n <div class=\"d-grid gap-2 d-md-flex justify-content-md-center\">\n <button type=\"button\" class=\"btn btn-primary\" data-action=\"go-back\">\n <i class=\"bi bi-arrow-left me-1\"></i>\n Go Back\n </button>\n <button type=\"button\" class=\"btn btn-outline-secondary\" data-action=\"go-home\">\n <i class=\"bi bi-house me-1\"></i>\n Home\n </button>\n </div>\n </div>\n </div>\n </div>\n `,\n ...options\n });\n\n // Store the not found path\n this.path = null;\n }\n\n /**\n * Handle route parameters\n */\n async onParams(params = {}, query = {}) {\n await super.onParams(params, query);\n\n // Store path from params or query\n if (params.path) {\n this.path = params.path;\n }\n if (query.path) {\n this.path = query.path;\n }\n }\n\n /**\n * Set not found path\n */\n setInfo(path) {\n this.path = path || null;\n return this;\n }\n\n /**\n * Handle going back to previous page\n */\n async handleActionGoBack(event, _element) {\n event.preventDefault();\n\n // Try to go back in browser history\n if (window.history.length > 1) {\n window.history.back();\n } else {\n // Fallback to home page\n await this.handleActionGoHome(event, _element);\n }\n }\n\n /**\n * Handle navigation to home page\n */\n async handleActionGoHome(event, _element) {\n event.preventDefault();\n\n const app = this.getApp();\n if (app) {\n await app.navigateToDefault();\n } else {\n // Fallback navigation\n window.location.href = '/';\n }\n }\n\n /**\n * Called when entering this page\n */\n async onEnter() {\n await super.onEnter();\n\n // Set appropriate page title\n if (this.path) {\n this.setMeta({\n title: `404 - ${this.path} Not Found`\n });\n }\n\n // Log 404 for analytics\n console.warn('404 Not Found:', {\n path: this.path,\n timestamp: new Date().toISOString()\n });\n }\n\n /**\n * Static helper to show 404 for a specific path\n */\n static showForPath(app, path) {\n const notFoundPage = new NotFoundPage();\n notFoundPage.setInfo(path);\n return notFoundPage.render(); // Just render, don't navigate\n }\n}\n\nexport default NotFoundPage;\n","/**\n * PortalApp - Complete portal application extending WebApp\n * Provides built-in navigation, sidebar, and content management\n * Clean, simple implementation that reuses WebApp and View logic\n */\n\nimport WebApp from '@core/WebApp.js';\nimport TopNav from '@core/views/navigation/TopNav.js';\nimport Sidebar from '@core/views/navigation/Sidebar.js';\nimport PageHeader from '@core/views/navigation/PageHeader.js';\nimport DeniedPage from '@core/pages/DeniedPage.js';\nimport TokenManager from '@core/services/TokenManager.js';\nimport {User} from '@core/models/User.js';\nimport {Group } from '@core/models/Group.js';\nimport {Member} from '@core/models/Member.js';\nimport NotFoundPage from '@core/pages/NotFoundPage.js';\nimport ToastService from '@core/services/ToastService.js';\nimport Dialog from '@core/views/feedback/Dialog.js';\n\nexport default class PortalApp extends WebApp {\n constructor(config = {}) {\n // Pass core WebApp config through\n super(config);\n\n this.sidebarConfig = config.sidebar;\n // Portal-specific configuration (clean flat structure)\n // if (config.sidebar && config.sidebar.menus) {\n // this.sidebarConfig.menus = config.sidebar.menus;\n // this.sidebarConfig.groupSelectorMode = config.sidebar.groupSelectorMode || \"inline\";\n // if (config.sidebar.groupHeader) {\n // this.sidebarConfig.groupHeader = config.sidebar.groupHeader;\n // }\n // } else if (config.sidebar.menu) {\n // this.sidebarConfig.menu = config.sidebar.menu;\n // } else if (config.sidebar.items) {\n // this.sidebarConfig.menu = config.sidebar;\n // }\n\n this.topbarConfig = config.topbar || {};\n\n // Legacy support - topnav -> topbar\n if (config.topnav && !config.topbar) {\n this.topbarConfig = config.topnav;\n }\n\n // Page header configuration\n this.showPageHeader = config.showPageHeader || false;\n this.pageHeaderConfig = config.pageHeader || {};\n\n // Portal components\n this.sidebar = null;\n this.topbar = null;\n this.topnav = null; // Legacy reference\n this.pageHeader = null;\n this.tokenManager = new TokenManager();\n\n // Active group management\n this.activeGroup = null;\n // Portal state - Load from localStorage first, then fallback to config\n if (!this.isMobile()) {\n this.sidebarCollapsed = this.loadSidebarState() ??\n (this.sidebarConfig.defaultCollapsed || false);\n } else {\n this.sidebarCollapsed = this.sidebarConfig.defaultCollapsed || false;\n }\n this.setupPageContainer();\n\n this.toast = new ToastService();\n this.Dialog = Dialog;\n\n this.registerPage(\"denied\", DeniedPage);\n this.registerPage(\"404\", NotFoundPage);\n }\n\n /**\n * Override WebApp start to setup portal layout\n */\n async start() {\n // Call parent start (handles router, error handling, etc.)\n // Setup router\n await this.checkAuthStatus();\n\n this.events.on('auth:unauthorized', () => {\n this.tokenManager.clearTokens();\n this.rest.clearAuth();\n this.setActiveUser(null);\n return;\n });\n\n this.events.on('auth:logout', () => {\n this.tokenManager.clearTokens();\n this.rest.clearAuth();\n this.setActiveUser(null);\n return;\n });\n\n this.events.on(\"browser:focus\", () => {\n if (!this.activeUser) return;\n this.tokenManager.checkAndRefreshTokens(this);\n });\n\n this.events.on('portal:action', this.onPortalAction.bind(this));\n\n if (this.activeUser) {\n // Check and load active group after auth\n await this.checkActiveGroup();\n }\n\n\n await this.setupRouter();\n\n // Mark as started\n this.isStarted = true;\n\n // Emit app ready event\n this.events.emit('app:ready', { app: this });\n\n\n }\n\n async checkAuthStatus() {\n const tokenStatus = this.tokenManager.checkTokenStatus();\n\n // Handle logout scenarios\n if (tokenStatus.action === 'logout') {\n this.events.emit('auth:unauthorized', { app: this });\n return false;\n }\n\n // Handle refresh scenarios - attempt refresh if needed\n if (tokenStatus.action === 'refresh') {\n const refreshed = await this.tokenManager.checkAndRefreshTokens(this);\n if (!refreshed) {\n // If refresh failed, checkAndRefreshTokens already handled logout\n return false;\n }\n }\n\n // At this point we have a valid token\n const token = this.tokenManager.getTokenInstance();\n\n // If user already loaded, just start auto-refresh and return\n if (this.activeUser) {\n this.tokenManager.startAutoRefresh(this);\n return true;\n }\n\n // Load user data\n this.rest.setAuthToken(token.token);\n const user = new User({ id: token.getUserId() });\n const resp = await user.fetch();\n if (!resp.success) {\n this.tokenManager.clearTokens();\n this.events.emit('auth:unauthorized', { app: this, error: resp.error });\n return false;\n }\n\n this.setActiveUser(user);\n this.tokenManager.startAutoRefresh(this);\n return true;\n }\n\n /**\n * Check and load active group from storage\n */\n async checkActiveGroup() {\n // First check URL search params for group parameter\n const urlParams = new URLSearchParams(window.location.search);\n const urlGroupId = urlParams.get('group');\n\n // Determine which group ID to use: URL param takes priority\n const groupId = urlGroupId || this.loadActiveGroupId();\n\n if (groupId) {\n try {\n const group = new Group({ id: groupId });\n const resp = await group.fetch();\n if (!resp.success || !resp.data.status) {\n this.clearActiveGroup();\n console.warn('Failed to load active group:', resp.statusText);\n return;\n }\n\n this.activeGroup = group;\n // If we got the group from URL, save it as the new active group\n if (urlGroupId) {\n this.saveActiveGroupId(groupId);\n }\n\n if (this.activeUser) {\n this.activeUser.member = new Member();\n await this.activeUser.member.fetchForGroup(group.id);\n }\n\n // Emit event that group was loaded\n this.events.emit('group:loaded', { group: this.activeGroup });\n\n\n } catch (error) {\n console.warn('Failed to load active group:', error);\n // If URL group failed, try to clear it and fall back to stored group\n if (urlGroupId && !this.loadActiveGroupId()) {\n // URL group failed and no stored group, clear everything\n this.clearActiveGroupId();\n } else if (urlGroupId) {\n // URL group failed but we have a stored group, try that instead\n const storedGroupId = this.loadActiveGroupId();\n if (storedGroupId && storedGroupId !== urlGroupId) {\n try {\n const fallbackGroup = new Group({ id: storedGroupId });\n await fallbackGroup.fetch();\n this.activeGroup = fallbackGroup;\n this.events.emit('group:loaded', { group: this.activeGroup });\n\n } catch (fallbackError) {\n console.warn('Fallback to stored group also failed:', fallbackError);\n this.clearActiveGroupId();\n }\n }\n }\n }\n }\n }\n\n\n /**\n * Set the active group\n */\n async setActiveGroup(group) {\n const previousGroup = this.activeGroup;\n this.activeGroup = group;\n\n // Save to storage\n if (group && group.get('id')) {\n this.saveActiveGroupId(group.get('id'));\n } else {\n this.clearActiveGroupId();\n }\n\n if (this.activeUser) {\n this.activeUser.member = new Member();\n await this.activeUser.member.fetchForGroup(group.id);\n }\n\n // Emit event\n this.events.emit('group:changed', {\n group,\n previousGroup,\n app: this\n });\n\n const page = this.getCurrentPage();\n if (page && page.onGroupChange) {\n page.onGroupChange(group);\n }\n\n this.router.updateUrl({group:group.id}, { replace: true });\n\n return this;\n }\n\n /**\n * Get the active group\n */\n getActiveGroup() {\n return this.activeGroup;\n }\n\n /**\n * Clear the active group\n */\n async clearActiveGroup() {\n const previousGroup = this.activeGroup;\n this.activeGroup = null;\n this.clearActiveGroupId();\n // Emit event\n this.events.emit('group:cleared', {\n previousGroup,\n app: this\n });\n return this;\n }\n\n /**\n * Save active group ID to localStorage\n */\n saveActiveGroupId(groupId) {\n try {\n const key = this.getActiveGroupStorageKey();\n localStorage.setItem(key, groupId.toString());\n } catch (error) {\n console.warn('Failed to save active group ID:', error);\n }\n }\n\n /**\n * Load active group ID from localStorage\n */\n loadActiveGroupId() {\n try {\n const key = this.getActiveGroupStorageKey();\n return localStorage.getItem(key);\n } catch (error) {\n console.warn('Failed to load active group ID:', error);\n return null;\n }\n }\n\n /**\n * Clear active group ID from localStorage\n */\n clearActiveGroupId() {\n try {\n const key = this.getActiveGroupStorageKey();\n localStorage.removeItem(key);\n } catch (error) {\n console.warn('Failed to clear active group ID:', error);\n }\n }\n\n /**\n * Get storage key for active group ID\n */\n getActiveGroupStorageKey() {\n return `active_group_id`;\n }\n\n /**\n * Set portal profile to localStorage\n */\n setPortalProfile(profile) {\n try {\n localStorage.setItem('portal_profile', profile);\n } catch (error) {\n console.warn('Failed to save portal profile:', error);\n }\n }\n\n /**\n * Check if user needs to select a group\n */\n needsGroupSelection() {\n return !this.activeGroup;\n }\n\n /**\n * Setup layout based on configuration\n */\n setupPageContainer() {\n const container = typeof this.container === 'string'\n ? document.querySelector(this.container)\n : this.container;\n\n if (!container) {\n throw new Error(`Portal container not found: ${this.container}`);\n }\n\n // Create clean portal layout\n const showSidebar = this.sidebarConfig && Object.keys(this.sidebarConfig).length > 0;\n const showTopbar = this.topbarConfig && Object.keys(this.topbarConfig).length > 0;\n\n // If page header is enabled, wrap content in two containers\n const contentMarkup = this.showPageHeader ? `\n <div class=\"portal-content\" id=\"portal-content\">\n <div id=\"page-header\"></div>\n <div id=\"page-container\">\n <!-- Pages render here -->\n </div>\n </div>\n ` : `\n <div class=\"portal-content\" id=\"page-container\">\n <!-- Pages render here -->\n </div>\n `;\n\n container.innerHTML = `\n <div class=\"portal-layout hide-sidebar\">\n ${showSidebar ? '<div id=\"portal-sidebar\"></div>' : ''}\n <div class=\"portal-body\">\n ${showTopbar ? '<div id=\"portal-topnav\"></div>' : ''}\n ${contentMarkup}\n </div>\n </div>\n `;\n\n // Set page container for WebApp\n this.pageContainer = '#page-container';\n\n // Add portal CSS classes and apply saved state\n container.classList.add('portal-container');\n\n // Setup page container\n this.setupPortalComponents();\n\n // Apply the saved sidebar state\n this.applySidebarState(container);\n }\n\n /**\n * Setup portal components\n */\n async setupPortalComponents() {\n await this.setupSidebar();\n await this.setupTopbar();\n await this.setupPageHeader();\n this.setupPortalEvents();\n }\n\n /**\n * Setup sidebar component\n */\n async setupSidebar() {\n if (!this.sidebarConfig || Object.keys(this.sidebarConfig).length === 0) return;\n\n this.sidebar = new Sidebar({\n containerId: 'portal-sidebar',\n ...this.sidebarConfig\n });\n\n await this.sidebar.render();\n }\n\n /**\n * Setup topbar component\n */\n async setupTopbar() {\n if (!this.topbarConfig || Object.keys(this.topbarConfig).length === 0) return;\n\n // Map config to TopNav format\n this.topbar = new TopNav({\n containerId: \"portal-topnav\",\n brandText: this.topbarConfig.brand || this.brand || this.title,\n brandRoute: this.topbarConfig.brandRoute || '/',\n brandIcon: this.topbarConfig.brandIcon || this.brandIcon,\n navItems: this.topbarConfig.leftItems || [],\n rightItems: this.topbarConfig.rightItems || [],\n displayMode: this.topbarConfig.displayMode || 'both',\n showSidebarToggle: this.topbarConfig.showSidebarToggle || false,\n ...this.topbarConfig\n });\n\n await this.topbar.render();\n\n // Legacy support\n this.topnav = this.topbar;\n }\n\n /**\n * Setup page header component\n */\n async setupPageHeader() {\n if (!this.showPageHeader) return;\n\n this.pageHeader = new PageHeader({\n containerId: 'page-header',\n style: this.pageHeaderConfig.style || 'default',\n showIcon: this.pageHeaderConfig.showIcon !== false,\n showDescription: this.pageHeaderConfig.showDescription !== false,\n showBreadcrumbs: this.pageHeaderConfig.showBreadcrumbs || false,\n ...this.pageHeaderConfig\n });\n\n // Render into the portal-content container\n const headerContainer = document.getElementById('page-header');\n if (headerContainer) {\n await this.pageHeader.render(true, headerContainer);\n }\n }\n\n /**\n * Setup portal event handling\n */\n setupPortalEvents() {\n // Handle sidebar toggle via event delegation\n document.addEventListener('click', (event) => {\n if (event.target.closest('[data-action=\"toggle-sidebar\"]')) {\n event.preventDefault();\n this.toggleSidebar();\n }\n });\n\n // Handle responsive changes\n if (window.ResizeObserver) {\n const resizeObserver = new ResizeObserver(() => {\n this.handleResponsive();\n });\n resizeObserver.observe(document.body);\n this._resizeObserver = resizeObserver;\n } else {\n // Fallback for older browsers\n this._resizeHandler = () => this.handleResponsive();\n window.addEventListener('resize', this._resizeHandler);\n }\n\n // Initial responsive setup\n this.handleResponsive();\n }\n\n /**\n * Toggle sidebar state\n */\n toggleSidebar() {\n if (!this.sidebar) return;\n\n const container = document.querySelector('.portal-container');\n const isMobile = this.isMobile();\n\n if (isMobile) {\n container.classList.toggle('hide-sidebar');\n } else {\n container.classList.toggle('collapse-sidebar');\n this.sidebarCollapsed = !this.sidebarCollapsed;\n\n // Save the new state\n this.saveSidebarState(this.sidebarCollapsed);\n }\n\n this.events.emit('sidebar:toggled', {\n collapsed: this.sidebarCollapsed,\n mobile: isMobile\n });\n }\n\n /**\n * Handle responsive layout\n */\n handleResponsive() {\n const container = document.querySelector('.portal-container');\n if (!container) return;\n const isMobile = this.isMobile();\n\n if (isMobile) {\n container.classList.add('mobile-layout');\n if (!container.classList.contains('hide-sidebar')) {\n container.classList.add('hide-sidebar');\n }\n } else {\n container.classList.remove('mobile-layout', 'hide-sidebar');\n }\n\n this.events.emit('responsive:changed', { mobile: isMobile });\n }\n\n getPortalContainer() {\n return document.querySelector('.portal-container');\n }\n\n isMobile() {\n return window.innerWidth < 768;\n }\n\n hasMobileLayout() {\n return this.getPortalContainer().classList.contains('mobile-layout');\n }\n\n /**\n * Override showPage to update navigation\n */\n async showPage(page, query = {}, params = {}, options = {}) {\n const result = await super.showPage(page, query, params, options);\n\n if (this.hasMobileLayout()) {\n this.getPortalContainer().classList.add('hide-sidebar');\n }\n\n if (this.currentPage) {\n this.updateNavigation(this.currentPage);\n }\n\n return result;\n }\n\n /**\n * Update navigation active states\n */\n updateNavigation(page) {\n // Update sidebar active state\n if (this.sidebar && this.sidebar.setActivePage) {\n this.sidebar.setActivePage(page.route);\n }\n\n // Update topbar active state\n if (this.topbar && this.topbar.setActivePage) {\n this.topbar.setActivePage(page.route);\n }\n\n // Update page header\n if (this.pageHeader) {\n this.pageHeader.setPage(page);\n }\n\n this.events.emit('portal:page-changed', { page });\n }\n\n /**\n * Set active user\n */\n setActiveUser(user) {\n this.activeUser = user;\n\n if (this.topbar) {\n this.topbar.setUser(user);\n }\n\n\n this.events.emit('portal:user-changed', { user });\n }\n\n /**\n * Get the active user (for backward compatibility)\n */\n getActiveUser() {\n return this.activeUser;\n }\n\n /**\n * Save sidebar state to localStorage\n */\n saveSidebarState(collapsed) {\n try {\n const key = this.getSidebarStorageKey();\n localStorage.setItem(key, JSON.stringify(collapsed));\n } catch (error) {\n console.warn('Failed to save sidebar state:', error);\n }\n }\n\n /**\n * Load sidebar state from localStorage\n */\n loadSidebarState() {\n try {\n const key = this.getSidebarStorageKey();\n const saved = localStorage.getItem(key);\n return saved !== null ? JSON.parse(saved) : null;\n } catch (error) {\n console.warn('Failed to load sidebar state:', error);\n return null;\n }\n }\n\n /**\n * Get storage key for sidebar state (allows multiple apps on same domain)\n */\n getSidebarStorageKey() {\n // Use app title/name to create unique key\n const appKey = this.title ? this.title.replace(/\\s+/g, '_').toLowerCase() : 'portal_app';\n return `${appKey}_sidebar_collapsed`;\n }\n\n /**\n * Apply saved sidebar state to the UI\n */\n applySidebarState(container = null) {\n if (!container) {\n container = document.querySelector('.portal-container');\n }\n\n if (!container) return;\n\n if (this.sidebarCollapsed) {\n container.classList.add('collapse-sidebar');\n } else {\n container.classList.remove('collapse-sidebar');\n }\n }\n\n /**\n * Clear saved sidebar state\n */\n clearSidebarState() {\n try {\n const key = this.getSidebarStorageKey();\n localStorage.removeItem(key);\n } catch (error) {\n console.warn('Failed to clear sidebar state:', error);\n }\n }\n\n async changePassword() {\n const data = await this.showForm({\n title: \"Change Password\",\n fields: [\n {\n name: 'current_password', type: 'password',\n label: 'Current Password', required: true,\n showToggle: true, // default, can omit\n strengthMeter: true,\n capsLockWarning: true,\n\n },\n {\n name: 'new_password', type: 'password', label: 'New Password', required: true,\n showToggle: true,\n passwordUsage: 'new', // sets autocomplete to 'new-password'\n\n strengthMeter: true,\n capsLockWarning: true,\n attributes: {\n // optional, override autocomplete if needed\n autocomplete: 'new-password'\n }\n },\n {\n name: 'confirm_password', type: 'password', label: 'Confirm Password', required: true,\n showToggle: true,\n passwordUsage: 'new', // sets autocomplete to 'new-password'\n\n strengthMeter: true,\n capsLockWarning: true,\n attributes: {\n // optional, override autocomplete if needed\n // autocomplete: 'new-password'\n }\n }\n ],\n submitLabel: 'Change Password'\n });\n if (data) {\n if (data.new_password === data.confirm_password) {\n // Perform password change logic here\n const resp = await this.activeUser.save(data);\n if (resp.status === 200) {\n this.toast.success('Password changed successfully');\n } else {\n this.toast.error('Failed to change password');\n }\n } else {\n this.toast.error('Passwords do not match');\n }\n }\n }\n\n onPortalAction(action) {\n switch (action.action) {\n case 'logout':\n this.tokenManager.clearTokens();\n this.rest.clearAuth();\n this.setActiveUser(null);\n break;\n case 'profile':\n this.showProfile();\n break;\n case 'change-password':\n this.changePassword();\n break;\n default:\n console.warn(`Unknown portal action: ${action}`);\n }\n }\n\n async showProfile() {\n if (!this.activeUser) {\n this.showError(\"No user is currently logged in\");\n return;\n }\n\n try {\n\n\n // Show profile edit form with automatic model saving\n const result = await Dialog.showModelForm({\n title: 'Edit Profile',\n size: 'lg',\n fileHandling: 'base64',\n model: this.activeUser,\n fields: [\n // Profile Header\n {\n type: 'header',\n text: 'Profile Information',\n level: 4,\n class: 'text-primary mb-3'\n },\n\n // Avatar and Basic Info\n {\n type: 'group',\n columns: { xs: 12, md: 4 },\n title: 'Avatar',\n fields: [\n {\n type: 'image',\n name: 'avatar',\n size: 'lg',\n imageSize: { width: 200, height: 200 },\n placeholder: 'Upload your avatar',\n help: 'Square images work best'\n }\n ]\n },\n\n // Profile Details\n {\n type: 'group',\n columns: { xs: 12, md: 8 },\n title: 'Details',\n fields: [\n {\n type: 'text',\n name: 'display_name',\n label: 'Display Name',\n required: true,\n columns: 12,\n placeholder: 'Enter first name'\n },\n {\n type: 'email',\n name: 'email',\n label: 'Email Address',\n required: true,\n columns: 8,\n placeholder: 'your.email@example.com'\n },\n {\n type: 'tel',\n name: 'phone_number',\n label: 'Phone Number',\n columns: 4,\n placeholder: '(555) 123-4567'\n },\n ]\n },\n\n // Account Settings\n {\n type: 'group',\n columns: 12,\n title: 'Account Settings',\n class: \"pt-3\",\n fields: [\n {\n type: 'select',\n name: 'timezone',\n label: 'Timezone',\n columns: 6,\n options: [\n { value: 'America/New_York', text: 'Eastern Time' },\n { value: 'America/Chicago', text: 'Central Time' },\n { value: 'America/Denver', text: 'Mountain Time' },\n { value: 'America/Los_Angeles', text: 'Pacific Time' },\n { value: 'UTC', text: 'UTC' }\n ]\n },\n {\n type: 'select',\n name: 'language',\n label: 'Language',\n columns: 6,\n options: [\n { value: 'en', text: 'English' },\n { value: 'es', text: 'Spanish' },\n { value: 'fr', text: 'French' },\n { value: 'de', text: 'German' }\n ]\n },\n {\n type: 'switch',\n name: 'email_notifications',\n label: 'Email Notifications',\n columns: 4\n },\n {\n type: 'switch',\n name: 'two_factor_enabled',\n label: 'Two-Factor Authentication',\n columns: 4\n },\n {\n type: 'switch',\n name: 'profile_public',\n label: 'Public Profile',\n columns: 4\n }\n ]\n }\n ],\n submitText: 'Save Profile',\n cancelText: 'Cancel'\n });\n\n if (result && result.success) {\n\n\n // Update active user with new data from model\n // (model should already be updated by save operation)\n\n // Show success message\n this.showSuccess('Profile updated successfully!');\n } else if (result && !result.success) {\n // Error case - already handled by Dialog.showForm\n\n }\n\n } catch (error) {\n console.error('Error showing profile form:', error);\n this.showError('Failed to load profile form');\n }\n }\n\n /**\n * Clean up portal resources\n */\n async destroy() {\n // Clean up event listeners\n // Clear active group\n this.activeGroup = null;\n\n // Clean up portal resources\n if (this._resizeObserver) {\n this._resizeObserver.disconnect();\n }\n if (this._resizeHandler) {\n window.removeEventListener('resize', this._resizeHandler);\n }\n\n // Destroy components using View lifecycle\n if (this.topbar) {\n await this.topbar.destroy();\n this.topbar = null;\n this.topnav = null;\n }\n\n if (this.sidebar) {\n await this.sidebar.destroy();\n this.sidebar = null;\n }\n\n // Call parent destroy\n await super.destroy();\n }\n\n /**\n * Static factory method\n */\n static create(config = {}) {\n return new PortalApp(config);\n }\n}\n","/**\n * MustacheFormatter - Mustache wrapper for MOJO Framework\n * \n * This is now a thin wrapper around Mustache.js since pipe formatting\n * is handled directly in Model.get() and View.get() via MOJOUtils.\n * \n * The wrapper is maintained for backward compatibility and to provide\n * a consistent API for template rendering throughout the framework.\n */\n\nimport mustache from './mustache.js';\nimport dataFormatter from './DataFormatter.js';\n\nclass MustacheFormatter {\n constructor() {\n this.formatter = dataFormatter;\n this.compiledTemplates = new Map();\n }\n\n /**\n * Render template with data\n * Pipes are now handled by Model.get() and View.get() automatically\n * \n * @param {string} template - Mustache template\n * @param {object} data - Data to render (View, Model, or plain object)\n * @param {object} partials - Mustache partials\n * @returns {string} Rendered template\n */\n render(template, data, partials = {}) {\n // Simply pass through to Mustache\n // If data has a get() method, Mustache will use it automatically\n return mustache.render(template, data, partials);\n }\n\n /**\n * Compile template for reuse\n * @param {string} template - Template to compile\n * @returns {object} Compiled template tokens\n */\n compile(template) {\n const compiled = mustache.parse(template);\n this.compiledTemplates.set(template, compiled);\n return compiled;\n }\n\n /**\n * Render with compiled template\n * @param {object} compiled - Compiled template tokens\n * @param {object} data - Data to render\n * @param {object} partials - Mustache partials\n * @returns {string} Rendered template\n */\n renderCompiled(compiled, data, partials = {}) {\n return mustache.render(compiled, data, partials);\n }\n\n /**\n * Clear compiled template cache\n */\n clearCache() {\n this.compiledTemplates.clear();\n mustache.clearCache();\n }\n\n /**\n * Process and cache a template\n * @param {string} key - Cache key\n * @param {string} template - Template to cache\n * @returns {object} Cached template info\n */\n cache(key, template) {\n const compiled = this.compile(template);\n return { key, template, compiled };\n }\n\n /**\n * Get cached template\n * @param {string} key - Cache key\n * @returns {object|null} Cached template info or null\n */\n getCached(key) {\n for (const [template, compiled] of this.compiledTemplates) {\n if (template === key || compiled === key) {\n return { key, template, compiled };\n }\n }\n return null;\n }\n\n /**\n * Register a custom formatter with DataFormatter\n * @param {string} name - Formatter name\n * @param {function} formatter - Formatter function\n * @returns {MustacheFormatter} This instance for chaining\n */\n registerFormatter(name, formatter) {\n this.formatter.register(name, formatter);\n return this;\n }\n\n /**\n * Check if a string contains pipe syntax\n * @param {string} template - Template string to check\n * @returns {boolean} True if contains pipes\n */\n hasPipes(template) {\n return /\\{\\{[{]?[^}|]+\\|[^}]+\\}[}]?\\}/.test(template);\n }\n\n /**\n * Pre-process data with pipe formatters\n * This is now handled automatically by get() methods, but kept for backward compatibility\n * \n * @param {object} data - Data object\n * @param {object} pipes - Object mapping keys to pipe strings\n * @returns {object} Processed data\n */\n processData(data, pipes) {\n const processed = { ...data };\n \n for (const [key, pipeString] of Object.entries(pipes)) {\n // If data has a get method, use it (which will handle pipes)\n if (data && typeof data.get === 'function') {\n processed[key] = data.get(`${key}|${pipeString}`);\n } else {\n // For plain objects, apply formatter directly\n const value = this.getValueFromPath(data, key);\n processed[key] = this.formatter.pipe(value, pipeString);\n }\n }\n \n return processed;\n }\n\n /**\n * Get value from object using dot notation path\n * Kept for backward compatibility, but MOJOUtils.getContextData is preferred\n * \n * @param {object} obj - Source object\n * @param {string} path - Dot notation path\n * @returns {*} Value at path\n */\n getValueFromPath(obj, path) {\n if (!obj || !path) return undefined;\n \n // If obj has a get method, use it\n if (obj && typeof obj.get === 'function') {\n return obj.get(path);\n }\n \n // Otherwise use standard property navigation\n const keys = path.split('.');\n let current = obj;\n \n for (const key of keys) {\n if (current === null || current === undefined) {\n return undefined;\n }\n \n // Handle array index\n if (!isNaN(key) && Array.isArray(current)) {\n current = current[parseInt(key)];\n } else {\n current = current[key];\n }\n }\n \n return current;\n }\n\n /**\n * Process template to handle pipe formatters\n * @deprecated Pipes are now handled by get() methods automatically\n * @param {string} template - Original template\n * @param {object} data - Original data\n * @returns {object} {template: processedTemplate, data: processedData}\n */\n processTemplate(template, data) {\n // For backward compatibility, just return as-is\n // Pipes will be handled by get() methods during Mustache rendering\n return { template, data };\n }\n}\n\n// Create singleton instance\nconst mustacheFormatter = new MustacheFormatter();\n\n// Export both class and instance\nexport { MustacheFormatter };\nexport default mustacheFormatter;","/**\n * MOJO Framework - Core Entry (2.1.0)\n */\n\n// Bundle core CSS\nimport '@core/css/core.css';\nimport '@core/css/portal.css';\nimport '@core/css/table.css';\nimport '@core/css/toast.css';\nimport '@core/css/chat.css';\n\nimport ConsoleSilencer from '@core/utils/ConsoleSilencer.js';\n// Reduce console noise globally: errors only by default (suppress logs, info, and warnings)\nConsoleSilencer.install({ level: 'warn' });\n\n// Version info\nexport {\n VERSION_INFO,\n VERSION,\n VERSION_MAJOR,\n VERSION_MINOR,\n VERSION_REVISION,\n BUILD_TIME\n} from './version.js';\n\n// Core runtime\nexport { default as View } from '@core/View.js';\nexport { default as Page } from '@core/Page.js';\nexport { default as Router } from '@core/Router.js';\nexport { default as Model } from '@core/Model.js';\nexport { default as Collection } from '@core/Collection.js';\nexport { default as Rest } from '@core/Rest.js';\n\n// Core Models - re-export everything from models/\nexport * from '@core/models/AWS.js';\nexport * from '@core/models/Email.js';\nexport * from '@core/models/Files.js';\nexport * from '@core/models/Group.js';\nexport * from '@core/models/Incident.js';\nexport * from '@core/models/Job.js';\nexport * from '@core/models/JobRunner.js';\nexport * from '@core/models/Log.js';\nexport * from '@core/models/Member.js';\nexport * from '@core/models/Metrics.js';\nexport * from '@core/models/Push.js';\nexport * from '@core/models/System.js';\nexport * from '@core/models/Tickets.js';\nexport * from '@core/models/User.js';\n\n// App classes\nexport { default as WebApp } from '@core/WebApp.js';\nexport { default as PortalApp } from '@core/PortalApp.js';\n\n// UI helper\nexport { default as Dialog } from '@core/views/feedback/Dialog.js';\n\n// Selected views (curated for tree-shaking)\nexport { default as TableView } from '@core/views/table/TableView.js';\nexport { default as TableRow } from '@core/views/table/TableRow.js';\nexport { default as TablePage } from '@core/pages/TablePage.js';\nexport { default as ListView } from '@core/views/list/ListView.js';\nexport { default as ListViewItem } from '@core/views/list/ListViewItem.js';\nexport { default as TopNav } from '@core/views/navigation/TopNav.js';\nexport { default as Sidebar } from '@core/views/navigation/Sidebar.js';\nexport { default as TabView } from '@core/views/navigation/TabView.js';\nexport { default as SimpleSearchView } from '@core/views/navigation/SimpleSearchView.js';\nexport { default as DataView } from '@core/views/data/DataView.js';\nexport { default as FormView } from '@core/forms/FormView.js';\nexport { default as FilePreviewView } from '@core/views/data/FilePreviewView.js';\nexport { default as ChatView } from '@core/views/chat/ChatView.js';\nexport { default as ChatMessageView } from '@core/views/chat/ChatMessageView.js';\nexport { default as ChatInputView } from '@core/views/chat/ChatInputView.js';\n\n// Services, utils, mixins\nexport { default as FileUpload } from '@core/services/FileUpload.js';\nexport { default as applyFileDropMixin } from '@core/mixins/FileDropMixin.js';\nexport { default as TokenManager } from '@core/services/TokenManager.js';\nexport { default as ToastService } from '@core/services/ToastService.js';\nexport { default as WebSocketClient } from '@core/services/WebSocketClient.js';\nexport { default as EventDelegate } from '@core/mixins/EventDelegate.js';\nexport { default as EventBus } from '@core/utils/EventBus.js';\nexport { default as dataFormatter } from '@core/utils/DataFormatter.js';\nexport { default as MustacheFormatter } from '@core/utils/MustacheFormatter.js';\nexport { default as MOJOUtils, DataWrapper } from '@core/utils/MOJOUtils.js';\nexport { default as ConsoleSilencer } from '@core/utils/ConsoleSilencer.js';\nexport { installConsoleSilencer } from '@core/utils/ConsoleSilencer.js';\n\n// Additional views\nexport { default as ProgressView } from '@core/views/feedback/ProgressView.js';\nexport { default as ContextMenu } from '@core/views/feedback/ContextMenu.js';\n\n// Names\nexport const FRAMEWORK_NAME = 'MOJO';\nexport const PACKAGE_NAME = 'web-mojo';\n\nexport default {\n FRAMEWORK_NAME,\n PACKAGE_NAME,\n};\n"],"names":["k","v","i","a","b","index","s","j","r","groupKind","e","mustache"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.es.js","sources":["../src/core/utils/ConsoleSilencer.js","../src/core/views/navigation/GroupSearchView.js","../src/core/views/navigation/Sidebar.js","../src/core/views/navigation/PageHeader.js","../src/core/pages/DeniedPage.js","../src/core/pages/NotFoundPage.js","../src/core/PortalApp.js","../src/core/utils/MustacheFormatter.js","../src/index.js"],"sourcesContent":["/**\n * ConsoleSilencer\n * \n * Purpose:\n * - Reduce console noise by filtering out non-critical logs in production.\n * - Keep critical logs (warn, error) by default in production.\n * - Allow runtime override via API, URL params, or localStorage without rebuilding.\n *\n * Usage:\n * import ConsoleSilencer from '@core/utils/ConsoleSilencer.js';\n * ConsoleSilencer.install(); // defaults to 'warn' in production, 'debug' in dev\n *\n * // Optional: set level at install-time\n * ConsoleSilencer.install({ level: 'error' });\n *\n * // Change level at runtime (optionally persist to localStorage)\n * ConsoleSilencer.setLevel('debug', { persist: true });\n *\n * // Temporarily change level around a block\n * ConsoleSilencer.withTemporaryLevel('debug', () => {\n * // noisy diagnostics here\n * });\n *\n * Runtime overrides (no code changes needed):\n * - URL: ?logLevel=debug|info|warn|error|silent\n * also accepts mojoLog and loglevel as param names\n * - localStorage: localStorage.setItem('MOJO_LOG_LEVEL', 'debug')\n *\n * Notes:\n * - This module is side-effect free until install() is called.\n * - Idempotent: calling install() multiple times won't double-wrap console.\n */\n\nconst LEVELS = Object.freeze({\n silent: 0,\n error: 1,\n warn: 2,\n info: 3,\n log: 3, // alias to info\n debug: 4,\n trace: 5,\n all: 5, // alias\n});\n\n// Resolve environment in a bundler/browser-safe way\n// __DEV__ can be injected by bundlers (e.g., Vite define)\nconst isDev = (() => {\n // Vite/ESM: import.meta.env.DEV if available\n try {\n /* eslint-disable-next-line no-undef */\n if (typeof import.meta !== 'undefined' && import.meta && import.meta.env && typeof import.meta.env.DEV !== 'undefined') {\n return !!import.meta.env.DEV;\n }\n } catch {\n // ignore\n }\n\n // Prefer global __DEV__ if present (e.g., defined via bundler define)\n if (typeof globalThis !== 'undefined' && typeof globalThis.__DEV__ !== 'undefined') {\n try {\n return !!globalThis.__DEV__;\n } catch {\n // fall through if __DEV__ is not directly evaluable\n }\n }\n\n // Fallback detection (best effort)\n const hasProcess = typeof process !== 'undefined' && process && typeof process.env === 'object';\n if (hasProcess && typeof process.env.NODE_ENV === 'string') {\n return process.env.NODE_ENV !== 'production';\n }\n // Default conservative behavior: assume production if unknown\n return false;\n})();\n\nconst isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined';\nconst GLOBAL = typeof globalThis !== 'undefined' ? globalThis : (typeof window !== 'undefined' ? window : global);\n\n// Capture the original console just once\nconst ORIGINAL_CONSOLE = GLOBAL.console || {};\nconst ORIGINALS = {};\nlet INSTALLED = false;\nlet CURRENT_LEVEL = null;\n\n// Default levels\nconst DEFAULT_DEV_LEVEL = 'debug';\nconst DEFAULT_PROD_LEVEL = 'warn'; // keep warn + error by default\n\n// Helper: normalize/parse level\nfunction parseLevel(level) {\n if (typeof level === 'number') {\n // Clamp to bounds\n const min = LEVELS.silent;\n const max = LEVELS.trace;\n return Math.min(Math.max(level, min), max);\n }\n if (typeof level === 'string') {\n const key = level.toLowerCase();\n if (Object.prototype.hasOwnProperty.call(LEVELS, key)) {\n return LEVELS[key];\n }\n }\n return null;\n}\n\n// Helper: detect override via URLSearchParams\nfunction getUrlLogLevel() {\n if (!isBrowser || typeof location === 'undefined' || !location.search) return null;\n try {\n const params = new URLSearchParams(location.search);\n const keys = ['logLevel', 'loglevel', 'mojoLog'];\n for (const k of keys) {\n const v = params.get(k);\n if (v != null) {\n const parsed = parseLevel(v);\n if (parsed !== null) return parsed;\n }\n }\n } catch {\n // ignore\n }\n return null;\n}\n\n// Helper: detect override via localStorage\nfunction getStoredLogLevel() {\n if (!isBrowser || !('localStorage' in GLOBAL)) return null;\n try {\n const v = GLOBAL.localStorage.getItem('MOJO_LOG_LEVEL');\n if (v != null) {\n const parsed = parseLevel(v);\n if (parsed !== null) return parsed;\n }\n } catch {\n // ignore storage errors\n }\n return null;\n}\n\nfunction storeLogLevel(levelNumberOrName) {\n if (!isBrowser || !('localStorage' in GLOBAL)) return;\n try {\n const key = typeof levelNumberOrName === 'string'\n ? levelNumberOrName\n : levelNumberOrName === null\n ? null\n : Object.entries(LEVELS).find(([, num]) => num === levelNumberOrName)?.[0] ?? null;\n if (key) {\n GLOBAL.localStorage.setItem('MOJO_LOG_LEVEL', key);\n } else {\n GLOBAL.localStorage.removeItem('MOJO_LOG_LEVEL');\n }\n } catch {\n // ignore storage errors\n }\n}\n\n// Build a wrapped method that checks the current level before calling through\nfunction makeWrapper(methodName, methodLevel) {\n const original = ORIGINALS[methodName] || ORIGINAL_CONSOLE[methodName] || (() => {});\n return function wrappedConsoleMethod(...args) {\n // If the method is allowed at the current level, call through\n if (CURRENT_LEVEL >= methodLevel) {\n return original.apply(ORIGINAL_CONSOLE, args);\n }\n // Otherwise, noop\n return undefined;\n };\n}\n\n// Special wrapper for assert: only logs when assertion fails\nfunction makeAssertWrapper() {\n const original = ORIGINALS.assert || ORIGINAL_CONSOLE.assert || (() => {});\n return function wrappedAssert(condition, ...args) {\n // Only logs when condition is falsy; treat failed assert like error-level\n if (!condition) {\n if (CURRENT_LEVEL >= LEVELS.error) {\n return original.apply(ORIGINAL_CONSOLE, [condition, ...args]);\n }\n return undefined;\n }\n // When assertion passes, no-op\n return undefined;\n };\n}\n\nfunction determineInitialLevel(explicitLevel) {\n // 1) Explicit install option\n const explicit = parseLevel(explicitLevel);\n if (explicit !== null) return explicit;\n\n // 2) URL override\n const urlLevel = getUrlLogLevel();\n if (urlLevel !== null) return urlLevel;\n\n // 3) localStorage override\n const storedLevel = getStoredLogLevel();\n if (storedLevel !== null) return storedLevel;\n\n // 4) Environment default\n return parseLevel(isDev ? DEFAULT_DEV_LEVEL : DEFAULT_PROD_LEVEL);\n}\n\n// Construct a patched console that respects CURRENT_LEVEL\nfunction buildPatchedConsole() {\n const patched = { ...ORIGINAL_CONSOLE };\n\n // Save originals once\n const methodLevels = {\n // Critical\n error: LEVELS.error,\n warn: LEVELS.warn,\n\n // Informational\n info: LEVELS.info,\n log: LEVELS.info,\n dir: LEVELS.info,\n table: LEVELS.info,\n\n // Verbose / Debug\n debug: LEVELS.debug,\n group: LEVELS.debug,\n groupCollapsed: LEVELS.debug,\n groupEnd: LEVELS.debug,\n time: LEVELS.debug,\n timeEnd: LEVELS.debug,\n timeLog: LEVELS.debug,\n trace: LEVELS.trace,\n };\n\n // Capture originals and build wrappers\n for (const name of Object.keys(methodLevels)) {\n ORIGINALS[name] = ORIGINAL_CONSOLE[name] || (() => {});\n patched[name] = makeWrapper(name, methodLevels[name]);\n }\n\n // Special-case assert\n ORIGINALS.assert = ORIGINAL_CONSOLE.assert || (() => {});\n patched.assert = makeAssertWrapper();\n\n // Preserve any other console methods as-is (clear, profile, count, etc.)\n return patched;\n}\n\nconst ConsoleSilencer = {\n // Install the silencer (idempotent)\n install(options = {}) {\n if (INSTALLED) {\n // Already installed; update level if provided\n if (options && typeof options.level !== 'undefined') {\n this.setLevel(options.level, { persist: !!options.persist });\n }\n return this;\n }\n\n if (!GLOBAL || !ORIGINAL_CONSOLE) {\n // No console available; nothing to do\n INSTALLED = true; // Prevent re-entry\n return this;\n }\n\n CURRENT_LEVEL = determineInitialLevel(options.level);\n\n const patched = buildPatchedConsole();\n // Replace the global console\n GLOBAL.console = patched;\n\n INSTALLED = true;\n\n // Expose for quick manual access if desired\n GLOBAL.MOJOConsoleSilencer = this;\n\n return this;\n },\n\n // Uninstall and restore the original console\n uninstall() {\n if (!INSTALLED) return this;\n\n try {\n GLOBAL.console = ORIGINAL_CONSOLE;\n } catch {\n // ignore\n }\n INSTALLED = false;\n return this;\n },\n\n // Set current level at runtime; accepts string or number\n // levels: 'silent' | 'error' | 'warn' | 'info' | 'debug' | 'trace'\n setLevel(level, { persist = false } = {}) {\n const parsed = parseLevel(level);\n if (parsed === null) return this; // ignore invalid level\n CURRENT_LEVEL = parsed;\n if (persist) {\n storeLogLevel(level);\n }\n return this;\n },\n\n // Get the current numeric level\n getLevel() {\n return CURRENT_LEVEL;\n },\n\n // Get the current level name (best-effort)\n getLevelName() {\n const entry = Object.entries(LEVELS).find(([, num]) => num === CURRENT_LEVEL);\n return entry ? entry[0] : null;\n },\n\n // Convenience helpers\n criticalOnly({ persist = false } = {}) {\n return this.setLevel('warn', { persist });\n },\n\n errorsOnly({ persist = false } = {}) {\n return this.setLevel('error', { persist });\n },\n\n silent({ persist = false } = {}) {\n return this.setLevel('silent', { persist });\n },\n\n verbose({ persist = false } = {}) {\n return this.setLevel(isDev ? 'debug' : 'info', { persist });\n },\n\n allowAll({ persist = false } = {}) {\n return this.setLevel('trace', { persist });\n },\n\n // Run a block with a temporary level, then restore\n withTemporaryLevel(level, fn) {\n const prev = CURRENT_LEVEL;\n const parsed = parseLevel(level);\n if (parsed === null || typeof fn !== 'function') return fn?.();\n CURRENT_LEVEL = parsed;\n try {\n return fn();\n } finally {\n CURRENT_LEVEL = prev;\n }\n },\n\n // Expose levels map for consumers\n LEVELS,\n};\n\n// Optional: convenience named export alias\nexport default ConsoleSilencer;\nexport const installConsoleSilencer = (options) => ConsoleSilencer.install(options);","/**\n * GroupSearchView - Hierarchical tree-view search component\n * Extends SimpleSearchView to support parent/child relationships\n * Displays items in a tree structure based on parent property\n */\n\nimport SimpleSearchView from './SimpleSearchView.js';\n\nclass GroupSearchView extends SimpleSearchView {\n constructor(options = {}) {\n super({\n ...options,\n className: `group-search-view ${options.className || ''}`.trim()\n });\n\n // Tree-specific configuration\n this.showKind = options.showKind !== undefined ? options.showKind : true;\n this.parentField = options.parentField || 'parent';\n this.kindField = options.kindField || 'kind';\n this.treeData = []; // Processed hierarchical data\n this.flattenedItems = []; // Flattened tree for display\n \n // Visual customization\n this.showLines = options.showLines !== undefined ? options.showLines : true;\n }\n\n /**\n * Build tree hierarchy from flat list\n */\n buildTreeHierarchy(items) {\n if (!items || items.length === 0) {\n return [];\n }\n\n // Create a map of items by ID for quick lookup\n const itemsById = new Map();\n \n // First pass: add all items and extract parent objects\n items.forEach(item => {\n if (!itemsById.has(item.id)) {\n itemsById.set(item.id, {\n ...item,\n children: [],\n level: 0,\n hasChildren: false\n });\n }\n \n // If this item has a parent object, add the parent too\n const parentObj = item[this.parentField];\n if (parentObj && parentObj.id && !itemsById.has(parentObj.id)) {\n itemsById.set(parentObj.id, {\n ...parentObj,\n children: [],\n level: 0,\n hasChildren: false\n });\n }\n });\n\n const rootItems = [];\n\n // Build parent-child relationships\n itemsById.forEach((treeItem, itemId) => {\n const originalItem = items.find(i => i.id === itemId) || treeItem;\n const parentId = originalItem[this.parentField]?.id;\n\n if (parentId && itemsById.has(parentId)) {\n const parent = itemsById.get(parentId);\n parent.children.push(treeItem);\n parent.hasChildren = true;\n } else {\n rootItems.push(treeItem);\n }\n });\n\n // Calculate levels recursively\n const calculateLevels = (nodes, level = 0) => {\n nodes.forEach(node => {\n node.level = level;\n if (node.children.length > 0) {\n node.children.sort((a, b) => (a.name || '').localeCompare(b.name || ''));\n calculateLevels(node.children, level + 1);\n }\n });\n };\n\n rootItems.sort((a, b) => (a.name || '').localeCompare(b.name || ''));\n calculateLevels(rootItems);\n\n return rootItems;\n }\n\n /**\n * Flatten tree structure for rendering\n * Tracks ancestor \"last child\" flags for proper line rendering\n */\n flattenTree(nodes, result = [], ancestorLastFlags = []) {\n nodes.forEach((node, index) => {\n node._isLastChild = index === nodes.length - 1;\n node._ancestorLastFlags = [...ancestorLastFlags];\n \n // Check if this node is the last descendant in its branch\n // (all ancestors are last children AND this node is last child with no children)\n const allAncestorsLast = ancestorLastFlags.every(flag => flag);\n node._isLastDescendant = allAncestorsLast && node._isLastChild && \n (!node.children || node.children.length === 0);\n \n result.push(node);\n \n if (node.children && node.children.length > 0) {\n const newFlags = [...ancestorLastFlags, node._isLastChild];\n this.flattenTree(node.children, result, newFlags);\n }\n });\n \n return result;\n }\n\n /**\n * Second pass: compute which vertical lines should continue for each item\n * \n * Vertical line at segment s shows if there are more siblings coming at level s+1\n * We need to look ahead until we find an item at level s+1 or shallower\n */\n computeVerticalLines(flatList) {\n for (let i = 0; i < flatList.length; i++) {\n const item = flatList[i];\n item._continueVertical = [];\n \n for (let s = 0; s < item.level; s++) {\n // Look ahead to find next item at level s+1 or shallower\n let foundSibling = false;\n for (let j = i + 1; j < flatList.length; j++) {\n const futureItem = flatList[j];\n if (futureItem.level === s + 1) {\n // Found a sibling at this level - vertical should continue\n foundSibling = true;\n break;\n } else if (futureItem.level <= s) {\n // Went back to ancestor level or shallower - no more siblings\n break;\n }\n // Keep searching if futureItem.level > s+1 (still in deeper subtree)\n }\n item._continueVertical[s] = foundSibling;\n }\n }\n }\n\n /**\n * Update filtered items with tree structure\n */\n updateFilteredItems() {\n if (!this.collection) {\n this.filteredItems = [];\n this.treeData = [];\n this.flattenedItems = [];\n return;\n }\n\n // Server-side filtering is handled in performSearch() (from parent class)\n const items = this.collection.toJSON();\n this.treeData = this.buildTreeHierarchy(items);\n this.flattenedItems = this.flattenTree(this.treeData);\n \n // Second pass: compute vertical line continuation\n this.computeVerticalLines(this.flattenedItems);\n \n // Set filteredItems to flattened tree for parent class compatibility\n this.filteredItems = this.flattenedItems;\n\n this.updateResultsView();\n }\n\n /**\n * Get tree-specific item template\n */\n getDefaultItemTemplate() {\n return `\n <div class=\"tree-item-content\">\n <div class=\"tree-item-name\">{{name}}</div>\n {{#showKind}}\n <div class=\"tree-item-kind\">{{kind}}</div>\n {{/showKind}}\n </div>\n `;\n }\n\n /**\n * Process item template with tree structure\n */\n processItemTemplate(item) {\n // Process the base template\n let content = this.itemTemplate;\n content = content.replace(/\\{\\{(\\w+)\\}\\}/g, (match, prop) => {\n if (prop === 'showKind') {\n return this.showKind ? 'true' : '';\n }\n return this.getNestedValue(item, prop) || '';\n });\n\n // Handle conditional sections for kind\n if (this.showKind) {\n content = content.replace(/\\{\\{#showKind\\}\\}(.*?)\\{\\{\\/showKind\\}\\}/gs, '$1');\n } else {\n content = content.replace(/\\{\\{#showKind\\}\\}.*?\\{\\{\\/showKind\\}\\}/gs, '');\n }\n\n // Build tree line segments\n // For an item at level N, we need N segments (one for each ancestor level)\n let lineSegments = '';\n if (this.showLines && item.level > 0) {\n for (let i = 0; i < item.level; i++) {\n const isLastSegment = (i === item.level - 1);\n \n if (isLastSegment) {\n // This segment connects directly to this item\n // Use _isLastChild to determine if this is └ or ├\n const segClass = item._isLastChild ? 'tree-seg tree-seg-last' : 'tree-seg tree-seg-mid';\n lineSegments += `<span class=\"${segClass}\"></span>`;\n } else {\n // Ancestor segment - vertical line continues if next item is deeper than this level\n const continueVertical = item._continueVertical && item._continueVertical[i];\n if (continueVertical) {\n lineSegments += `<span class=\"tree-seg tree-seg-vert\"></span>`;\n } else {\n lineSegments += `<span class=\"tree-seg\"></span>`;\n }\n }\n }\n }\n\n // Classes for the wrapper\n const hasChildren = item.hasChildren ? ' has-children' : '';\n const isLastChild = item._isLastChild ? ' is-last-child' : '';\n\n // Wrap in tree structure\n return `\n <div class=\"tree-item-wrapper${hasChildren}${isLastChild}\" data-tree-level=\"${item.level}\">\n <div class=\"tree-lines\">\n ${lineSegments}\n </div>\n <div class=\"tree-item-body flex-grow-1\">\n ${content}\n </div>\n </div>\n `;\n }\n\n /**\n * Get all root items\n */\n getRootItems() {\n return this.treeData;\n }\n\n /**\n * Get children of a specific node\n */\n getNodeChildren(nodeId) {\n const findNode = (nodes, targetId) => {\n for (const node of nodes) {\n if (node.id === targetId) {\n return node.children;\n }\n if (node.children.length > 0) {\n const found = findNode(node.children, targetId);\n if (found) return found;\n }\n }\n return null;\n };\n\n return findNode(this.treeData, nodeId) || [];\n }\n}\n\nexport default GroupSearchView;\n","/**\n * Sidebar - Simple sidebar navigation component for MOJO framework\n * Provides easy menu switching and dynamic configuration\n */\n\nimport View from '@core/View.js';\nimport GroupSearchView from './GroupSearchView.js';\nimport {GroupList, Group} from '@core/models/Group.js';\nimport Dialog from '@core/views/feedback/Dialog.js';\n\n\nclass Sidebar extends View {\n constructor(options = {}) {\n super({\n tagName: 'nav',\n className: 'sidebar',\n id: 'sidebar',\n ...options\n });\n\n this.menus = new Map();\n this.activeMenuName = null;\n this.currentRoute = null;\n this.showToggle = options.showToggle; // Default to true\n this.isCollapsed = false;\n this.sidebarTheme = options.theme || 'sidebar-light';\n this.customView = null;\n if (this.options.groupHeader) this.groupHeader = this.options.groupHeader;\n\n // Group selector configuration\n // 'inline' (default) - replaces sidebar view\n // 'dialog' - opens in a modal dialog like TopNav\n this.groupSelectorMode = options.groupSelectorMode || 'inline';\n this.groupSelectorDialog = null;\n // Apply sidebar theme\n if (this.sidebarTheme) {\n this.addClass(this.sidebarTheme);\n }\n\n // Initialize menus\n this.initializeMenus(options);\n\n // Setup route change listeners like TopNav\n this.setupRouteListeners();\n\n // Auto-collapse on mobile if specified\n if (options.autoCollapseMobile !== false) {\n this.setupResponsiveBehavior();\n }\n }\n\n groupHeader = `\n {{#group.parent}}\n <div class=\"sidebar-parent-bar\" data-action=\"select-group-parent\">\n <div class=\"parent-info\">\n <span class=\"parent-label\">{{group.parent.kind}}:</span>\n <span class=\"parent-name collapsed-hidden\">{{group.parent.name}}</span>\n </div>\n <i class=\"bi bi-chevron-down parent-expand collapsed-hidden\"></i>\n </div>\n {{/group.parent}}\n <div class=\"sidebar-selected-group-row\" data-action=\"show-group-search\">\n <div class=\"selected-group-info\">\n <div class='selected-group-name collapsed-hidden'>{{group.name}}</div>\n <div class='selected-group-meta collapsed-hidden'>\n <span class=\"selected-group-kind\">{{group.kind}}</span>\n </div>\n </div>\n <i class=\"bi bi-chevron-down selected-group-chevron collapsed-hidden\"></i>\n </div>\n `;\n\n /**\n * Initialize sidebar and auto-switch to correct menu based on current route\n */\n async onInit() {\n await super.onInit();\n\n // Get current route from router\n const app = this.getApp();\n const router = app?.router;\n\n if (router) {\n const currentPath = router.getCurrentPath();\n if (currentPath) {\n this.autoSwitchToMenuForRoute(currentPath);\n }\n }\n\n // Initialize tooltips for nav items\n this.initializeTooltips();\n\n this.searchView = new GroupSearchView({\n noAppend: true,\n showExitButton: true,\n headerText: \"Select Group\",\n containerId: \"sidebar-search-container\",\n Collection: GroupList,\n itemTemplate: `\n <div class=\"p-3 border-bottom\">\n <div class=\"fw-semibold text-dark\">{{name}}</div>\n <small class=\"text-muted\">#{{id}} {{kind}}</small>\n </div>\n `\n });\n this.addChild(this.searchView);\n this.searchView.on(\"item:selected\", (evt) => {\n console.log(evt);\n this.getApp().setActiveGroup(evt.model);\n });\n this.searchView.on(\"exit\", (item) => {\n console.log(item);\n this.hideGroupSearch();\n });\n }\n\n showGroupSearch() {\n if (this.groupSelectorMode === 'dialog') {\n this.showGroupSearchDialog();\n } else {\n // Inline mode (default)\n this.setClass('sidebar');\n this.showSearch = true;\n this.render();\n }\n }\n\n hideGroupSearch() {\n if (this.groupSelectorMode === 'dialog') {\n if (this.groupSelectorDialog) {\n this.groupSelectorDialog.hide();\n }\n } else {\n // Inline mode\n this.setClass('sidebar');\n this.showSearch = false;\n this.render();\n }\n }\n\n onActionShowGroupSearch() {\n this.showGroupSearch();\n }\n\n async onActionSelectGroupParent() {\n // select-group-parent\n const group = this.getApp().activeGroup;\n const result = await Dialog.confirm(`Are you sure you want to navigate to the '${group.get(\"parent.name\")}'?`);\n if (result) {\n this.getApp().showLoading();\n let parent = new Group({id: group.get(\"parent.id\")});\n await parent.fetch();\n this.getApp().setActiveGroup(parent);\n this.getApp().hideLoading();\n }\n }\n\n /**\n * Show group selector in a dialog (like TopNav)\n */\n async showGroupSearchDialog() {\n // Create or reuse collection instance (like GroupSelectorButton does)\n const collection = new GroupList();\n\n // Create GroupSearchView instance matching GroupSelectorButton pattern\n const searchView = new GroupSearchView({\n Collection: GroupList,\n collection: collection, // Pass the collection instance\n searchFields: ['name'],\n headerText: null,\n searchPlaceholder: \"Search groups...\",\n headerIcon: null,\n maxHeight: Math.min(600, window.innerHeight - 200),\n showExitButton: false,\n showKind: true, // Show kind badges (default: true)\n parentField: 'parent', // Field containing parent object\n kindField: 'kind', // Field containing kind/type\n autoExpandRoot: true, // Auto-expand root items (default: true)\n autoExpandAll: false, // Auto-expand all nodes (default: false)\n indentSize: 20, // Pixels per level (default: 20)\n showLines: true,\n });\n\n // Create dialog\n this.groupSelectorDialog = new Dialog({\n body: searchView,\n size: 'md',\n header: null,\n noBodyPadding: true,\n scrollable: false,\n buttons: [],\n closeButton: true\n });\n\n // Listen for item selection\n searchView.on('item:selected', (evt) => {\n console.log(evt);\n this.getApp().setActiveGroup(evt.model);\n if (this.groupSelectorDialog) {\n this.groupSelectorDialog.hide();\n }\n });\n\n // Clean up dialog reference when closed\n this.groupSelectorDialog.on('hidden', () => {\n this.groupSelectorDialog.destroy();\n this.groupSelectorDialog = null;\n });\n\n // Render and show the dialog\n await this.groupSelectorDialog.render(true, document.body);\n this.groupSelectorDialog.show();\n }\n\n /**\n * Find and switch to the menu that contains the given route\n */\n autoSwitchToMenuForRoute(route) {\n // Search through all menus to find one that contains this route\n for (const [menuName, menuConfig] of this.menus) {\n if (menuConfig.groupKind && !this.getApp().activeGroup)\n continue;\n if (this.menuContainsRoute(menuConfig, route)) {\n // Switch to this menu\n this._setActiveMenu(menuName);\n this.currentRoute = route;\n\n // Clear all active states and set new active item\n this.clearAllActiveStates();\n this.setActiveItemByRoute(route);\n\n // Re-render to show changes\n this.render();\n\n console.log(`Auto-switched to menu '${menuName}' for route '${route}'`);\n\n // Emit event for any listeners\n this.emit('menu-auto-switched', {\n menuName,\n route,\n config: menuConfig,\n sidebar: this\n });\n\n return true;\n }\n }\n\n return false; // No menu found for this route\n }\n\n /**\n * Clear active state from all menu items in all menus\n */\n clearAllActiveStates() {\n for (const [menuName, menuConfig] of this.menus) {\n for (const item of menuConfig.items || []) {\n item.active = false;\n if (item.children) {\n for (const child of item.children) {\n child.active = false;\n }\n }\n }\n }\n }\n\n /**\n * Set active state for item matching the given route\n */\n setActiveItemByRoute(route) {\n const normalizeRoute = (r) => {\n if (!r) return '/';\n // Decode URL-encoded characters (like %2F -> /)\n const decoded = decodeURIComponent(r);\n return decoded.startsWith('/') ? decoded : `/${decoded}`;\n };\n\n const targetRoute = normalizeRoute(route);\n\n // Search through all menus\n for (const [menuName, menuConfig] of this.menus) {\n if (menuConfig.groupKind && !this.getApp().activeGroup)\n continue;\n for (const item of menuConfig.items || []) {\n // Check main item\n if (item.route) {\n const itemRoute = normalizeRoute(item.route);\n if (this.routesMatch(targetRoute, itemRoute)) {\n item.active = true;\n this.activeMenuItem = item;\n return true;\n }\n }\n\n // Check children\n if (item.children) {\n for (const child of item.children) {\n if (child.route) {\n const childRoute = normalizeRoute(child.route);\n if (this.routesMatch(targetRoute, childRoute)) {\n child.active = true;\n item.active = true; // Parent also active\n return true;\n }\n }\n }\n }\n }\n }\n\n return false;\n }\n\n /**\n * Check if a menu contains a specific route in its items or children\n */\n menuContainsRoute(menuConfig, route) {\n const normalizeRoute = (r) => {\n if (!r) return '/';\n // Decode URL-encoded characters (like %2F -> /)\n const decoded = decodeURIComponent(r);\n return decoded.startsWith('/') ? decoded : `/${decoded}`;\n };\n\n const targetRoute = normalizeRoute(route);\n\n // Check each item in the menu\n for (const item of menuConfig.items || []) {\n // Check main item\n if (item.route) {\n const itemRoute = normalizeRoute(item.route);\n if (this.routesMatch(targetRoute, itemRoute)) {\n return true;\n }\n }\n\n // Check children\n if (item.children) {\n for (const child of item.children) {\n if (child.route) {\n const childRoute = normalizeRoute(child.route);\n if (this.routesMatch(targetRoute, childRoute)) {\n return true;\n }\n }\n }\n }\n }\n\n return false;\n }\n\n /**\n * Check if two routes match (using same logic as isItemActive)\n */\n routesMatch(currentRoute, itemRoute) {\n return this.getApp().router.doRoutesMatch(currentRoute, itemRoute);\n }\n\n getTemplate() {\n if (this.customView) {\n return '<div class=\"sidebar-container\" id=\"sidebar-custom-view-container\"></div>';\n }\n if (this.showSearch) return this.getSearchTemplate();\n return this.getMenuTemplate();\n }\n\n getSearchTemplate() {\n return `\n <div class=\"sidebar-container\" id=\"sidebar-search-container\">\n </div>\n `;\n }\n\n getMenuTemplate() {\n return `\n <div class=\"sidebar-container\">\n {{#data.currentMenu}}\n <!-- Header -->\n {{#header}}\n <div class=\"sidebar-header\">\n {{{header}}}\n {{#showToggle}}\n <button class=\"sidebar-toggle\" data-action=\"toggle-sidebar\"\n aria-label=\"Toggle Sidebar\">\n <i class=\"bi bi-chevron-left toggle-icon\"></i>\n <i class=\"bi bi-chevron-right toggle-icon\"></i>\n </button>\n {{/showToggle}}\n </div>\n {{/header}}\n\n <!-- Navigation Items -->\n <div class=\"sidebar-body\">\n <ul class=\"nav nav-pills flex-column sidebar-nav\" id=\"sidebar-nav-menu\">\n {{#items}}\n {{>nav-item}}\n {{/items}}\n </ul>\n </div>\n\n <!-- Footer -->\n {{#footer}}\n <div class=\"sidebar-footer\">\n {{{footer}}}\n </div>\n {{/footer}}\n {{/data.currentMenu}}\n\n {{^data.currentMenu}}\n <div class=\"sidebar-empty\">\n <p class=\"text-danger text-center\">No menu configured</p>\n </div>\n {{/data.currentMenu}}\n </div>\n `;\n }\n\n /**\n * Get template partials for rendering\n */\n getPartials() {\n return {\n 'nav-item': `\n {{#isDivider}}\n {{>nav-divider}}\n {{/isDivider}}\n {{#isSpacer}}\n {{>nav-spacer}}\n {{/isSpacer}}\n {{#isLabel}}\n {{>nav-label}}\n {{/isLabel}}\n\n {{^isDivider}}\n {{^isSpacer}}\n {{^isLabel}}\n <li class=\"nav-item\">\n {{#hasChildren}}\n <!-- Item with submenu -->\n <a class=\"nav-link {{#active}}active{{/active}} has-children collapsed\"\n data-bs-toggle=\"collapse\"\n href=\"#collapse-{{id}}\"\n role=\"button\"\n aria-expanded=\"{{#active}}true{{/active}}{{^active}}false{{/active}}\"\n data-action=\"toggle-submenu\">\n {{#icon}}<i class=\"{{icon}} me-2\"></i>{{/icon}}\n <span class=\"nav-text\">{{text}}</span>\n {{#badge}}\n <span class=\"{{badge.class}} ms-auto\">{{badge.text}}</span>\n {{/badge}}\n <i class=\"bi bi-chevron-down nav-arrow ms-auto\"></i>\n </a>\n <div class=\"collapse {{#active}}show{{/active}}\" id=\"collapse-{{id}}\" data-bs-parent=\"#sidebar-nav-menu\">\n <ul class=\"nav flex-column nav-submenu\">\n {{#children}}\n <li class=\"nav-item\">\n <a class=\"nav-link {{#active}}active{{/active}}\"\n {{#action}}data-action=\"{{action}}\"{{/action}}\n {{#href}}href=\"{{href}}\"{{/href}}>\n {{#icon}}<i class=\"{{icon}} me-2\"></i>{{/icon}}\n <span class=\"nav-text\">{{text}}</span>\n {{#badge}}\n <span class=\"{{badge.class}} ms-auto\">{{badge.text}}</span>\n {{/badge}}\n </a>\n </li>\n {{/children}}\n </ul>\n </div>\n {{/hasChildren}}\n {{^hasChildren}}\n <!-- Simple item -->\n <a class=\"nav-link {{#active}}active{{/active}} {{#disabled}}disabled{{/disabled}}\"\n {{#action}}{{^disabled}}data-action=\"{{action}}\"{{/disabled}}{{/action}}\n {{#href}}{{^disabled}}href=\"{{href}}\"{{/disabled}}{{/href}}>\n {{#icon}}<i class=\"{{icon}} me-2\"></i>{{/icon}}\n <span class=\"nav-text\">{{text}}</span>\n {{#badge}}\n <span class=\"{{badge.class}} ms-auto\">{{badge.text}}</span>\n {{/badge}}\n </a>\n {{/hasChildren}}\n </li>\n {{/isLabel}}\n {{/isSpacer}}\n {{/isDivider}}\n `,\n 'nav-divider': `\n <li class=\"nav-divider-item\">\n <hr class=\"nav-divider-line\">\n </li>\n `,\n 'nav-spacer': `\n <li class=\"nav-spacer-item\"></li>\n `,\n 'nav-label': `\n <li class=\"nav-item {{className}}\">\n <div class=\"nav-text px-3\">{{text}}</div>\n </li>\n `\n };\n }\n\n getGroupHeader() {\n return this.groupHeader;\n }\n\n /**\n * Add a menu configuration\n */\n addMenu(name, config) {\n if (config.groupKind && !config.header) {\n config.header = this.getGroupHeader();\n }\n\n this.menus.set(name, {\n name,\n groupKind: config.groupKind || null,\n header: config.header || null,\n footer: config.footer || null,\n items: config.items || [],\n data: config.data || {},\n className: config.className || \"sidebar sidebar-dark\"\n });\n\n\n // Set as active if it's the first menu\n if (!this.activeMenuName) {\n this._setActiveMenu(name);\n }\n\n return this;\n }\n\n _setActiveMenu(name) {\n this.showSearch = false;\n this.activeMenuName = name;\n const config = this.getCurrentMenuConfig();\n if (config.className) {\n this.setClass(config.className);\n } else {\n this.setClass('sidebar');\n }\n }\n\n /**\n * Set the active menu\n */\n async setActiveMenu(name) {\n if (!this.menus.has(name)) {\n console.warn(`Menu '${name}' not found`);\n return this;\n }\n\n const menuConfig = this.menus.get(name);\n\n if (menuConfig.groupKind) {\n this.lastGroupMenu = menuConfig;\n // Handle group kind logic here\n if (!this.getApp().activeGroup) {\n this.showGroupSearch();\n return;\n }\n }\n\n this._setActiveMenu(name);\n await this.render();\n // Emit event\n this.emit('menu-changed', {\n menuName: name,\n config: menuConfig,\n sidebar: this\n });\n\n return this;\n }\n\n getGroupMenu(group) {\n if (!group) {\n console.warn('No group provided');\n return null;\n }\n // Find menu by group.kind\n let targetMenu = this.lastGroupMenu;\n let anyGroupMenu = null;\n if (group._.kind) {\n for (const [menuName, menuConfig] of this.menus) {\n // Check if groupKind matches\n const matches = this._groupKindMatches(menuConfig.groupKind, group._.kind);\n\n if (matches) {\n targetMenu = menuConfig;\n break;\n } else if (menuConfig.groupKind === 'any') {\n anyGroupMenu = menuConfig;\n }\n }\n }\n\n if (!targetMenu) {\n return anyGroupMenu;\n }\n return targetMenu;\n }\n\n /**\n * Check if a groupKind matches the group's kind\n * Supports both single string and array of strings\n * @param {string|string[]} groupKind - Single kind or array of kinds\n * @param {string} kind - The group's kind to match\n * @returns {boolean} True if matches\n */\n _groupKindMatches(groupKind, kind) {\n if (!groupKind || !kind) return false;\n\n // Handle array of kinds\n if (Array.isArray(groupKind)) {\n return groupKind.includes(kind);\n }\n\n // Handle single kind string\n return groupKind === kind;\n }\n\n showMenuForGroup(group) {\n if (!group) {\n console.warn('No group provided');\n return;\n }\n // Find menu by group.kind\n let targetMenu = this.getGroupMenu(group);\n\n if (!targetMenu) {\n console.warn(`No menu found for group kind: ${group.kind}`);\n return;\n }\n this._setActiveMenu(targetMenu.name);\n this.render();\n // Emit event\n this.emit('menu-changed', {\n menuName: targetMenu.name,\n config: targetMenu,\n sidebar: this\n });\n return this;\n }\n\n /**\n * Get menu configuration\n */\n getMenuConfig(name) {\n return this.menus.get(name) || null;\n }\n\n /**\n * Get current active menu configuration\n */\n getCurrentMenuConfig() {\n return this.activeMenuName ? this.menus.get(this.activeMenuName) : null;\n }\n\n /**\n * Update menu configuration\n */\n updateMenu(name, updates) {\n const menu = this.menus.get(name);\n if (!menu) {\n console.warn(`Menu '${name}' not found`);\n return this;\n }\n\n // Deep merge updates\n Object.assign(menu, updates);\n\n // Re-render if this is the active menu\n if (this.activeMenuName === name) {\n this.render();\n }\n\n return this;\n }\n\n /**\n * Remove a menu\n */\n removeMenu(name) {\n this.menus.delete(name);\n\n // If this was the active menu, switch to another or clear\n if (this.activeMenuName === name) {\n const remainingMenus = Array.from(this.menus.keys());\n this.activeMenuName = remainingMenus.length > 0 ? remainingMenus[0] : null;\n this.render();\n }\n\n return this;\n }\n\n /**\n * Get view data for template rendering\n */\n async onBeforeRender() {\n const currentMenu = this.getCurrentMenuConfig();\n\n if (!currentMenu) {\n return { currentMenu: null };\n }\n\n let subData = {\n version: this.getApp().version || null,\n group: this.getApp().activeGroup || null,\n user: this.getApp.activeUser || null\n };\n // Process menu data through template if it contains handlebars\n this.data = {\n currentMenu: {\n header: this.renderTemplateString(currentMenu.header || '', subData),\n footer: this.renderTemplateString(currentMenu.footer || '', subData),\n items: this.processNavItems(currentMenu.items, currentMenu.groupKind),\n data: currentMenu.data,\n showToggle: this.showToggle\n }\n\n };\n }\n\n async onAfterRender() {\n // Re-initialize tooltips after render, but only if collapsed\n if (this.isCollapsedState()) {\n // Small delay to ensure DOM is fully rendered\n setTimeout(() => this.initializeTooltips(), 50);\n } else {\n this.destroyTooltips();\n }\n }\n\n setCustomView(view) {\n if (this.customView) {\n this.removeChild(this.customView.id);\n }\n this.customView = view;\n if (view) {\n view.containerId = 'sidebar-custom-view-container';\n this.addChild(view);\n }\n this.render();\n return this;\n }\n\n clearCustomView() {\n if (this.customView) {\n this.removeChild(this.customView.id);\n this.customView = null;\n }\n this.render();\n return this;\n }\n\n /**\n * Process navigation items - add IDs, active states, and proper hrefs\n */\n processNavItems(items, groupKind) {\n const app = this.getApp();\n const activeUser = app?.activeUser;\n const activeGroup = app?.activeGroup;\n\n // Helper function to update route with group parameter\n const updateRouteWithGroup = (route) => {\n if (groupKind && activeGroup && activeGroup.id) {\n const separator = route.includes('?') ? '&' : '?';\n return `${route}${separator}group=${activeGroup.id}`;\n }\n return route;\n };\n\n return items.map((item, index) => {\n // Handle divider items\n if (item === \"\" || (typeof item === 'object' && item.divider)) {\n return {\n isDivider: true,\n id: `divider-${index}`\n };\n }\n\n // Handle spacer items\n if (typeof item === 'object' && item.spacer) {\n return {\n isSpacer: true,\n id: `spacer-${index}`\n };\n }\n\n const processedItem = { ...item };\n\n // Check permissions - skip item if user doesn't have required permissions\n if (processedItem.permissions) {\n if (!activeUser || !activeUser.hasPermission(processedItem.permissions)) {\n return null; // Will be filtered out\n }\n }\n\n // Check requiresGroupKind - skip item if group kind doesn't match\n if (processedItem.requiresGroupKind) {\n const groupKind = activeGroup?._.kind || activeGroup?.kind;\n if (!groupKind || !this._groupKindMatches(processedItem.requiresGroupKind, groupKind)) {\n return null; // Will be filtered out\n }\n }\n\n if (processedItem.kind === 'label') {\n processedItem.isLabel = true;\n if (!processedItem.id) {\n processedItem.id = `nav-label-${index}`;\n }\n return processedItem;\n }\n\n // Generate ID if not provided\n if (!processedItem.id) {\n processedItem.id = `nav-${index}`;\n }\n\n // Use route directly as href (like TopNav does)\n if (processedItem.route) {\n processedItem.href = updateRouteWithGroup(processedItem.route);\n } else if (processedItem.page) {\n // If only page is provided, convert to route format\n const baseRoute = processedItem.page.startsWith('/') ? processedItem.page : `/${processedItem.page}`;\n processedItem.href = updateRouteWithGroup(baseRoute);\n processedItem.route = processedItem.href; // Store for active matching\n }\n\n // Active state is already set on the item object, no need to calculate\n\n // Process children\n if (processedItem.children) {\n processedItem.children = processedItem.children.map(child => {\n const processedChild = { ...child };\n\n // Check permissions for child items\n if (processedChild.permissions && activeUser) {\n if (!activeUser.hasPermission(processedChild.permissions)) {\n return null; // Will be filtered out\n }\n }\n\n // Check requiresGroupKind for child items\n if (processedChild.requiresGroupKind) {\n const groupKind = activeGroup?._.kind || activeGroup?.kind;\n if (!groupKind || !this._groupKindMatches(processedChild.requiresGroupKind, groupKind)) {\n return null; // Will be filtered out\n }\n }\n\n // Use route directly as href\n if (processedChild.route) {\n processedChild.href = updateRouteWithGroup(processedChild.route);\n } else if (processedChild.page) {\n const baseRoute = processedChild.page.startsWith('/') ? processedChild.page : `/${processedChild.page}`;\n processedChild.href = updateRouteWithGroup(baseRoute);\n processedChild.route = processedChild.href;\n }\n\n // Active state is already set on the child object\n return processedChild;\n }).filter(child => child !== null); // Filter out permission-denied children\n\n // Update hasChildren flag after filtering children\n processedItem.hasChildren = !!(processedItem.children && processedItem.children.length > 0);\n } else {\n // Add hasChildren flag for template logic\n processedItem.hasChildren = false;\n }\n\n return processedItem;\n }).filter(item => item !== null); // Filter out permission-denied items\n }\n\n\n\n\n /**\n * Check if navigation item should be active (similar to TopNav)\n */\n isItemActive(item) {\n if (!item.route || !this.currentRoute) {\n return false;\n }\n\n const normalizeRoute = (route) => {\n if (!route) return '/';\n // Decode URL-encoded characters (like %2F -> /)\n const decoded = decodeURIComponent(route);\n return decoded.startsWith('/') ? decoded : `/${decoded}`;\n };\n\n const itemRoute = normalizeRoute(item.route);\n const currentRoute = normalizeRoute(this.currentRoute);\n\n if (itemRoute === '/' && currentRoute === '/') {\n return true;\n }\n\n if (itemRoute !== '/' && currentRoute !== '/') {\n return currentRoute.startsWith(itemRoute) || currentRoute === itemRoute;\n }\n\n return false;\n }\n\n /**\n * Update active item based on current route (like TopNav)\n */\n async updateActiveItem(route) {\n this.currentRoute = route;\n\n // Clear all active states and set new active item\n this.clearAllActiveStates();\n this.setActiveItemByRoute(route);\n\n await this.render();\n return this;\n }\n\n /**\n * Action handler: Toggle submenu\n */\n async handleActionToggleSubmenu(event, element) {\n const arrow = element.querySelector('.nav-arrow');\n if (arrow) {\n arrow.classList.toggle('rotated');\n }\n }\n\n /**\n * Action handler: Toggle sidebar collapsed/expanded state\n */\n async handleActionToggleSidebar(event, element) {\n this.toggleSidebar();\n }\n\n onActionShowGroupMenu(action, event, el) {\n this.setActiveMenu(\"group_default\");\n\n return false;\n }\n\n async onActionDefault(action, event, el) {\n const config = this.getCurrentMenuConfig();\n if (!config) return;\n\n for (const item of config.items) {\n if ((item.action == action) && item.handler) {\n item.handler(action, event, el);\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Get all menu names\n */\n getMenuNames() {\n return Array.from(this.menus.keys());\n }\n\n /**\n * Check if menu exists\n */\n hasMenu(name) {\n return this.menus.has(name);\n }\n\n /**\n * Clear all menus\n */\n clearMenus() {\n this.menus.clear();\n this.activeMenuName = null;\n this.render();\n return this;\n }\n\n /**\n * Set data for current menu\n */\n setMenuData(data) {\n const currentMenu = this.getCurrentMenuConfig();\n if (currentMenu) {\n currentMenu.data = { ...currentMenu.data, ...data };\n this.render();\n }\n return this;\n }\n\n /**\n * Get data for current menu\n */\n getMenuData() {\n const currentMenu = this.getCurrentMenuConfig();\n return currentMenu ? currentMenu.data : {};\n }\n\n /**\n * Setup listeners for route change events (like TopNav)\n */\n setupRouteListeners() {\n const app = this.getApp();\n if (app && app.events) {\n app.events.on([\"page:showing\"], (data) => {\n this.onRouteChanged(data);\n });\n app.events.on(\"group:changed\", (data) => {\n this.showMenuForGroup(data.group);\n });\n app.events.on(\"portal:user-changed\", (data) => {\n this.render();\n });\n }\n }\n\n /**\n * Handle route changed event - auto-switch menu and update active item\n */\n onRouteChanged(data) {\n if (data.page && data.page.route) {\n const route = data.page.route;\n if (this.activeMenuItem && this.routesMatch(route, this.activeMenuItem.route)) {\n return;\n }\n // First, try to auto-switch to correct menu for this route\n const switchedMenu = this.autoSwitchToMenuForRoute(route);\n\n // If no menu switch happened, still update active item\n if (!switchedMenu) {\n this.clearAllActiveStates();\n this.setActiveItemByRoute(route);\n this.updateActiveItem(route);\n }\n\n if (switchedMenu) {\n console.log(`Route changed to '${route}', auto-switched menu`);\n }\n }\n }\n\n /**\n * Toggle sidebar between collapsed and expanded states\n */\n toggleSidebar() {\n const portalContainer = document.querySelector('.portal-container');\n if (!portalContainer) return;\n\n // Hide any visible tooltips before state change\n this.hideAllTooltips();\n\n const isCurrentlyCollapsed = portalContainer.classList.contains('collapse-sidebar');\n const isCurrentlyHidden = portalContainer.classList.contains('hide-sidebar');\n\n if (isCurrentlyHidden) {\n // Hidden -> Normal\n portalContainer.classList.remove('hide-sidebar');\n this.isCollapsed = false;\n this.destroyTooltips();\n } else if (isCurrentlyCollapsed) {\n // Collapsed -> Normal\n portalContainer.classList.remove('collapse-sidebar');\n this.isCollapsed = false;\n this.destroyTooltips();\n } else {\n // Normal -> Collapsed\n portalContainer.classList.add('collapse-sidebar');\n this.isCollapsed = true;\n // Initialize tooltips with delay to ensure DOM is ready\n setTimeout(() => this.initializeTooltips(), 150);\n }\n\n return this;\n }\n\n /**\n * Set sidebar state programmatically\n */\n setSidebarState(state) {\n const portalContainer = document.querySelector('.portal-container');\n if (!portalContainer) return this;\n\n // Remove all state classes first\n portalContainer.classList.remove('collapse-sidebar', 'hide-sidebar');\n\n switch (state) {\n case 'collapsed':\n portalContainer.classList.add('collapse-sidebar');\n this.isCollapsed = true;\n break;\n case 'hidden':\n portalContainer.classList.add('hide-sidebar');\n this.isCollapsed = false;\n break;\n case 'normal':\n default:\n this.isCollapsed = false;\n break;\n }\n\n // Handle tooltips based on state\n if (this.isCollapsed) {\n // Hide any visible tooltips first\n this.hideAllTooltips();\n // Initialize tooltips when collapsed\n setTimeout(() => this.initializeTooltips(), 100);\n } else {\n // Destroy tooltips when not collapsed\n this.destroyTooltips();\n }\n\n return this;\n }\n\n /**\n * Initialize tooltips for nav items when sidebar is collapsed\n */\n initializeTooltips() {\n // Clean up existing tooltips first\n this.destroyTooltips();\n\n // Only initialize tooltips in collapsed state\n if (!this.isCollapsedState()) {\n return this;\n }\n\n // Auto-generate tooltips from nav-text content\n const navLinks = this.element.querySelectorAll('.sidebar-nav .nav-link');\n\n navLinks.forEach((link) => {\n const navText = link.querySelector('.nav-text');\n\n if (navText && navText.textContent.trim()) {\n const tooltipText = navText.textContent.trim();\n\n // Set Bootstrap tooltip attributes\n link.setAttribute('data-bs-toggle', 'tooltip');\n link.setAttribute('data-bs-placement', 'right');\n link.setAttribute('data-bs-title', tooltipText);\n link.setAttribute('data-bs-container', 'body');\n\n // Initialize Bootstrap tooltip with better config\n if (window.bootstrap && window.bootstrap.Tooltip) {\n // Extract custom theme/size if specified\n const theme = link.getAttribute('data-tooltip-theme');\n const size = link.getAttribute('data-tooltip-size');\n\n // Build custom class list\n let customClass = '';\n if (theme) customClass += `tooltip-${theme} `;\n if (size) customClass += `tooltip-${size}`;\n\n // Build options object\n const tooltipOptions = {\n placement: 'right',\n container: 'body',\n trigger: 'hover',\n delay: { show: 500, hide: 100 },\n fallbackPlacements: ['top', 'bottom', 'left']\n };\n\n // Only add customClass if it has a value\n const trimmedClass = customClass.trim();\n if (trimmedClass) {\n tooltipOptions.customClass = trimmedClass;\n }\n\n const tooltip = new window.bootstrap.Tooltip(link, tooltipOptions);\n\n // Store tooltip instance for better management\n link._tooltipInstance = tooltip;\n\n // Add event listeners to prevent stuck tooltips\n link.addEventListener('click', () => {\n tooltip.hide();\n });\n\n link.addEventListener('blur', () => {\n tooltip.hide();\n });\n }\n }\n });\n\n // Add global event listeners to hide tooltips\n this.addTooltipHideListeners();\n\n return this;\n }\n\n destroyTooltips() {\n // Remove global tooltip hide listeners\n this.removeTooltipHideListeners();\n\n const navLinks = this.element.querySelectorAll('.sidebar-nav .nav-link[data-bs-toggle=\"tooltip\"]');\n\n navLinks.forEach((link) => {\n // Use stored instance first, then try to get it\n const tooltipInstance = link._tooltipInstance || window.bootstrap?.Tooltip?.getInstance(link);\n if (tooltipInstance) {\n // Force hide before dispose\n tooltipInstance.hide();\n tooltipInstance.dispose();\n }\n\n // Clean up stored reference\n delete link._tooltipInstance;\n\n // Remove tooltip attributes\n link.removeAttribute('data-bs-toggle');\n link.removeAttribute('data-bs-placement');\n link.removeAttribute('data-bs-title');\n link.removeAttribute('data-bs-container');\n });\n\n return this;\n }\n\n /**\n * Get current sidebar state\n */\n getSidebarState() {\n const portalContainer = document.querySelector('.portal-container');\n if (!portalContainer) return 'normal';\n\n if (portalContainer.classList.contains('hide-sidebar')) {\n return 'hidden';\n } else if (portalContainer.classList.contains('collapse-sidebar')) {\n return 'collapsed';\n } else {\n return 'normal';\n }\n }\n\n /**\n * Check if sidebar is collapsed\n */\n isCollapsedState() {\n return this.getSidebarState() === 'collapsed';\n }\n\n /**\n * Enable/disable toggle button\n */\n setToggleEnabled(enabled) {\n this.showToggle = enabled;\n this.render();\n return this;\n }\n\n /**\n * Initialize menus from options\n */\n initializeMenus(options) {\n if (options.menus) {\n for (const menu of options.menus) {\n this.addMenu(menu.name, menu);\n }\n } else if (options.menu) {\n options.menu.name = options.menu.name || \"default\";\n this.addMenu(options.menu.name, options.menu);\n }\n }\n\n /**\n * Add global listeners to hide tooltips when needed\n */\n addTooltipHideListeners() {\n // Hide tooltips on scroll\n this._tooltipScrollHandler = () => this.hideAllTooltips();\n this.element.addEventListener('scroll', this._tooltipScrollHandler, { passive: true });\n\n // Hide tooltips on route change\n this._tooltipRouteHandler = () => this.hideAllTooltips();\n const app = this.getApp();\n\n\n // Hide tooltips on window blur\n this._tooltipBlurHandler = () => this.hideAllTooltips();\n window.addEventListener('blur', this._tooltipBlurHandler);\n\n // Hide tooltips on escape key\n this._tooltipEscapeHandler = (e) => {\n if (e.key === 'Escape') {\n this.hideAllTooltips();\n }\n };\n document.addEventListener('keydown', this._tooltipEscapeHandler);\n }\n\n /**\n * Remove global tooltip hide listeners\n */\n removeTooltipHideListeners() {\n if (this._tooltipScrollHandler) {\n this.element.removeEventListener('scroll', this._tooltipScrollHandler);\n delete this._tooltipScrollHandler;\n }\n\n if (this._tooltipBlurHandler) {\n window.removeEventListener('blur', this._tooltipBlurHandler);\n delete this._tooltipBlurHandler;\n }\n\n if (this._tooltipEscapeHandler) {\n document.removeEventListener('keydown', this._tooltipEscapeHandler);\n delete this._tooltipEscapeHandler;\n }\n }\n\n /**\n * Force hide all visible tooltips\n */\n hideAllTooltips() {\n const navLinks = this.element.querySelectorAll('.sidebar-nav .nav-link[data-bs-toggle=\"tooltip\"]');\n navLinks.forEach((link) => {\n const tooltip = link._tooltipInstance || window.bootstrap?.Tooltip?.getInstance(link);\n if (tooltip) {\n tooltip.hide();\n }\n });\n\n // Also hide any orphaned tooltips\n const visibleTooltips = document.querySelectorAll('.tooltip.show');\n visibleTooltips.forEach(tooltip => {\n tooltip.remove();\n });\n }\n\n /**\n * Cleanup on destroy\n */\n async onBeforeDestroy() {\n // Clean up tooltips\n this.destroyTooltips();\n\n // Call parent cleanup\n await super.onBeforeDestroy();\n }\n\n /**\n * Setup responsive behavior for mobile\n */\n setupResponsiveBehavior() {\n const checkMobile = () => {\n const isMobile = window.innerWidth <= 768;\n const portalContainer = document.querySelector('.portal-container');\n\n if (portalContainer) {\n if (isMobile) {\n portalContainer.classList.add('sidebar-mobile');\n } else {\n portalContainer.classList.remove('sidebar-mobile', 'sidebar-open');\n }\n }\n };\n\n // Check on load and resize\n checkMobile();\n window.addEventListener('resize', checkMobile);\n }\n\n /**\n * Static method to create a sidebar with common configuration\n */\n static createDefault(options = {}) {\n return new Sidebar({\n theme: 'sidebar-clean',\n showToggle: true,\n autoCollapseMobile: true,\n ...options\n });\n }\n\n /**\n * Static method to create a minimal sidebar\n */\n static createMinimal(options = {}) {\n return new Sidebar({\n theme: 'sidebar-clean',\n showToggle: false,\n autoCollapseMobile: false,\n ...options\n });\n }\n\n /**\n * Set sidebar theme\n */\n setSidebarTheme(theme) {\n // Remove existing theme classes\n this.removeClass('sidebar-light sidebar-dark sidebar-clean');\n\n // Add new theme\n this.sidebarTheme = theme;\n this.addClass(theme);\n\n return this;\n }\n\n /**\n * Quick method to show/hide the sidebar\n */\n show() {\n return this.setSidebarState('normal');\n }\n\n hide() {\n return this.setSidebarState('hidden');\n }\n\n collapse() {\n return this.setSidebarState('collapsed');\n }\n\n expand() {\n return this.setSidebarState('normal');\n }\n\n /**\n * Add pulse effect to toggle button\n */\n pulseToggle() {\n const toggleButton = this.element.querySelector('.sidebar-toggle');\n if (toggleButton) {\n toggleButton.classList.add('pulse');\n\n // Remove pulse after 3 seconds or first click\n const removePulse = () => {\n toggleButton.classList.remove('pulse');\n toggleButton.removeEventListener('click', removePulse);\n };\n\n toggleButton.addEventListener('click', removePulse, { once: true });\n setTimeout(removePulse, 3000);\n }\n return this;\n }\n\n /**\n * Utility method to quickly add a simple menu item\n */\n addSimpleMenuItem(menuName, text, route, icon = 'bi-circle') {\n const menu = this.menus.get(menuName);\n if (menu) {\n menu.items = menu.items || [];\n menu.items.push({\n text: text,\n route: route,\n icon: icon\n });\n\n if (this.activeMenuName === menuName) {\n this.render();\n }\n }\n return this;\n }\n\n /**\n * Utility method to quickly create and set a simple menu\n */\n setSimpleMenu(name, header, items) {\n const menu = {\n name: name,\n header: header,\n items: items\n };\n\n this.addMenu(name, menu);\n this.setActiveMenu(name);\n\n return this;\n }\n\n}\n\nexport default Sidebar;\n","/**\n * PageHeader - Displays page title, description, and actions above page content\n * Used by PortalApp to show consistent page headers\n */\n\nimport View from '@core/View.js';\n\nclass PageHeader extends View {\n constructor(options = {}) {\n super({\n tagName: 'div',\n className: 'page-header',\n ...options\n });\n\n // Configuration\n this.style = options.style || 'default'; // 'default' | 'minimal' | 'breadcrumb'\n this.size = options.size || 'md'; // 'sm' | 'md' | 'lg' | 'xl'\n this.showIcon = options.showIcon !== false;\n this.showDescription = options.showDescription !== false;\n this.showBreadcrumbs = options.showBreadcrumbs || false;\n \n // Current page reference\n this.currentPage = null;\n }\n\n async getTemplate() {\n if (this.style === 'minimal') {\n return this.getMinimalTemplate();\n } else if (this.style === 'breadcrumb') {\n return this.getBreadcrumbTemplate();\n }\n return this.getDefaultTemplate();\n }\n\n getDefaultTemplate() {\n return `\n {{#data.hasPage}}\n <div class=\"page-header-content page-header-{{data.size}}\">\n <div class=\"page-header-main\">\n <div class=\"page-header-info\">\n {{#data.showIcon}}\n {{#data.pageIcon}}\n <div class=\"page-icon\">\n <i class=\"{{data.pageIcon}}\"></i>\n </div>\n {{/data.pageIcon}}\n {{/data.showIcon}}\n \n <div class=\"page-title-group\">\n <h1 class=\"page-title\">{{data.pageTitle}}</h1>\n {{#data.showDescription}}\n {{#data.pageDescription}}\n <p class=\"page-description text-muted\">{{data.pageDescription}}</p>\n {{/data.pageDescription}}\n {{/data.showDescription}}\n </div>\n </div>\n\n {{#data.hasActions}}\n <div class=\"page-actions\">\n {{#data.actions}}\n <button class=\"btn {{buttonClass}}\" \n data-action=\"{{action}}\"\n type=\"button\">\n {{#icon}}<i class=\"{{icon}} me-1\"></i>{{/icon}}\n {{label}}\n </button>\n {{/data.actions}}\n </div>\n {{/data.hasActions}}\n </div>\n </div>\n {{/data.hasPage}}\n `;\n }\n\n getMinimalTemplate() {\n return `\n {{#data.hasPage}}\n <div class=\"page-header-content page-header-minimal\">\n <h1 class=\"page-title\">\n {{#data.showIcon}}\n {{#data.pageIcon}}<i class=\"{{data.pageIcon}} me-2\"></i>{{/data.pageIcon}}\n {{/data.showIcon}}\n {{data.pageTitle}}\n </h1>\n </div>\n {{/data.hasPage}}\n `;\n }\n\n getBreadcrumbTemplate() {\n return `\n {{#data.hasPage}}\n <div class=\"page-header-content page-header-breadcrumb\">\n {{#data.showBreadcrumbs}}\n <nav aria-label=\"breadcrumb\">\n <ol class=\"breadcrumb mb-2\">\n {{#data.breadcrumbs}}\n <li class=\"breadcrumb-item {{#active}}active{{/active}}\">\n {{#href}}<a href=\"{{href}}\">{{label}}</a>{{/href}}\n {{^href}}{{label}}{{/href}}\n </li>\n {{/data.breadcrumbs}}\n </ol>\n </nav>\n {{/data.showBreadcrumbs}}\n \n <div class=\"d-flex justify-content-between align-items-start\">\n <h1 class=\"page-title\">\n {{#data.showIcon}}\n {{#data.pageIcon}}<i class=\"{{data.pageIcon}} me-2\"></i>{{/data.pageIcon}}\n {{/data.showIcon}}\n {{data.pageTitle}}\n </h1>\n \n {{#data.hasActions}}\n <div class=\"page-actions\">\n {{#data.actions}}\n <button class=\"btn {{buttonClass}}\" \n data-action=\"{{action}}\"\n type=\"button\">\n {{#icon}}<i class=\"{{icon}} me-1\"></i>{{/icon}}\n {{label}}\n </button>\n {{/data.actions}}\n </div>\n {{/data.hasActions}}\n </div>\n \n {{#data.showDescription}}\n {{#data.pageDescription}}\n <p class=\"page-description text-muted mt-2\">{{data.pageDescription}}</p>\n {{/data.pageDescription}}\n {{/data.showDescription}}\n </div>\n {{/data.hasPage}}\n `;\n }\n\n async onBeforeRender() {\n await super.onBeforeRender();\n\n const page = this.currentPage;\n const hasPage = !!page;\n\n // Get headerActions from page options, instance, or constructor.prototype\n const headerActions = page?.options?.headerActions ||\n page?.headerActions || \n page?.constructor?.prototype?.headerActions || \n [];\n\n this.data = {\n hasPage,\n pageTitle: page?.title || page?.name || '',\n pageIcon: page?.icon || page?.pageIcon || '',\n pageDescription: page?.description || '',\n showIcon: this.showIcon,\n showDescription: this.showDescription,\n showBreadcrumbs: this.showBreadcrumbs,\n breadcrumbs: page?.options?.breadcrumbs || page?.breadcrumbs || [],\n actions: headerActions,\n hasActions: headerActions.length > 0,\n size: this.size\n };\n }\n\n /**\n * Set the current page to display\n */\n setPage(page) {\n this.currentPage = page;\n if (this.mounted) {\n this.render();\n }\n }\n\n /**\n * Get the current page\n */\n getPage() {\n return this.currentPage;\n }\n\n /**\n * Handle action clicks from page header buttons\n */\n async onActionDefault(action, event, element) {\n // Emit to page if it has a handler\n if (this.currentPage && typeof this.currentPage.onHeaderAction === 'function') {\n await this.currentPage.onHeaderAction(action, event, element);\n return true;\n }\n\n // Emit event for parent to handle\n this.emit('action', {\n action,\n event,\n element,\n page: this.currentPage\n });\n\n return false;\n }\n}\n\nexport default PageHeader;\n","/**\n * DeniedPage - Access Denied page for MOJO Framework\n * Displays when a user attempts to access a page without proper permissions\n */\n\nimport Page from '@core/Page.js';\n\nclass DeniedPage extends Page {\n constructor(options = {}) {\n super({\n pageName: 'Access Denied',\n route: '/denied',\n title: 'Access Denied',\n pageIcon: 'bi bi-shield-x',\n template: `\n <div class=\"container mt-5\">\n <div class=\"row justify-content-center\">\n <div class=\"col-md-8 col-lg-6\">\n <div class=\"text-center mb-4\">\n <i class=\"bi bi-shield-x text-muted\" style=\"font-size: 3rem;\"></i>\n <h2 class=\"mt-3 mb-2\">Access Denied</h2>\n <p class=\"text-muted\">You don't have permission to access this page.</p>\n </div>\n\n {{#deniedPage}}\n <div class=\"card border-0 shadow-sm mb-4\">\n <div class=\"card-body\">\n <h6 class=\"card-subtitle mb-2 text-muted\">Requested Page</h6>\n <h5 class=\"card-title\">\n <i class=\"{{pageIcon}} me-2\"></i>\n {{displayName}}\n </h5>\n {{#route}}\n <p class=\"card-text text-muted small\">{{route}}</p>\n {{/route}}\n {{#description}}\n <p class=\"card-text\">{{description}}</p>\n {{/description}}\n\n {{#requiredPermissions}}\n <div class=\"mt-3\">\n <h6 class=\"mb-2\">Required Permissions:</h6>\n {{#permissions}}\n <span class=\"badge bg-light text-dark me-1 mb-1\">{{.}}</span>\n {{/permissions}}\n {{^permissions}}\n <span class=\"text-muted small\">Authentication required</span>\n {{/permissions}}\n </div>\n {{/requiredPermissions}}\n </div>\n </div>\n {{/deniedPage}}\n\n <div class=\"d-grid gap-2 d-md-flex justify-content-md-center\">\n <button type=\"button\" class=\"btn btn-primary\" data-action=\"go-back\">\n <i class=\"bi bi-arrow-left me-1\"></i>\n Go Back\n </button>\n <button type=\"button\" class=\"btn btn-outline-secondary\" data-action=\"go-home\">\n <i class=\"bi bi-house me-1\"></i>\n Home\n </button>\n {{#showLogin}}\n <button type=\"button\" class=\"btn btn-outline-primary\" data-action=\"login\">\n <i class=\"bi bi-box-arrow-in-right me-1\"></i>\n Login\n </button>\n {{/showLogin}}\n </div>\n\n {{#currentUser}}\n <div class=\"text-center mt-4\">\n <small class=\"text-muted\">\n Logged in as <strong>{{username}}</strong>\n </small>\n </div>\n {{/currentUser}}\n </div>\n </div>\n </div>\n `,\n ...options\n });\n\n // Store the denied page instance\n this.deniedPage = null;\n this.deniedPageOptions = null;\n }\n\n /**\n * Handle route parameters - expect denied page info\n */\n async onParams(params = {}, query = {}) {\n await super.onParams(params, query);\n\n // If page info is passed in params\n if (params.page) {\n this.deniedPage = params.page;\n this.deniedPageOptions = params.page.options || params.page.pageOptions || {};\n } else if (query.page) {\n // Handle page name from query string\n this.deniedPageName = query.page;\n }\n }\n\n /**\n * Set the denied page instance\n */\n setDeniedPage(pageInstance) {\n this.deniedPage = pageInstance;\n this.deniedPageOptions = pageInstance?.options || pageInstance?.pageOptions || {};\n return this;\n }\n\n /**\n * Get view data for template rendering\n */\n async getViewData() {\n const app = this.getApp();\n\n // Get current user info\n const currentUser = app?.activeUser || app?.getCurrentUser?.() || null;\n\n // Process denied page info\n let deniedPageInfo = null;\n if (this.deniedPage) {\n const permissions = this.deniedPageOptions?.permissions ||\n this.deniedPage.options?.permissions ||\n this.deniedPage.pageOptions?.permissions;\n\n deniedPageInfo = {\n displayName: this.deniedPage.displayName || this.deniedPage.pageName || this.deniedPage.title || 'Unknown Page',\n pageName: this.deniedPage.pageName,\n route: this.deniedPage.route,\n description: this.deniedPage.pageDescription || this.deniedPage.description,\n pageIcon: this.deniedPage.pageIcon || 'bi bi-file-text',\n requiredPermissions: permissions ? {\n permissions: Array.isArray(permissions) ? permissions : [permissions]\n } : null\n };\n } else if (this.deniedPageName) {\n deniedPageInfo = {\n displayName: this.deniedPageName,\n pageName: this.deniedPageName,\n pageIcon: 'bi bi-file-text'\n };\n }\n\n return {\n deniedPage: deniedPageInfo,\n currentUser: currentUser ? {\n username: currentUser.username || currentUser.name || currentUser.email || 'Unknown User',\n name: currentUser.name,\n email: currentUser.email\n } : null,\n showLogin: !currentUser // Show login button if not authenticated\n };\n }\n\n /**\n * Handle going back to previous page\n */\n async handleActionGoBack(event, element) {\n event.preventDefault();\n\n // Try to go back in browser history\n if (window.history.length > 1) {\n window.history.back();\n } else {\n // Fallback to home page\n await this.handleActionGoHome(event, element);\n }\n }\n\n /**\n * Handle navigation to home page\n */\n async handleActionGoHome(event, element) {\n event.preventDefault();\n\n const app = this.getApp();\n if (app) {\n await app.navigateToDefault();\n } else {\n // Fallback navigation\n window.location.href = '/';\n }\n }\n\n /**\n * Handle login action\n */\n async handleActionLogin(event, element) {\n event.preventDefault();\n\n const app = this.getApp();\n\n // Try to navigate to login page\n if (app) {\n try {\n await app.showPage('login');\n } catch (error) {\n // If login page doesn't exist, try auth route\n try {\n await app.navigate('/login');\n } catch (navError) {\n // Fallback - emit login required event\n this.emit('login-required', {\n returnUrl: this.deniedPage?.route || window.location.pathname\n });\n\n // Show message if no handlers\n setTimeout(() => {\n app?.showInfo?.('Please contact your administrator for access.');\n }, 100);\n }\n }\n }\n }\n\n /**\n * Called when entering this page\n */\n async onEnter() {\n await super.onEnter();\n\n // Set appropriate page title\n const pageName = this.deniedPage?.pageName || this.deniedPageName;\n if (pageName) {\n this.setMeta({\n title: `Access Denied - ${pageName}`\n });\n }\n\n // Log access denial for security monitoring\n console.warn('Access denied to page:', {\n page: this.deniedPage?.pageName || this.deniedPageName,\n route: this.deniedPage?.route,\n permissions: this.deniedPageOptions?.permissions,\n timestamp: new Date().toISOString()\n });\n }\n\n /**\n * Static helper to show access denied for a specific page\n */\n static showForPage(app, pageInstance) {\n const deniedPage = new DeniedPage();\n deniedPage.setDeniedPage(pageInstance);\n return app.showPage(deniedPage);\n }\n}\n\nexport default DeniedPage;\n","/**\n * NotFoundPage - 404 Not Found page for MOJO Framework\n * Displays when a user attempts to access a non-existent page or route\n */\n\nimport Page from '@core/Page.js';\n\nclass NotFoundPage extends Page {\n constructor(options = {}) {\n super({\n pageName: '404',\n route: '/404',\n title: '404 - Page Not Found',\n pageIcon: 'bi bi-search',\n template: `\n <div class=\"container mt-5\">\n <div class=\"row justify-content-center\">\n <div class=\"col-md-8 col-lg-6\">\n <div class=\"text-center mb-4\">\n <i class=\"bi bi-search text-muted\" style=\"font-size: 3rem;\"></i>\n <h2 class=\"mt-3 mb-2\">Page Not Found</h2>\n <p class=\"text-muted\">The page you're looking for doesn't exist.</p>\n </div>\n\n {{#path}}\n <div class=\"card border-0 shadow-sm mb-4\">\n <div class=\"card-body text-center\">\n <h6 class=\"card-subtitle mb-2 text-muted\">Requested Path</h6>\n <code class=\"text-primary\">{{path}}</code>\n </div>\n </div>\n {{/path}}\n\n <div class=\"d-grid gap-2 d-md-flex justify-content-md-center\">\n <button type=\"button\" class=\"btn btn-primary\" data-action=\"go-back\">\n <i class=\"bi bi-arrow-left me-1\"></i>\n Go Back\n </button>\n <button type=\"button\" class=\"btn btn-outline-secondary\" data-action=\"go-home\">\n <i class=\"bi bi-house me-1\"></i>\n Home\n </button>\n </div>\n </div>\n </div>\n </div>\n `,\n ...options\n });\n\n // Store the not found path\n this.path = null;\n }\n\n /**\n * Handle route parameters\n */\n async onParams(params = {}, query = {}) {\n await super.onParams(params, query);\n\n // Store path from params or query\n if (params.path) {\n this.path = params.path;\n }\n if (query.path) {\n this.path = query.path;\n }\n }\n\n /**\n * Set not found path\n */\n setInfo(path) {\n this.path = path || null;\n return this;\n }\n\n /**\n * Handle going back to previous page\n */\n async handleActionGoBack(event, _element) {\n event.preventDefault();\n\n // Try to go back in browser history\n if (window.history.length > 1) {\n window.history.back();\n } else {\n // Fallback to home page\n await this.handleActionGoHome(event, _element);\n }\n }\n\n /**\n * Handle navigation to home page\n */\n async handleActionGoHome(event, _element) {\n event.preventDefault();\n\n const app = this.getApp();\n if (app) {\n await app.navigateToDefault();\n } else {\n // Fallback navigation\n window.location.href = '/';\n }\n }\n\n /**\n * Called when entering this page\n */\n async onEnter() {\n await super.onEnter();\n\n // Set appropriate page title\n if (this.path) {\n this.setMeta({\n title: `404 - ${this.path} Not Found`\n });\n }\n\n // Log 404 for analytics\n console.warn('404 Not Found:', {\n path: this.path,\n timestamp: new Date().toISOString()\n });\n }\n\n /**\n * Static helper to show 404 for a specific path\n */\n static showForPath(app, path) {\n const notFoundPage = new NotFoundPage();\n notFoundPage.setInfo(path);\n return notFoundPage.render(); // Just render, don't navigate\n }\n}\n\nexport default NotFoundPage;\n","/**\n * PortalApp - Complete portal application extending WebApp\n * Provides built-in navigation, sidebar, and content management\n * Clean, simple implementation that reuses WebApp and View logic\n */\n\nimport WebApp from '@core/WebApp.js';\nimport TopNav from '@core/views/navigation/TopNav.js';\nimport Sidebar from '@core/views/navigation/Sidebar.js';\nimport PageHeader from '@core/views/navigation/PageHeader.js';\nimport DeniedPage from '@core/pages/DeniedPage.js';\nimport TokenManager from '@core/services/TokenManager.js';\nimport {User} from '@core/models/User.js';\nimport {Group } from '@core/models/Group.js';\nimport {Member} from '@core/models/Member.js';\nimport NotFoundPage from '@core/pages/NotFoundPage.js';\nimport ToastService from '@core/services/ToastService.js';\nimport Dialog from '@core/views/feedback/Dialog.js';\n\nexport default class PortalApp extends WebApp {\n constructor(config = {}) {\n // Pass core WebApp config through\n super(config);\n\n this.sidebarConfig = config.sidebar;\n // Portal-specific configuration (clean flat structure)\n // if (config.sidebar && config.sidebar.menus) {\n // this.sidebarConfig.menus = config.sidebar.menus;\n // this.sidebarConfig.groupSelectorMode = config.sidebar.groupSelectorMode || \"inline\";\n // if (config.sidebar.groupHeader) {\n // this.sidebarConfig.groupHeader = config.sidebar.groupHeader;\n // }\n // } else if (config.sidebar.menu) {\n // this.sidebarConfig.menu = config.sidebar.menu;\n // } else if (config.sidebar.items) {\n // this.sidebarConfig.menu = config.sidebar;\n // }\n\n this.topbarConfig = config.topbar || {};\n\n // Legacy support - topnav -> topbar\n if (config.topnav && !config.topbar) {\n this.topbarConfig = config.topnav;\n }\n\n // Page header configuration\n this.showPageHeader = config.showPageHeader || false;\n this.pageHeaderConfig = config.pageHeader || {};\n\n // Portal components\n this.sidebar = null;\n this.topbar = null;\n this.topnav = null; // Legacy reference\n this.pageHeader = null;\n this.tokenManager = new TokenManager();\n\n // Active group management\n this.activeGroup = null;\n // Portal state - Load from localStorage first, then fallback to config\n if (!this.isMobile()) {\n this.sidebarCollapsed = this.loadSidebarState() ??\n (this.sidebarConfig.defaultCollapsed || false);\n } else {\n this.sidebarCollapsed = this.sidebarConfig.defaultCollapsed || false;\n }\n this.setupPageContainer();\n\n this.toast = new ToastService();\n this.Dialog = Dialog;\n\n this.registerPage(\"denied\", DeniedPage);\n this.registerPage(\"404\", NotFoundPage);\n }\n\n /**\n * Override WebApp start to setup portal layout\n */\n async start() {\n // Call parent start (handles router, error handling, etc.)\n // Setup router\n await this.checkAuthStatus();\n\n this.events.on('auth:unauthorized', () => {\n this.tokenManager.clearTokens();\n this.rest.clearAuth();\n this.setActiveUser(null);\n return;\n });\n\n this.events.on('auth:logout', () => {\n this.tokenManager.clearTokens();\n this.rest.clearAuth();\n this.setActiveUser(null);\n return;\n });\n\n this.events.on(\"browser:focus\", () => {\n if (!this.activeUser) return;\n this.tokenManager.checkAndRefreshTokens(this);\n });\n\n this.events.on('portal:action', this.onPortalAction.bind(this));\n\n if (this.activeUser) {\n // Check and load active group after auth\n await this.checkActiveGroup();\n }\n\n\n await this.setupRouter();\n\n // Mark as started\n this.isStarted = true;\n\n // Emit app ready event\n this.events.emit('app:ready', { app: this });\n\n\n }\n\n async checkAuthStatus() {\n const tokenStatus = this.tokenManager.checkTokenStatus();\n\n // Handle logout scenarios\n if (tokenStatus.action === 'logout') {\n this.events.emit('auth:unauthorized', { app: this });\n return false;\n }\n\n // Handle refresh scenarios - attempt refresh if needed\n if (tokenStatus.action === 'refresh') {\n const refreshed = await this.tokenManager.checkAndRefreshTokens(this);\n if (!refreshed) {\n // If refresh failed, checkAndRefreshTokens already handled logout\n return false;\n }\n }\n\n // At this point we have a valid token\n const token = this.tokenManager.getTokenInstance();\n\n // If user already loaded, just start auto-refresh and return\n if (this.activeUser) {\n this.tokenManager.startAutoRefresh(this);\n return true;\n }\n\n // Load user data\n this.rest.setAuthToken(token.token);\n const user = new User({ id: token.getUserId() });\n const resp = await user.fetch();\n if (!resp.success) {\n this.tokenManager.clearTokens();\n this.events.emit('auth:unauthorized', { app: this, error: resp.error });\n return false;\n }\n\n this.setActiveUser(user);\n this.tokenManager.startAutoRefresh(this);\n return true;\n }\n\n /**\n * Check and load active group from storage\n */\n async checkActiveGroup() {\n // First check URL search params for group parameter\n const urlParams = new URLSearchParams(window.location.search);\n const urlGroupId = urlParams.get('group');\n\n // Determine which group ID to use: URL param takes priority\n const groupId = urlGroupId || this.loadActiveGroupId();\n\n if (groupId) {\n try {\n const group = new Group({ id: groupId });\n const resp = await group.fetch();\n if (!resp.success || !resp.data.status) {\n this.clearActiveGroup();\n console.warn('Failed to load active group:', resp.statusText);\n return;\n }\n\n this.activeGroup = group;\n // If we got the group from URL, save it as the new active group\n if (urlGroupId) {\n this.saveActiveGroupId(groupId);\n }\n\n if (this.activeUser) {\n this.activeUser.member = new Member();\n await this.activeUser.member.fetchForGroup(group.id);\n }\n\n // Emit event that group was loaded\n this.events.emit('group:loaded', { group: this.activeGroup });\n\n\n } catch (error) {\n console.warn('Failed to load active group:', error);\n // If URL group failed, try to clear it and fall back to stored group\n if (urlGroupId && !this.loadActiveGroupId()) {\n // URL group failed and no stored group, clear everything\n this.clearActiveGroupId();\n } else if (urlGroupId) {\n // URL group failed but we have a stored group, try that instead\n const storedGroupId = this.loadActiveGroupId();\n if (storedGroupId && storedGroupId !== urlGroupId) {\n try {\n const fallbackGroup = new Group({ id: storedGroupId });\n await fallbackGroup.fetch();\n this.activeGroup = fallbackGroup;\n this.events.emit('group:loaded', { group: this.activeGroup });\n\n } catch (fallbackError) {\n console.warn('Fallback to stored group also failed:', fallbackError);\n this.clearActiveGroupId();\n }\n }\n }\n }\n }\n }\n\n\n /**\n * Set the active group\n */\n async setActiveGroup(group) {\n const previousGroup = this.activeGroup;\n this.activeGroup = group;\n\n // Save to storage\n if (group && group.get('id')) {\n this.saveActiveGroupId(group.get('id'));\n } else {\n this.clearActiveGroupId();\n }\n\n if (this.activeUser) {\n this.activeUser.member = new Member();\n await this.activeUser.member.fetchForGroup(group.id);\n }\n\n // Emit event\n this.events.emit('group:changed', {\n group,\n previousGroup,\n app: this\n });\n\n const page = this.getCurrentPage();\n if (page && page.onGroupChange) {\n page.onGroupChange(group);\n }\n\n this.router.updateUrl({group:group.id}, { replace: true });\n\n return this;\n }\n\n /**\n * Get the active group\n */\n getActiveGroup() {\n return this.activeGroup;\n }\n\n /**\n * Clear the active group\n */\n async clearActiveGroup() {\n const previousGroup = this.activeGroup;\n this.activeGroup = null;\n this.clearActiveGroupId();\n // Emit event\n this.events.emit('group:cleared', {\n previousGroup,\n app: this\n });\n return this;\n }\n\n /**\n * Save active group ID to localStorage\n */\n saveActiveGroupId(groupId) {\n try {\n const key = this.getActiveGroupStorageKey();\n localStorage.setItem(key, groupId.toString());\n } catch (error) {\n console.warn('Failed to save active group ID:', error);\n }\n }\n\n /**\n * Load active group ID from localStorage\n */\n loadActiveGroupId() {\n try {\n const key = this.getActiveGroupStorageKey();\n return localStorage.getItem(key);\n } catch (error) {\n console.warn('Failed to load active group ID:', error);\n return null;\n }\n }\n\n /**\n * Clear active group ID from localStorage\n */\n clearActiveGroupId() {\n try {\n const key = this.getActiveGroupStorageKey();\n localStorage.removeItem(key);\n } catch (error) {\n console.warn('Failed to clear active group ID:', error);\n }\n }\n\n /**\n * Get storage key for active group ID\n */\n getActiveGroupStorageKey() {\n return `active_group_id`;\n }\n\n /**\n * Set portal profile to localStorage\n */\n setPortalProfile(profile) {\n try {\n localStorage.setItem('portal_profile', profile);\n } catch (error) {\n console.warn('Failed to save portal profile:', error);\n }\n }\n\n /**\n * Check if user needs to select a group\n */\n needsGroupSelection() {\n return !this.activeGroup;\n }\n\n /**\n * Setup layout based on configuration\n */\n setupPageContainer() {\n const container = typeof this.container === 'string'\n ? document.querySelector(this.container)\n : this.container;\n\n if (!container) {\n throw new Error(`Portal container not found: ${this.container}`);\n }\n\n // Create clean portal layout\n const showSidebar = this.sidebarConfig && Object.keys(this.sidebarConfig).length > 0;\n const showTopbar = this.topbarConfig && Object.keys(this.topbarConfig).length > 0;\n\n // If page header is enabled, wrap content in two containers\n const contentMarkup = this.showPageHeader ? `\n <div class=\"portal-content\" id=\"portal-content\">\n <div id=\"page-header\"></div>\n <div id=\"page-container\">\n <!-- Pages render here -->\n </div>\n </div>\n ` : `\n <div class=\"portal-content\" id=\"page-container\">\n <!-- Pages render here -->\n </div>\n `;\n\n container.innerHTML = `\n <div class=\"portal-layout hide-sidebar\">\n ${showSidebar ? '<div id=\"portal-sidebar\"></div>' : ''}\n <div class=\"portal-body\">\n ${showTopbar ? '<div id=\"portal-topnav\"></div>' : ''}\n ${contentMarkup}\n </div>\n </div>\n `;\n\n // Set page container for WebApp\n this.pageContainer = '#page-container';\n\n // Add portal CSS classes and apply saved state\n container.classList.add('portal-container');\n\n // Setup page container\n this.setupPortalComponents();\n\n // Apply the saved sidebar state\n this.applySidebarState(container);\n }\n\n /**\n * Setup portal components\n */\n async setupPortalComponents() {\n await this.setupSidebar();\n await this.setupTopbar();\n await this.setupPageHeader();\n this.setupPortalEvents();\n }\n\n /**\n * Setup sidebar component\n */\n async setupSidebar() {\n if (!this.sidebarConfig || Object.keys(this.sidebarConfig).length === 0) return;\n\n this.sidebar = new Sidebar({\n containerId: 'portal-sidebar',\n ...this.sidebarConfig\n });\n\n await this.sidebar.render();\n }\n\n /**\n * Setup topbar component\n */\n async setupTopbar() {\n if (!this.topbarConfig || Object.keys(this.topbarConfig).length === 0) return;\n\n // Map config to TopNav format\n this.topbar = new TopNav({\n containerId: \"portal-topnav\",\n brandText: this.topbarConfig.brand || this.brand || this.title,\n brandRoute: this.topbarConfig.brandRoute || '/',\n brandIcon: this.topbarConfig.brandIcon || this.brandIcon,\n navItems: this.topbarConfig.leftItems || [],\n rightItems: this.topbarConfig.rightItems || [],\n displayMode: this.topbarConfig.displayMode || 'both',\n showSidebarToggle: this.topbarConfig.showSidebarToggle || false,\n ...this.topbarConfig\n });\n\n await this.topbar.render();\n\n // Legacy support\n this.topnav = this.topbar;\n }\n\n /**\n * Setup page header component\n */\n async setupPageHeader() {\n if (!this.showPageHeader) return;\n\n this.pageHeader = new PageHeader({\n containerId: 'page-header',\n style: this.pageHeaderConfig.style || 'default',\n showIcon: this.pageHeaderConfig.showIcon !== false,\n showDescription: this.pageHeaderConfig.showDescription !== false,\n showBreadcrumbs: this.pageHeaderConfig.showBreadcrumbs || false,\n ...this.pageHeaderConfig\n });\n\n // Render into the portal-content container\n const headerContainer = document.getElementById('page-header');\n if (headerContainer) {\n await this.pageHeader.render(true, headerContainer);\n }\n }\n\n /**\n * Setup portal event handling\n */\n setupPortalEvents() {\n // Handle sidebar toggle via event delegation\n document.addEventListener('click', (event) => {\n if (event.target.closest('[data-action=\"toggle-sidebar\"]')) {\n event.preventDefault();\n this.toggleSidebar();\n }\n });\n\n // Handle responsive changes\n if (window.ResizeObserver) {\n const resizeObserver = new ResizeObserver(() => {\n this.handleResponsive();\n });\n resizeObserver.observe(document.body);\n this._resizeObserver = resizeObserver;\n } else {\n // Fallback for older browsers\n this._resizeHandler = () => this.handleResponsive();\n window.addEventListener('resize', this._resizeHandler);\n }\n\n // Initial responsive setup\n this.handleResponsive();\n }\n\n /**\n * Toggle sidebar state\n */\n toggleSidebar() {\n if (!this.sidebar) return;\n\n const container = document.querySelector('.portal-container');\n const isMobile = this.isMobile();\n\n if (isMobile) {\n container.classList.toggle('hide-sidebar');\n } else {\n container.classList.toggle('collapse-sidebar');\n this.sidebarCollapsed = !this.sidebarCollapsed;\n\n // Save the new state\n this.saveSidebarState(this.sidebarCollapsed);\n }\n\n this.events.emit('sidebar:toggled', {\n collapsed: this.sidebarCollapsed,\n mobile: isMobile\n });\n }\n\n /**\n * Handle responsive layout\n */\n handleResponsive() {\n const container = document.querySelector('.portal-container');\n if (!container) return;\n const isMobile = this.isMobile();\n\n if (isMobile) {\n container.classList.add('mobile-layout');\n if (!container.classList.contains('hide-sidebar')) {\n container.classList.add('hide-sidebar');\n }\n } else {\n container.classList.remove('mobile-layout', 'hide-sidebar');\n }\n\n this.events.emit('responsive:changed', { mobile: isMobile });\n }\n\n getPortalContainer() {\n return document.querySelector('.portal-container');\n }\n\n isMobile() {\n return window.innerWidth < 768;\n }\n\n hasMobileLayout() {\n return this.getPortalContainer().classList.contains('mobile-layout');\n }\n\n /**\n * Override showPage to update navigation\n */\n async showPage(page, query = {}, params = {}, options = {}) {\n const result = await super.showPage(page, query, params, options);\n\n if (this.hasMobileLayout()) {\n this.getPortalContainer().classList.add('hide-sidebar');\n }\n\n if (this.currentPage) {\n this.updateNavigation(this.currentPage);\n }\n\n return result;\n }\n\n /**\n * Update navigation active states\n */\n updateNavigation(page) {\n // Update sidebar active state\n if (this.sidebar && this.sidebar.setActivePage) {\n this.sidebar.setActivePage(page.route);\n }\n\n // Update topbar active state\n if (this.topbar && this.topbar.setActivePage) {\n this.topbar.setActivePage(page.route);\n }\n\n // Update page header\n if (this.pageHeader) {\n this.pageHeader.setPage(page);\n }\n\n this.events.emit('portal:page-changed', { page });\n }\n\n /**\n * Set active user\n */\n setActiveUser(user) {\n this.activeUser = user;\n\n if (this.topbar) {\n this.topbar.setUser(user);\n }\n\n\n this.events.emit('portal:user-changed', { user });\n }\n\n /**\n * Get the active user (for backward compatibility)\n */\n getActiveUser() {\n return this.activeUser;\n }\n\n /**\n * Save sidebar state to localStorage\n */\n saveSidebarState(collapsed) {\n try {\n const key = this.getSidebarStorageKey();\n localStorage.setItem(key, JSON.stringify(collapsed));\n } catch (error) {\n console.warn('Failed to save sidebar state:', error);\n }\n }\n\n /**\n * Load sidebar state from localStorage\n */\n loadSidebarState() {\n try {\n const key = this.getSidebarStorageKey();\n const saved = localStorage.getItem(key);\n return saved !== null ? JSON.parse(saved) : null;\n } catch (error) {\n console.warn('Failed to load sidebar state:', error);\n return null;\n }\n }\n\n /**\n * Get storage key for sidebar state (allows multiple apps on same domain)\n */\n getSidebarStorageKey() {\n // Use app title/name to create unique key\n const appKey = this.title ? this.title.replace(/\\s+/g, '_').toLowerCase() : 'portal_app';\n return `${appKey}_sidebar_collapsed`;\n }\n\n /**\n * Apply saved sidebar state to the UI\n */\n applySidebarState(container = null) {\n if (!container) {\n container = document.querySelector('.portal-container');\n }\n\n if (!container) return;\n\n if (this.sidebarCollapsed) {\n container.classList.add('collapse-sidebar');\n } else {\n container.classList.remove('collapse-sidebar');\n }\n }\n\n /**\n * Clear saved sidebar state\n */\n clearSidebarState() {\n try {\n const key = this.getSidebarStorageKey();\n localStorage.removeItem(key);\n } catch (error) {\n console.warn('Failed to clear sidebar state:', error);\n }\n }\n\n async changePassword() {\n const data = await this.showForm({\n title: \"Change Password\",\n fields: [\n {\n name: 'current_password', type: 'password',\n label: 'Current Password', required: true,\n showToggle: true, // default, can omit\n strengthMeter: true,\n capsLockWarning: true,\n\n },\n {\n name: 'new_password', type: 'password', label: 'New Password', required: true,\n showToggle: true,\n passwordUsage: 'new', // sets autocomplete to 'new-password'\n\n strengthMeter: true,\n capsLockWarning: true,\n attributes: {\n // optional, override autocomplete if needed\n autocomplete: 'new-password'\n }\n },\n {\n name: 'confirm_password', type: 'password', label: 'Confirm Password', required: true,\n showToggle: true,\n passwordUsage: 'new', // sets autocomplete to 'new-password'\n\n strengthMeter: true,\n capsLockWarning: true,\n attributes: {\n // optional, override autocomplete if needed\n // autocomplete: 'new-password'\n }\n }\n ],\n submitLabel: 'Change Password'\n });\n if (data) {\n if (data.new_password === data.confirm_password) {\n // Perform password change logic here\n const resp = await this.activeUser.save(data);\n if (resp.status === 200) {\n this.toast.success('Password changed successfully');\n } else {\n this.toast.error('Failed to change password');\n }\n } else {\n this.toast.error('Passwords do not match');\n }\n }\n }\n\n onPortalAction(action) {\n switch (action.action) {\n case 'logout':\n this.tokenManager.clearTokens();\n this.rest.clearAuth();\n this.setActiveUser(null);\n break;\n case 'profile':\n this.showProfile();\n break;\n case 'change-password':\n this.changePassword();\n break;\n default:\n console.warn(`Unknown portal action: ${action}`);\n }\n }\n\n async showProfile() {\n if (!this.activeUser) {\n this.showError(\"No user is currently logged in\");\n return;\n }\n\n try {\n\n\n // Show profile edit form with automatic model saving\n const result = await Dialog.showModelForm({\n title: 'Edit Profile',\n size: 'lg',\n fileHandling: 'base64',\n model: this.activeUser,\n fields: [\n // Profile Header\n {\n type: 'header',\n text: 'Profile Information',\n level: 4,\n class: 'text-primary mb-3'\n },\n\n // Avatar and Basic Info\n {\n type: 'group',\n columns: { xs: 12, md: 4 },\n title: 'Avatar',\n fields: [\n {\n type: 'image',\n name: 'avatar',\n size: 'lg',\n imageSize: { width: 200, height: 200 },\n placeholder: 'Upload your avatar',\n help: 'Square images work best'\n }\n ]\n },\n\n // Profile Details\n {\n type: 'group',\n columns: { xs: 12, md: 8 },\n title: 'Details',\n fields: [\n {\n type: 'text',\n name: 'display_name',\n label: 'Display Name',\n required: true,\n columns: 12,\n placeholder: 'Enter first name'\n },\n {\n type: 'email',\n name: 'email',\n label: 'Email Address',\n required: true,\n columns: 8,\n placeholder: 'your.email@example.com'\n },\n {\n type: 'tel',\n name: 'phone_number',\n label: 'Phone Number',\n columns: 4,\n placeholder: '(555) 123-4567'\n },\n ]\n },\n\n // Account Settings\n {\n type: 'group',\n columns: 12,\n title: 'Account Settings',\n class: \"pt-3\",\n fields: [\n {\n type: 'select',\n name: 'timezone',\n label: 'Timezone',\n columns: 6,\n options: [\n { value: 'America/New_York', text: 'Eastern Time' },\n { value: 'America/Chicago', text: 'Central Time' },\n { value: 'America/Denver', text: 'Mountain Time' },\n { value: 'America/Los_Angeles', text: 'Pacific Time' },\n { value: 'UTC', text: 'UTC' }\n ]\n },\n {\n type: 'select',\n name: 'language',\n label: 'Language',\n columns: 6,\n options: [\n { value: 'en', text: 'English' },\n { value: 'es', text: 'Spanish' },\n { value: 'fr', text: 'French' },\n { value: 'de', text: 'German' }\n ]\n },\n {\n type: 'switch',\n name: 'email_notifications',\n label: 'Email Notifications',\n columns: 4\n },\n {\n type: 'switch',\n name: 'two_factor_enabled',\n label: 'Two-Factor Authentication',\n columns: 4\n },\n {\n type: 'switch',\n name: 'profile_public',\n label: 'Public Profile',\n columns: 4\n }\n ]\n }\n ],\n submitText: 'Save Profile',\n cancelText: 'Cancel'\n });\n\n if (result && result.success) {\n\n\n // Update active user with new data from model\n // (model should already be updated by save operation)\n\n // Show success message\n this.showSuccess('Profile updated successfully!');\n } else if (result && !result.success) {\n // Error case - already handled by Dialog.showForm\n\n }\n\n } catch (error) {\n console.error('Error showing profile form:', error);\n this.showError('Failed to load profile form');\n }\n }\n\n /**\n * Clean up portal resources\n */\n async destroy() {\n // Clean up event listeners\n // Clear active group\n this.activeGroup = null;\n\n // Clean up portal resources\n if (this._resizeObserver) {\n this._resizeObserver.disconnect();\n }\n if (this._resizeHandler) {\n window.removeEventListener('resize', this._resizeHandler);\n }\n\n // Destroy components using View lifecycle\n if (this.topbar) {\n await this.topbar.destroy();\n this.topbar = null;\n this.topnav = null;\n }\n\n if (this.sidebar) {\n await this.sidebar.destroy();\n this.sidebar = null;\n }\n\n // Call parent destroy\n await super.destroy();\n }\n\n /**\n * Static factory method\n */\n static create(config = {}) {\n return new PortalApp(config);\n }\n}\n","/**\n * MustacheFormatter - Mustache wrapper for MOJO Framework\n * \n * This is now a thin wrapper around Mustache.js since pipe formatting\n * is handled directly in Model.get() and View.get() via MOJOUtils.\n * \n * The wrapper is maintained for backward compatibility and to provide\n * a consistent API for template rendering throughout the framework.\n */\n\nimport mustache from './mustache.js';\nimport dataFormatter from './DataFormatter.js';\n\nclass MustacheFormatter {\n constructor() {\n this.formatter = dataFormatter;\n this.compiledTemplates = new Map();\n }\n\n /**\n * Render template with data\n * Pipes are now handled by Model.get() and View.get() automatically\n * \n * @param {string} template - Mustache template\n * @param {object} data - Data to render (View, Model, or plain object)\n * @param {object} partials - Mustache partials\n * @returns {string} Rendered template\n */\n render(template, data, partials = {}) {\n // Simply pass through to Mustache\n // If data has a get() method, Mustache will use it automatically\n return mustache.render(template, data, partials);\n }\n\n /**\n * Compile template for reuse\n * @param {string} template - Template to compile\n * @returns {object} Compiled template tokens\n */\n compile(template) {\n const compiled = mustache.parse(template);\n this.compiledTemplates.set(template, compiled);\n return compiled;\n }\n\n /**\n * Render with compiled template\n * @param {object} compiled - Compiled template tokens\n * @param {object} data - Data to render\n * @param {object} partials - Mustache partials\n * @returns {string} Rendered template\n */\n renderCompiled(compiled, data, partials = {}) {\n return mustache.render(compiled, data, partials);\n }\n\n /**\n * Clear compiled template cache\n */\n clearCache() {\n this.compiledTemplates.clear();\n mustache.clearCache();\n }\n\n /**\n * Process and cache a template\n * @param {string} key - Cache key\n * @param {string} template - Template to cache\n * @returns {object} Cached template info\n */\n cache(key, template) {\n const compiled = this.compile(template);\n return { key, template, compiled };\n }\n\n /**\n * Get cached template\n * @param {string} key - Cache key\n * @returns {object|null} Cached template info or null\n */\n getCached(key) {\n for (const [template, compiled] of this.compiledTemplates) {\n if (template === key || compiled === key) {\n return { key, template, compiled };\n }\n }\n return null;\n }\n\n /**\n * Register a custom formatter with DataFormatter\n * @param {string} name - Formatter name\n * @param {function} formatter - Formatter function\n * @returns {MustacheFormatter} This instance for chaining\n */\n registerFormatter(name, formatter) {\n this.formatter.register(name, formatter);\n return this;\n }\n\n /**\n * Check if a string contains pipe syntax\n * @param {string} template - Template string to check\n * @returns {boolean} True if contains pipes\n */\n hasPipes(template) {\n return /\\{\\{[{]?[^}|]+\\|[^}]+\\}[}]?\\}/.test(template);\n }\n\n /**\n * Pre-process data with pipe formatters\n * This is now handled automatically by get() methods, but kept for backward compatibility\n * \n * @param {object} data - Data object\n * @param {object} pipes - Object mapping keys to pipe strings\n * @returns {object} Processed data\n */\n processData(data, pipes) {\n const processed = { ...data };\n \n for (const [key, pipeString] of Object.entries(pipes)) {\n // If data has a get method, use it (which will handle pipes)\n if (data && typeof data.get === 'function') {\n processed[key] = data.get(`${key}|${pipeString}`);\n } else {\n // For plain objects, apply formatter directly\n const value = this.getValueFromPath(data, key);\n processed[key] = this.formatter.pipe(value, pipeString);\n }\n }\n \n return processed;\n }\n\n /**\n * Get value from object using dot notation path\n * Kept for backward compatibility, but MOJOUtils.getContextData is preferred\n * \n * @param {object} obj - Source object\n * @param {string} path - Dot notation path\n * @returns {*} Value at path\n */\n getValueFromPath(obj, path) {\n if (!obj || !path) return undefined;\n \n // If obj has a get method, use it\n if (obj && typeof obj.get === 'function') {\n return obj.get(path);\n }\n \n // Otherwise use standard property navigation\n const keys = path.split('.');\n let current = obj;\n \n for (const key of keys) {\n if (current === null || current === undefined) {\n return undefined;\n }\n \n // Handle array index\n if (!isNaN(key) && Array.isArray(current)) {\n current = current[parseInt(key)];\n } else {\n current = current[key];\n }\n }\n \n return current;\n }\n\n /**\n * Process template to handle pipe formatters\n * @deprecated Pipes are now handled by get() methods automatically\n * @param {string} template - Original template\n * @param {object} data - Original data\n * @returns {object} {template: processedTemplate, data: processedData}\n */\n processTemplate(template, data) {\n // For backward compatibility, just return as-is\n // Pipes will be handled by get() methods during Mustache rendering\n return { template, data };\n }\n}\n\n// Create singleton instance\nconst mustacheFormatter = new MustacheFormatter();\n\n// Export both class and instance\nexport { MustacheFormatter };\nexport default mustacheFormatter;","/**\n * MOJO Framework - Core Entry (2.1.0)\n */\n\n// Bundle core CSS\nimport '@core/css/core.css';\nimport '@core/css/portal.css';\nimport '@core/css/table.css';\nimport '@core/css/toast.css';\nimport '@core/css/chat.css';\n\nimport ConsoleSilencer from '@core/utils/ConsoleSilencer.js';\n// Reduce console noise globally: errors only by default (suppress logs, info, and warnings)\nConsoleSilencer.install({ level: 'warn' });\n\n// Version info\nexport {\n VERSION_INFO,\n VERSION,\n VERSION_MAJOR,\n VERSION_MINOR,\n VERSION_REVISION,\n BUILD_TIME\n} from './version.js';\n\n// Core runtime\nexport { default as View } from '@core/View.js';\nexport { default as Page } from '@core/Page.js';\nexport { default as Router } from '@core/Router.js';\nexport { default as Model } from '@core/Model.js';\nexport { default as Collection } from '@core/Collection.js';\nexport { default as Rest } from '@core/Rest.js';\n\n// Core Models - re-export everything from models/\nexport * from '@core/models/AWS.js';\nexport * from '@core/models/Email.js';\nexport * from '@core/models/Files.js';\nexport * from '@core/models/Group.js';\nexport * from '@core/models/Incident.js';\nexport * from '@core/models/Job.js';\nexport * from '@core/models/JobRunner.js';\nexport * from '@core/models/Log.js';\nexport * from '@core/models/Member.js';\nexport * from '@core/models/Metrics.js';\nexport * from '@core/models/Push.js';\nexport * from '@core/models/System.js';\nexport * from '@core/models/Tickets.js';\nexport * from '@core/models/User.js';\n\n// App classes\nexport { default as WebApp } from '@core/WebApp.js';\nexport { default as PortalApp } from '@core/PortalApp.js';\n\n// UI helper\nexport { default as Dialog } from '@core/views/feedback/Dialog.js';\n\n// Selected views (curated for tree-shaking)\nexport { default as TableView } from '@core/views/table/TableView.js';\nexport { default as TableRow } from '@core/views/table/TableRow.js';\nexport { default as TablePage } from '@core/pages/TablePage.js';\nexport { default as ListView } from '@core/views/list/ListView.js';\nexport { default as ListViewItem } from '@core/views/list/ListViewItem.js';\nexport { default as TopNav } from '@core/views/navigation/TopNav.js';\nexport { default as Sidebar } from '@core/views/navigation/Sidebar.js';\nexport { default as TabView } from '@core/views/navigation/TabView.js';\nexport { default as SimpleSearchView } from '@core/views/navigation/SimpleSearchView.js';\nexport { default as DataView } from '@core/views/data/DataView.js';\nexport { default as FormView } from '@core/forms/FormView.js';\nexport { default as FilePreviewView } from '@core/views/data/FilePreviewView.js';\nexport { default as ChatView } from '@core/views/chat/ChatView.js';\nexport { default as ChatMessageView } from '@core/views/chat/ChatMessageView.js';\nexport { default as ChatInputView } from '@core/views/chat/ChatInputView.js';\n\n// Services, utils, mixins\nexport { default as FileUpload } from '@core/services/FileUpload.js';\nexport { default as applyFileDropMixin } from '@core/mixins/FileDropMixin.js';\nexport { default as TokenManager } from '@core/services/TokenManager.js';\nexport { default as ToastService } from '@core/services/ToastService.js';\nexport { default as WebSocketClient } from '@core/services/WebSocketClient.js';\nexport { default as EventDelegate } from '@core/mixins/EventDelegate.js';\nexport { default as EventBus } from '@core/utils/EventBus.js';\nexport { default as dataFormatter } from '@core/utils/DataFormatter.js';\nexport { default as MustacheFormatter } from '@core/utils/MustacheFormatter.js';\nexport { default as MOJOUtils, DataWrapper } from '@core/utils/MOJOUtils.js';\nexport { default as ConsoleSilencer } from '@core/utils/ConsoleSilencer.js';\nexport { installConsoleSilencer } from '@core/utils/ConsoleSilencer.js';\nexport { default as DjangoLookups, parseFilterKey, formatFilterDisplay, LOOKUPS } from '@core/utils/DjangoLookups.js';\n\n// Additional views\nexport { default as ProgressView } from '@core/views/feedback/ProgressView.js';\nexport { default as ContextMenu } from '@core/views/feedback/ContextMenu.js';\n\n// Names\nexport const FRAMEWORK_NAME = 'MOJO';\nexport const PACKAGE_NAME = 'web-mojo';\n\nexport default {\n FRAMEWORK_NAME,\n PACKAGE_NAME,\n};\n"],"names":["k","v","i","a","b","index","s","j","r","groupKind","e","mustache"],"mappings":"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"}
|