web-mojo 2.2.4 → 2.2.5

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.
Files changed (72) hide show
  1. package/dist/admin.cjs.js +1 -1
  2. package/dist/admin.es.js +12 -12
  3. package/dist/auth.cjs.js +1 -1
  4. package/dist/auth.es.js +1 -1
  5. package/dist/charts.cjs.js +1 -1
  6. package/dist/charts.es.js +4 -4
  7. package/dist/chunks/{ChatView-DZ7f2Rl5.js → ChatView-0zfOatg-.js} +7 -7
  8. package/dist/chunks/{ChatView-DZ7f2Rl5.js.map → ChatView-0zfOatg-.js.map} +1 -1
  9. package/dist/chunks/{ChatView-DoA8h81E.js → ChatView-B2STE47I.js} +2 -2
  10. package/dist/chunks/{ChatView-DoA8h81E.js.map → ChatView-B2STE47I.js.map} +1 -1
  11. package/dist/chunks/{Collection-CREl6Fa9.js → Collection-BgX6OcUC.js} +2 -2
  12. package/dist/chunks/{Collection-CREl6Fa9.js.map → Collection-BgX6OcUC.js.map} +1 -1
  13. package/dist/chunks/{Collection-DJaa8dhS.js → Collection-G5_fJcpB.js} +2 -2
  14. package/dist/chunks/{Collection-DJaa8dhS.js.map → Collection-G5_fJcpB.js.map} +1 -1
  15. package/dist/chunks/{ContextMenu-DvsDXgOe.js → ContextMenu-C4_MWleT.js} +2 -2
  16. package/dist/chunks/{ContextMenu-DvsDXgOe.js.map → ContextMenu-C4_MWleT.js.map} +1 -1
  17. package/dist/chunks/{ContextMenu-CvLNRuJb.js → ContextMenu-CMoik8q6.js} +3 -3
  18. package/dist/chunks/{ContextMenu-CvLNRuJb.js.map → ContextMenu-CMoik8q6.js.map} +1 -1
  19. package/dist/chunks/{DataView-Bm8dffDn.js → DataView-BYNjIf--.js} +2 -2
  20. package/dist/chunks/{DataView-Bm8dffDn.js.map → DataView-BYNjIf--.js.map} +1 -1
  21. package/dist/chunks/{DataView-gc1VouWJ.js → DataView-i7kpJjVQ.js} +2 -2
  22. package/dist/chunks/{DataView-gc1VouWJ.js.map → DataView-i7kpJjVQ.js.map} +1 -1
  23. package/dist/chunks/{Dialog-Cl_rBFSh.js → Dialog-C-Xl4SYW.js} +2 -2
  24. package/dist/chunks/{Dialog-Cl_rBFSh.js.map → Dialog-C-Xl4SYW.js.map} +1 -1
  25. package/dist/chunks/{Dialog-LPU__Q7Z.js → Dialog-D_TcKXUc.js} +5 -5
  26. package/dist/chunks/{Dialog-LPU__Q7Z.js.map → Dialog-D_TcKXUc.js.map} +1 -1
  27. package/dist/chunks/{FormView-DMMUiciW.js → FormView-DCtLjTmF.js} +2 -2
  28. package/dist/chunks/{FormView-DMMUiciW.js.map → FormView-DCtLjTmF.js.map} +1 -1
  29. package/dist/chunks/{FormView-Cc5iagqS.js → FormView-UtTgxKhq.js} +2 -2
  30. package/dist/chunks/{FormView-Cc5iagqS.js.map → FormView-UtTgxKhq.js.map} +1 -1
  31. package/dist/chunks/{ListView-Xcsfu4IL.js → ListView-9b-jQTQZ.js} +2 -2
  32. package/dist/chunks/{ListView-Xcsfu4IL.js.map → ListView-9b-jQTQZ.js.map} +1 -1
  33. package/dist/chunks/{ListView-8FqhYWRU.js → ListView-C9OoIPfC.js} +3 -3
  34. package/dist/chunks/{ListView-8FqhYWRU.js.map → ListView-C9OoIPfC.js.map} +1 -1
  35. package/dist/chunks/{MetricsMiniChartWidget-CsawNLeS.js → MetricsMiniChartWidget-CJZo6Mzi.js} +4 -4
  36. package/dist/chunks/{MetricsMiniChartWidget-CsawNLeS.js.map → MetricsMiniChartWidget-CJZo6Mzi.js.map} +1 -1
  37. package/dist/chunks/{MetricsMiniChartWidget-BuvhT5NG.js → MetricsMiniChartWidget-DDDtbxVu.js} +2 -2
  38. package/dist/chunks/{MetricsMiniChartWidget-BuvhT5NG.js.map → MetricsMiniChartWidget-DDDtbxVu.js.map} +1 -1
  39. package/dist/chunks/{PDFViewer-Dr72gJt1.js → PDFViewer-BGvS4SV2.js} +3 -3
  40. package/dist/chunks/{PDFViewer-Dr72gJt1.js.map → PDFViewer-BGvS4SV2.js.map} +1 -1
  41. package/dist/chunks/{PDFViewer-Bg06w3Cu.js → PDFViewer-CBMSMWI8.js} +2 -2
  42. package/dist/chunks/{PDFViewer-Bg06w3Cu.js.map → PDFViewer-CBMSMWI8.js.map} +1 -1
  43. package/dist/chunks/{Rest-BoKp2Hj4.js → Rest-ChN4Ntac.js} +97 -14
  44. package/dist/chunks/Rest-ChN4Ntac.js.map +1 -0
  45. package/dist/chunks/Rest-DhD-U1vp.js +2 -0
  46. package/dist/chunks/Rest-DhD-U1vp.js.map +1 -0
  47. package/dist/chunks/{TokenManager-BoolOcxQ.js → TokenManager-BCgqjJTM.js} +5 -5
  48. package/dist/chunks/{TokenManager-BoolOcxQ.js.map → TokenManager-BCgqjJTM.js.map} +1 -1
  49. package/dist/chunks/{TokenManager-Bh1WshcR.js → TokenManager-sw1FUivr.js} +2 -2
  50. package/dist/chunks/{TokenManager-Bh1WshcR.js.map → TokenManager-sw1FUivr.js.map} +1 -1
  51. package/dist/chunks/{WebSocketClient-DcJBT-iB.js → WebSocketClient-JHjYcYbU.js} +2 -2
  52. package/dist/chunks/{WebSocketClient-DcJBT-iB.js.map → WebSocketClient-JHjYcYbU.js.map} +1 -1
  53. package/dist/chunks/{WebSocketClient-Do0CazHx.js → WebSocketClient-bLYhu2Wv.js} +2 -2
  54. package/dist/chunks/{WebSocketClient-Do0CazHx.js.map → WebSocketClient-bLYhu2Wv.js.map} +1 -1
  55. package/dist/chunks/{version-Bado0p82.js → version-URMnesIW.js} +2 -2
  56. package/dist/chunks/{version-Bado0p82.js.map → version-URMnesIW.js.map} +1 -1
  57. package/dist/chunks/{version-_FYWwpG_.js → version-kqYGrCKv.js} +4 -4
  58. package/dist/chunks/{version-_FYWwpG_.js.map → version-kqYGrCKv.js.map} +1 -1
  59. package/dist/docit.cjs.js +1 -1
  60. package/dist/docit.es.js +6 -6
  61. package/dist/index.cjs.js +1 -1
  62. package/dist/index.es.js +15 -15
  63. package/dist/lightbox.cjs.js +1 -1
  64. package/dist/lightbox.es.js +5 -5
  65. package/dist/map.cjs.js +1 -1
  66. package/dist/map.es.js +2 -2
  67. package/dist/timeline.cjs.js +1 -1
  68. package/dist/timeline.es.js +4 -4
  69. package/package.json +1 -1
  70. package/dist/chunks/Rest-29RtA7pe.js +0 -2
  71. package/dist/chunks/Rest-29RtA7pe.js.map +0 -1
  72. package/dist/chunks/Rest-BoKp2Hj4.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ContextMenu-DvsDXgOe.js","sources":["../../src/core/Page.js","../../src/core/models/Group.js","../../src/core/models/User.js","../../src/core/views/feedback/ContextMenu.js","../../src/core/services/ToastService.js"],"sourcesContent":["/**\n * Page - Extends View with routing capabilities for MOJO framework\n * Handles URL routing, parameters, and page-specific actions\n *\n * Event Emitter notes:\n * - Uses EventEmitter via View base class.\n * - Use .emit/.on/.off/.once for all custom events.\n */\n\nimport View from '@core/View.js';\n\nclass Page extends View {\n constructor(options = {}) {\n // Set default tag name for pages\n options.tagName = options.tagName || 'main';\n options.className = options.className || 'mojo-page';\n\n // Set page ID based on page name\n const pageName = options.pageName || '';\n if (pageName && !options.id) {\n options.id = 'page_' + pageName.toLowerCase().replace(/\\s+/g, '_');\n }\n\n super(options);\n\n // Core page properties from design doc\n this.pageName = options.pageName || this.constructor.pageName || '';\n this.route = options.route || this.constructor.route || '';\n this.title = options.title || this.pageName || '';\n\n // Set page ID if not already set and we have a page_name from constructor\n if (!this.id && this.constructor.pageName && !options.pageName) {\n this.id = 'page_' + this.constructor.pageName.toLowerCase().replace(/\\s+/g, '_');\n }\n\n // Page metadata for event system\n this.pageIcon = options.icon || options.pageIcon || this.constructor.pageIcon || 'bi bi-file-text';\n this.displayName = options.displayName || this.constructor.displayName || this.pageName || '';\n this.pageDescription = options.pageDescription || this.constructor.pageDescription || '';\n\n // Routing state\n this.params = {};\n this.query = {};\n this.matched = false;\n this.isActive = false;\n\n // Page-specific options\n this.pageOptions = {\n title: options.title || this.pageName || 'Untitled Page',\n description: options.description || '',\n requiresAuth: options.requiresAuth || false,\n ...options.pageOptions\n };\n\n // State preservation\n this.savedState = null;\n\n console.log(`Page ${this.pageName} constructed with route: ${this.route}`);\n }\n\n /**\n * Handle route parameters - from design doc\n * @param {object} params - Route parameters\n * @param {object} query - Query string parameters\n */\n async onParams(params = {}, query = {}) {\n // const paramsChanged = JSON.stringify(params) !== JSON.stringify(this.params);\n // const queryChanged = JSON.stringify(query) !== JSON.stringify(this.query);\n\n this.params = params;\n this.query = query;\n\n // Only re-render if params actually changed and page is active\n // if (this.isActive && (paramsChanged || queryChanged)) {\n // console.log(`Page ${this.pageName} params changed, re-rendering`);\n // await this.render();\n // }\n }\n\n canEnter() {\n if (this.options.permissions) {\n const user = this.getApp().activeUser;\n if (!user || !user.hasPermission(this.options.permissions)) {\n return false;\n }\n }\n if (this.options.requiresGroup && !this.getApp().activeGroup) {\n return false;\n }\n return true;\n }\n\n /**\n * Called when entering this page (before render)\n * Override this method for initialization logic\n */\n async onEnter() {\n this.isActive = true;\n await this.onInitView();\n\n // Restore saved state if exists\n if (this.savedState) {\n this.restoreState(this.savedState);\n this.savedState = null;\n }\n\n // Set page title if provided\n if (this.pageOptions && this.pageOptions.title && typeof document !== 'undefined') {\n document.title = this.pageOptions.title;\n }\n\n // Emit activation event\n this.emit('activated', {\n page: this.getMetadata()\n });\n\n console.log(`Page ${this.pageName} entered`);\n }\n\n /**\n * Called when leaving this page (before cleanup)\n * Override this method for cleanup logic like removing listeners, clearing timers, etc.\n */\n async onExit() {\n // Save state before exit\n this.savedState = this.captureState();\n this.isActive = false;\n\n // Emit deactivation event\n this.emit('deactivated', {\n page: this.getMetadata()\n });\n console.log(`Page ${this.pageName} exiting`);\n }\n\n /**\n * Get page metadata for display and events\n * @returns {object} Page metadata\n */\n getMetadata() {\n return {\n name: this.pageName,\n displayName: this.displayName || this.pageName,\n icon: this.pageIcon,\n description: this.pageDescription,\n route: this.route,\n isActive: this.isActive\n };\n }\n\n /**\n * Handle default action - fallback from design doc\n */\n async onActionDefault(action) {\n console.log(`Default action '${action}' triggered on page: ${this.pageName}`);\n }\n\n async makeActive() {\n this.getApp().showPage(this);\n }\n\n async onActionNavigate(event, element) {\n event.preventDefault();\n const page = element.dataset.page;\n this.getApp().showPage(page);\n }\n\n /**\n * Capture current page state for preservation\n * @returns {object|null} Captured state\n */\n captureState() {\n if (!this.element) return null;\n\n return {\n scrollTop: this.element.scrollTop,\n formData: this.captureFormData(),\n custom: this.captureCustomState()\n };\n }\n\n /**\n * Restore saved state\n * @param {object} state - State to restore\n */\n restoreState(state) {\n if (!state || !this.element) return;\n\n this.element.scrollTop = state.scrollTop || 0;\n this.restoreFormData(state.formData);\n if (state.custom) {\n this.restoreCustomState(state.custom);\n }\n }\n\n /**\n * Capture form data from page\n * @returns {object} Form data\n */\n captureFormData() {\n const data = {};\n if (!this.element) return data;\n\n this.element.querySelectorAll('input, select, textarea').forEach(field => {\n if (field.name) {\n if (field.type === 'checkbox') {\n data[field.name] = field.checked;\n } else if (field.type === 'radio') {\n if (field.checked) {\n data[field.name] = field.value;\n }\n } else {\n data[field.name] = field.value;\n }\n }\n });\n\n return data;\n }\n\n /**\n * Restore form data to page\n * @param {object} formData - Form data to restore\n */\n restoreFormData(formData) {\n if (!formData || !this.element) return;\n\n Object.entries(formData).forEach(([name, value]) => {\n const field = this.element.querySelector(`[name=\"${name}\"]`);\n if (field) {\n if (field.type === 'checkbox') {\n field.checked = value;\n } else if (field.type === 'radio') {\n const radio = this.element.querySelector(`[name=\"${name}\"][value=\"${value}\"]`);\n if (radio) radio.checked = true;\n } else {\n field.value = value;\n }\n }\n });\n }\n\n /**\n * Capture custom state - override in subclasses\n * @returns {object} Custom state\n */\n captureCustomState() {\n return {};\n }\n\n /**\n * Restore custom state - override in subclasses\n * @param {object} state - Custom state to restore\n */\n restoreCustomState(state) {\n // Override in subclasses\n }\n\n\n\n /**\n * Set page metadata\n * @param {object} meta - Metadata object\n */\n setMeta(meta = {}) {\n if (typeof document === 'undefined') {\n return;\n }\n\n // Set title\n if (meta.title) {\n document.title = meta.title;\n this.pageOptions.title = meta.title;\n }\n\n // Set description\n if (meta.description) {\n let descMeta = document.querySelector('meta[name=\"description\"]');\n if (!descMeta) {\n descMeta = document.createElement('meta');\n descMeta.name = 'description';\n document.head.appendChild(descMeta);\n }\n descMeta.content = meta.description;\n this.pageOptions.description = meta.description;\n }\n\n // Set other meta tags\n Object.entries(meta).forEach(([key, value]) => {\n if (key !== 'title' && key !== 'description') {\n let metaEl = document.querySelector(`meta[name=\"${key}\"]`);\n if (!metaEl) {\n metaEl = document.createElement('meta');\n metaEl.name = key;\n document.head.appendChild(metaEl);\n }\n metaEl.content = value;\n }\n });\n }\n\n\n /**\n * Show error message with page context\n * @param {string} message - Error message\n */\n showError(message) {\n super.showError(message);\n\n // Page-specific error display can be implemented here\n if (this.element) {\n // Example: Add error to page\n const errorDiv = document.createElement('div');\n errorDiv.className = 'alert alert-danger alert-dismissible fade show';\n errorDiv.innerHTML = `\n ${message}\n <button type=\"button\" class=\"btn-close\" data-bs-dismiss=\"alert\" aria-label=\"Close\"></button>\n `;\n\n // Insert at top of page\n this.element.insertBefore(errorDiv, this.element.firstChild);\n\n // Auto-remove after 5 seconds\n setTimeout(() => {\n if (errorDiv.parentNode) {\n errorDiv.parentNode.removeChild(errorDiv);\n }\n }, 5000);\n }\n }\n\n /**\n * Show success message with page context\n * @param {string} message - Success message\n */\n showSuccess(message) {\n super.showSuccess(message);\n\n // Page-specific success display\n if (this.element) {\n const successDiv = document.createElement('div');\n successDiv.className = 'alert alert-success alert-dismissible fade show';\n successDiv.innerHTML = `\n ${message}\n <button type=\"button\" class=\"btn-close\" data-bs-dismiss=\"alert\" aria-label=\"Close\"></button>\n `;\n\n // Insert at top of page\n this.element.insertBefore(successDiv, this.element.firstChild);\n\n // Auto-remove after 3 seconds\n setTimeout(() => {\n if (successDiv.parentNode) {\n successDiv.parentNode.removeChild(successDiv);\n }\n }, 3000);\n }\n }\n\n /**\n * Page-specific before render hook\n */\n async onBeforeRender() {\n await super.onBeforeRender();\n\n // Set page metadata before rendering\n this.setMeta({\n title: this.pageOptions.title,\n description: this.pageOptions.description\n });\n }\n\n /**\n * Page-specific after mount hook\n */\n async onAfterMount() {\n await super.onAfterMount();\n\n // Add page-specific class to body\n if (typeof document !== 'undefined' && this.pageName) {\n document.body.classList.add(`page-${this.pageName.toLowerCase().replace(/\\s+/g, '-')}`);\n }\n }\n\n /**\n * Page-specific before destroy hook\n */\n async onBeforeDestroy() {\n await super.onBeforeDestroy();\n\n // Remove page-specific class from body\n if (typeof document !== 'undefined' && this.pageName) {\n document.body.classList.remove(`page-${this.pageName.toLowerCase().replace(/\\s+/g, '-')}`);\n }\n }\n\n /**\n * Navigate to another page using the app's router\n * @param {string} route - Route to navigate to\n * @param {object} params - Route parameters\n * @param {object} options - Navigation options\n */\n navigate(route, params = {}, options = {}) {\n // Delegate to app's router\n if (this.app && this.app.router) {\n return this.app.router.navigate(route, options);\n }\n\n // Fallback to MOJO global router\n if (typeof window !== 'undefined' && window.MOJO?.router) {\n return window.MOJO.router.navigate(route, options);\n }\n\n console.error('No router available for navigation');\n }\n\n getRoute() {\n if (this.route) {\n let route = this.route;\n if (typeof route === 'string' && route.startsWith('/')) {\n route = route.substring(1);\n }\n return route;\n }\n return this.pageName;\n }\n\n syncUrl(force = true) {\n this.updateBrowserUrl(this.query, false, false);\n }\n\n updateBrowserUrl(query = null, replace = false, trigger = false) {\n this.getApp();\n // we need to do this to normalize the URL\n // const targetPath = this.app.buildPagePath(this, this.params, query);\n // const { pageName, queryParams } = this.app.router.parseInput(targetPath);\n this.app.router.updateBrowserUrl(this.getRoute(), query, replace, trigger);\n }\n\n /**\n * Static method to define a page class with metadata\n * @param {object} definition - Page class definition\n * @returns {class} Page class\n */\n static define(definition) {\n class DefinedPage extends Page {\n constructor(options = {}) {\n super({\n ...definition,\n ...options\n });\n }\n }\n\n // Copy static properties\n DefinedPage.template = definition.template;\n DefinedPage.pageName = definition.pageName;\n DefinedPage.route = definition.route;\n\n return DefinedPage;\n }\n}\n\nexport default Page;\n","\nimport Collection from '@core/Collection.js';\nimport Model from '@core/Model.js';\n\n/**\n * Group Model - Represents an organization, team, or group entity\n *\n * Features:\n * - Hierarchical group support (parent/child relationships)\n * - Member management\n * - Search and filtering capabilities\n * - Role-based permissions within groups\n * - Metadata and settings management\n */\nclass Group extends Model {\n constructor(data = {}) {\n super(data, {\n endpoint: '/api/group'\n });\n }\n}\n\n/**\n * GroupCollection - Enhanced collection for managing groups with advanced search and filtering\n */\nclass GroupList extends Collection {\n constructor(options = {}) {\n super({\n ModelClass: Group,\n endpoint: '/api/group',\n size: 10,\n ...options\n });\n }\n}\n\nconst GroupKinds = {\n 'org': 'Organization',\n 'division': 'Division',\n 'department': 'Department',\n 'team': 'Team',\n 'merchant': 'Merchant',\n 'partner': 'Partner',\n 'client': 'Client',\n 'iso': 'ISO',\n 'sales': 'Sales',\n 'reseller': 'Reseller',\n 'location': 'Location',\n 'region': 'Region',\n 'route': 'Route',\n 'project': 'Project',\n \"inventory\": \"Inventory\",\n 'test': 'Testing',\n 'misc': 'Miscellaneous',\n 'qa': 'Quality Assurance'\n};\n\n// Convert GroupKinds to select options\nconst GroupKindOptions = Object.entries(GroupKinds).map(([key, label]) => ({\n value: key,\n label: label\n}));\n\n/**\n * Form configurations for group management\n */\nconst GroupForms = {\n create: {\n title: 'Create Group',\n fields: [\n {\n name: 'name',\n type: 'text',\n label: 'Group Name',\n required: true,\n placeholder: 'Enter group name'\n },\n {\n name: 'kind',\n type: 'select',\n label: 'Group Kind',\n required: true,\n options: GroupKindOptions\n },\n {\n type: 'collection',\n name: 'parent',\n label: 'Parent Group',\n Collection: GroupList, // Collection class\n labelField: 'name', // Field to display in dropdown\n valueField: 'id', // Field to use as value\n maxItems: 10, // Max items to show in dropdown\n placeholder: 'Search groups...',\n emptyFetch: false,\n debounceMs: 300, // Search debounce delay\n }\n ]\n },\n\n edit: {\n title: 'Edit Group',\n fields: [\n {\n name: 'name',\n type: 'text',\n label: 'Group Name',\n required: true,\n placeholder: 'Enter group name',\n },\n {\n name: 'kind',\n type: 'select',\n label: 'Group Kind',\n required: true,\n options: GroupKindOptions\n },\n {\n type: 'collection',\n name: 'parent',\n label: 'Parent Group',\n Collection: GroupList, // Collection class\n labelField: 'name', // Field to display in dropdown\n valueField: 'id', // Field to use as value\n maxItems: 10, // Max items to show in dropdown\n placeholder: 'Search groups...',\n emptyFetch: false,\n debounceMs: 300, // Search debounce delay\n },\n {\n name: 'metadata.domain',\n type: 'text',\n label: 'Default Domain',\n placeholder: 'Enter Domain',\n },\n {\n name: 'metadata.portal',\n type: 'text',\n label: 'Default Portal',\n placeholder: 'Enter Portal URL',\n },\n {\n name: 'is_active',\n type: 'switch',\n label: 'Is Active',\n cols: 4\n },\n ]\n },\n\n detailed: {\n title: 'Group Details',\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 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 columns: 12\n },\n {\n name: 'is_active',\n type: 'switch',\n label: 'Is Active',\n columns: 12\n },\n ]\n },\n\n // Profile Details\n {\n type: 'group',\n columns: { xs: 12, md: 8 },\n title: 'Details',\n fields: [\n {\n name: 'name',\n type: 'text',\n label: 'Group Name',\n required: true,\n placeholder: 'Enter group name',\n columns: 12\n },\n {\n name: 'kind',\n type: 'select',\n label: 'Group Kind',\n required: true,\n columns: 12,\n options: [\n { value: 'org', label: 'Organization' },\n { value: 'team', label: 'Team' },\n { value: 'department', label: 'Department' },\n { value: 'merchant', label: 'Merchant' },\n { value: 'iso', label: 'ISO' },\n { value: 'group', label: 'Group' }\n ]\n },\n {\n type: 'collection',\n name: 'parent',\n label: 'Parent Group',\n Collection: GroupList, // Collection class\n labelField: 'name', // Field to display in dropdown\n valueField: 'id', // Field to use as value\n maxItems: 10, // Max items to show in dropdown\n placeholder: 'Search groups...',\n emptyFetch: false,\n debounceMs: 300, // Search debounce delay\n columns: 12\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: 'metadata.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: 'metadata.eod_hour',\n label: 'End of Day Hour',\n columns: 6,\n options: [\n { value: 0, text: 'Midnight' },\n { value: 1, text: '1 AM' },\n { value: 2, text: '2 AM' },\n { value: 3, text: '3 AM' },\n { value: 4, text: '4 AM' },\n { value: 5, text: '5 AM' },\n { value: 6, text: '6 AM' },\n { value: 7, text: '7 AM' },\n { value: 8, text: '8 AM' },\n { value: 9, text: '9 AM' },\n { value: 10, text: '10 AM' },\n { value: 11, text: '11 AM' },\n { value: 12, text: '12 PM' },\n { value: 13, text: '1 PM' },\n { value: 14, text: '2 PM' },\n { value: 15, text: '3 PM' },\n { value: 16, text: '4 PM' },\n { value: 17, text: '5 PM' },\n { value: 18, text: '6 PM' },\n { value: 19, text: '7 PM' },\n { value: 20, text: '8 PM' },\n { value: 21, text: '9 PM' },\n { value: 22, text: '10 PM' },\n { value: 23, text: '11 PM' }\n ]\n }\n ]\n },\n {\n type: \"text\",\n label: \"Email Template (Prefix)\",\n name: \"metadata.email_template\",\n columns: 12\n }\n ]\n },\n};\n\nGroup.EDIT_FORM = GroupForms.edit;\nGroup.ADD_FORM = GroupForms.create;\nGroup.CREATE_FORM = GroupForms.create; // Alias for compatibility\nGroup.GroupKindOptions = GroupKindOptions;\nGroup.GroupKinds = GroupKinds;\nexport { Group, GroupList, GroupForms };\n","import Collection from '@core/Collection.js';\nimport Model from '@core/Model.js';\n\nimport { GroupList } from './Group.js';\n\nclass User extends Model {\n constructor(data = {}) {\n super(data, {\n endpoint: '/api/user'\n });\n }\n\n hasPermission(permission) {\n if (Array.isArray(permission)) {\n return permission.some(p => this.hasPermission(p));\n }\n\n // Check if permission has \"sys.\" prefix\n const isSysPermission = permission.startsWith('sys.');\n const permissionToCheck = isSysPermission ? permission.substring(4) : permission;\n\n if (this._hasPermission(permissionToCheck)) {\n return true;\n }\n\n // Only check member permissions if it's not a system permission\n if (!isSysPermission && this.member && this.member.hasPermission(permission)) {\n return true;\n }\n\n return false;\n }\n\n _hasPermission(permission) {\n const permissions = this.get(\"permissions\");\n if (!permissions) {\n return false;\n }\n return permissions[permission] == true;\n }\n\n hasPerm(p) {\n return this.hasPermission(p);\n }\n}\n\nclass UserList extends Collection {\n constructor(options = {}) {\n super({\n ModelClass: User,\n endpoint: '/api/user',\n ...options\n });\n }\n}\n\nUser.PERMISSIONS = [\n { name: \"manage_users\", label: \"Manage Users\" },\n { name: \"view_users\", label: \"View Users\" },\n { name: \"view_groups\", label: \"View Groups\" },\n { name: \"manage_groups\", label: \"Manage Groups\" },\n { name: \"view_metrics\", label: \"View System Metrics\" },\n { name: \"manage_metrics\", label: \"Manage System Metrics\" },\n { name: \"view_logs\", label: \"View Logs\" },\n { name: \"view_incidents\", label: \"View Incidents\" },\n { name: \"manage_incidents\", label: \"Manage Incidents\" },\n { name: \"view_tickets\", label: \"View Tickets\" },\n { name: \"manage_tickets\", label: \"Manage Tickets\" },\n { name: \"view_admin\", label: \"View Admin\" },\n { name: \"view_jobs\", label: \"View Jobs\" },\n { name: \"manage_jobs\", label: \"Manage Jobs\" },\n { name: \"view_global\", label: \"View Global\" },\n { name: \"manage_notifications\", label: \"Manage Notifications\" },\n { name: \"manage_files\", label: \"Manage Files\" },\n { name: \"force_single_session\", label: \"Force Single Session\" },\n { name: \"file_vault\", label: \"Access File Vault\" },\n { name: \"manage_aws\", label: \"Manage AWS\" },\n { name: \"manage_docit\", label: \"Manage DocIt\" }\n];\n\n\nUser.PERMISSION_FIELDS = [\n ...User.PERMISSIONS.map(permission => ({\n name: `permissions.${permission.name}`,\n type: 'switch',\n label: permission.label,\n columns: 4\n }))\n];\n\nconst UserForms = {\n create: {\n title: 'Create User',\n fields: [\n { name: 'email', type: 'text', label: 'Email', required: true },\n { name: 'phone_number', type: 'text', label: 'Phone number', columns: 12 },\n { name: 'display_name', type: 'text', label: 'Display Name' }\n ]\n },\n edit: {\n title: 'Edit User',\n fields: [\n { name: 'email', type: 'email', label: 'Email', columns: 12 },\n { name: 'display_name', type: 'text', label: 'Display Name', columns: 12},\n { name: 'phone_number', type: 'text', label: 'Phone number', columns: 12 },\n { type: 'collection', name: 'org', label: 'Organization', Collection: GroupList, labelField: 'name', valueField: 'id', columns: 12 },\n ]\n },\n permissions: {\n title: 'Edit Permissions',\n fields: User.PERMISSION_FIELDS\n }\n};\n\n\n// DataView configuration for User model\nconst UserDataView = {\n // Basic user profile view\n profile: {\n title: 'User Profile',\n columns: 2,\n fields: [\n {\n name: 'id',\n label: 'User ID',\n type: 'number',\n columns: 4\n },\n {\n name: 'last_login',\n label: 'Last Login',\n type: 'datetime',\n format: 'relative',\n columns: 4\n },\n {\n name: 'last_activity',\n label: 'Last Activity',\n type: 'datetime',\n format: 'relative',\n columns: 4\n },\n {\n name: 'username',\n label: 'Username',\n type: 'text',\n format: 'lowercase',\n columns: 4\n },\n {\n name: 'display_name',\n label: 'Display Name',\n type: 'text',\n columns: 4\n },\n\n {\n name: 'email',\n label: 'Email',\n type: 'email',\n columns: 12\n },\n\n {\n name: 'org.name',\n label: 'Organization',\n type: 'text',\n columns: 6\n },\n {\n name: 'phone_number',\n label: 'Phone Number',\n type: 'text',\n columns: 6\n }\n ]\n },\n\n // Activity tracking view\n activity: {\n title: 'User Activity',\n columns: 2,\n fields: [\n {\n name: 'last_login',\n label: 'Last Login',\n type: 'datetime',\n format: 'relative',\n colSize: 6\n },\n {\n name: 'last_activity',\n label: 'Last Activity',\n type: 'datetime',\n format: 'relative',\n colSize: 6\n }\n ]\n },\n\n // Comprehensive view with all data\n detailed: {\n title: 'Detailed User Information',\n columns: 2,\n showEmptyValues: true,\n emptyValueText: 'Not set',\n fields: [\n // Basic Info Section\n {\n name: 'id',\n label: 'User ID',\n type: 'number',\n colSize: 3\n },\n {\n name: 'display_name',\n label: 'Display Name',\n type: 'text',\n format: 'capitalize|default(\"Unnamed User\")',\n colSize: 9\n },\n {\n name: 'username',\n label: 'Username',\n type: 'text',\n format: 'lowercase',\n colSize: 6\n },\n {\n name: 'email',\n label: 'Email Address',\n type: 'email',\n colSize: 6\n },\n {\n name: 'phone_number',\n label: 'Phone Number',\n type: 'phone',\n format: 'phone|default(\"Not provided\")',\n colSize: 6\n },\n {\n name: 'is_active',\n label: 'Account Status',\n type: 'boolean',\n colSize: 6\n },\n\n // Activity Info\n {\n name: 'last_login',\n label: 'Last Login',\n type: 'datetime',\n format: 'relative',\n colSize: 6\n },\n {\n name: 'last_activity',\n label: 'Last Activity',\n type: 'datetime',\n format: 'relative',\n colSize: 6\n },\n\n // Avatar Info\n {\n name: 'avatar.url',\n label: 'Avatar',\n type: 'url',\n colSize: 12\n },\n\n // Complex Data (will use full width automatically)\n {\n name: 'permissions',\n label: 'User Permissions',\n type: 'dataview',\n dataViewColumns: 2,\n showEmptyValues: false\n },\n {\n name: 'metadata',\n label: 'User Metadata',\n type: 'dataview',\n dataViewColumns: 1\n },\n {\n name: 'avatar',\n label: 'Avatar Details',\n type: 'dataview',\n dataViewColumns: 1\n }\n ]\n },\n\n // Permissions-focused view\n permissions: {\n title: 'User Permissions',\n columns: 1,\n fields: [\n {\n name: 'display_name',\n label: 'User',\n type: 'text',\n format: 'capitalize',\n columns: 12\n },\n {\n name: 'permissions',\n label: 'Assigned Permissions',\n type: 'dataview',\n dataViewColumns: 3,\n showEmptyValues: false,\n colSize: 12\n }\n ]\n },\n\n // Compact summary view\n summary: {\n title: 'User Summary',\n columns: 3,\n fields: [\n {\n name: 'display_name',\n label: 'Name',\n type: 'text',\n format: 'capitalize|truncate(30)'\n },\n {\n name: 'email',\n label: 'Email',\n type: 'email'\n },\n {\n name: 'is_active',\n label: 'Status',\n type: 'boolean'\n },\n {\n name: 'last_activity',\n label: 'Last Seen',\n type: 'datetime',\n format: 'relative',\n colSize: 12\n }\n ]\n }\n};\n\nUser.DATA_VIEW = UserDataView.detailed;\nUser.EDIT_FORM = UserForms.edit;\nUser.ADD_FORM = UserForms.create;\n\n/* =========================\n * UserDevice\n * ========================= */\nclass UserDevice extends Model {\n constructor(data = {}) {\n super(data, {\n endpoint: '/api/user/device',\n });\n }\n\n static async getByDuid(duid) {\n const model = new UserDevice();\n const resp = await model.rest.GET('/api/user/device/lookup', { duid: duid });\n if (resp.success && resp.data && resp.data.data) {\n // A direct lookup should return a single object\n return new UserDevice(resp.data.data);\n }\n return null;\n }\n}\n\nclass UserDeviceList extends Collection {\n constructor(options = {}) {\n super({\n ModelClass: UserDevice,\n endpoint: '/api/user/device',\n ...options,\n });\n }\n}\n\n/* =========================\n * UserDeviceLocation\n * ========================= */\nclass UserDeviceLocation extends Model {\n constructor(data = {}) {\n super(data, {\n endpoint: '/api/user/device/location',\n });\n }\n}\n\nclass UserDeviceLocationList extends Collection {\n constructor(options = {}) {\n super({\n ModelClass: UserDeviceLocation,\n endpoint: '/api/user/device/location',\n ...options,\n });\n }\n}\n\nexport { User, UserList, UserForms, UserDataView, UserDevice, UserDeviceList, UserDeviceLocation, UserDeviceLocationList };\n","/**\n * ContextMenu - A reusable context menu component for MOJO\n *\n * Renders a Bootstrap 5 dropdown menu based on a configuration object.\n * This component is designed to be easily embedded in any other View.\n * It supports the same configuration syntax as the Dialog's contextMenu.\n *\n * Features:\n * - Renders a dropdown button with a configurable icon.\n * - Generates menu items from a configuration array.\n * - Supports dividers, icons, labels, and links.\n * - Handles actions via inline handlers or by emitting an 'action' event.\n *\n * @example\n * const contextMenu = new ContextMenu({\n * config: {\n * icon: 'bi-gear', // Optional: custom trigger icon\n * items: [\n * { label: 'Edit', action: 'edit', icon: 'bi-pencil' },\n * { label: 'Delete', action: 'delete', icon: 'bi-trash', danger: true },\n * { type: 'divider' },\n * {\n * label: 'Custom Action',\n * action: 'custom',\n * icon: 'bi-star',\n * handler: (context) => {\n * console.log('Inline handler called with context:', context);\n * }\n * }\n * ]\n * },\n * context: { id: 123, name: 'My Item' } // Optional data to pass to handlers/events\n * });\n *\n * // Listen for actions from the parent view\n * contextMenu.on('action', (data) => {\n * console.log(`Action '${data.action}' triggered for context:`, data.context);\n * if (data.action === 'edit') {\n * // handle edit\n * }\n * });\n */\n\nimport View from '@core/View.js';\n\nclass ContextMenu extends View {\n constructor(options = {}) {\n super({\n tagName: 'div',\n className: 'context-menu-view dropdown',\n ...options\n });\n\n this.config = options.contextMenu || options.config || {};\n this.context = options.context || {}; // Optional data to pass to handlers/events\n }\n\n /**\n * Build the dropdown menu HTML from the configuration.\n */\n async renderTemplate() {\n const menuItems = this.config.items || [];\n if (menuItems.length === 0) {\n return ''; // Don't render anything if there are no items\n }\n\n const triggerIcon = this.config.icon || 'bi-three-dots-horizontal';\n const buttonClass = this.config.buttonClass || 'btn btn-link text-secondary ps-3 pe-0 pt-0 pb-1';\n const dropdownId = `context-menu-${this.id}`;\n\n const menuItemsHtml = menuItems.map(item => this.buildMenuItemHTML(item)).join('');\n\n return `\n <button class=\"${buttonClass}\" type=\"button\" id=\"${dropdownId}\" data-bs-toggle=\"dropdown\" aria-expanded=\"false\">\n <i class=\"${triggerIcon}\"></i>\n </button>\n <ul class=\"dropdown-menu dropdown-menu-end\" aria-labelledby=\"${dropdownId}\">\n ${menuItemsHtml}\n </ul>\n `;\n }\n\n /**\n * Build the HTML for a single menu item.\n * @param {object} item - The menu item configuration.\n * @returns {string} The HTML string for the list item.\n */\n buildMenuItemHTML(item) {\n if (item.type === 'divider' || item.separator) {\n return '<li><hr class=\"dropdown-divider\"></li>';\n }\n\n const icon = item.icon ? `<i class=\"${item.icon} me-2\"></i>` : '';\n const label = item.label || '';\n const itemClass = `dropdown-item ${item.danger ? 'text-danger' : ''} ${item.disabled ? 'disabled' : ''}`;\n const action = item.action || '';\n\n if (item.href) {\n return `<li><a class=\"${itemClass}\" href=\"${item.href}\" target=\"${item.target || '_self'}\">${icon}${label}</a></li>`;\n }\n\n return `<li><a class=\"${itemClass}\" href=\"#\" data-action=\"menu-item-click\" data-item-action=\"${action}\">${icon}${label}</a></li>`;\n }\n\n /**\n * Handle clicks on menu items.\n * @param {Event} event - The click event.\n * @param {HTMLElement} element - The clicked anchor element.\n */\n async onActionMenuItemClick(event, element) {\n event.preventDefault();\n const action = element.getAttribute('data-item-action');\n if (!action) return;\n\n const menuItem = this.config.items.find(item => item.action === action);\n if (!menuItem || menuItem.disabled) return;\n\n // Support for inline handlers\n if (typeof menuItem.handler === 'function') {\n menuItem.handler(this.context, event, element);\n } else {\n // Emit a general event for parent views to listen to\n // this.emit('action', {\n // action: action,\n // context: this.context,\n // sourceEvent: event\n // });\n this.parent.events.dispatch(action, event, element);\n }\n this.closeDropdown();\n }\n\n closeDropdown() {\n const dropdownTrigger = this.element.querySelector('[data-bs-toggle=\"dropdown\"]');\n if (dropdownTrigger) {\n const dropdownInstance = window.bootstrap?.Dropdown.getInstance(dropdownTrigger);\n dropdownInstance?.hide();\n }\n }\n}\n\nexport default ContextMenu;\n","/**\n * ToastService - Bootstrap 5 Toast Notification Service\n * Provides methods to display toast notifications with different types and options\n *\n * Features:\n * - Bootstrap 5 toast integration\n * - Multiple toast types (success, error, info, warning)\n * - Auto-dismiss with customizable delays\n * - Toast container management\n * - Event integration\n * - Proper cleanup and memory management\n *\n * @example\n * const toastService = new ToastService();\n * toastService.success('Operation completed successfully!');\n * toastService.error('Something went wrong');\n * toastService.info('FYI: This is informational');\n * toastService.warning('Please be careful');\n */\n\nclass ToastService {\n constructor(options = {}) {\n this.options = {\n containerId: 'toast-container',\n position: 'top-end', // top-start, top-center, top-end, middle-start, etc.\n autohide: true,\n defaultDelay: 5000, // 5 seconds\n maxToasts: 5, // Maximum number of toasts to show at once\n ...options\n };\n\n this.toasts = new Map(); // Track active toasts\n this.toastCounter = 0; // For unique IDs\n \n this.init();\n }\n\n /**\n * Initialize the toast service\n */\n init() {\n this.createContainer();\n }\n\n /**\n * Create the toast container if it doesn't exist\n */\n createContainer() {\n let container = document.getElementById(this.options.containerId);\n \n if (!container) {\n container = document.createElement('div');\n container.id = this.options.containerId;\n container.className = `toast-container position-fixed ${this.getPositionClasses()}`;\n container.style.zIndex = '1070'; // Bootstrap toast z-index\n container.setAttribute('aria-live', 'polite');\n container.setAttribute('aria-atomic', 'true');\n \n document.body.appendChild(container);\n }\n \n this.container = container;\n }\n\n /**\n * Get CSS classes for toast positioning\n */\n getPositionClasses() {\n const positionMap = {\n 'top-start': 'top-0 start-0 p-3',\n 'top-center': 'top-0 start-50 translate-middle-x p-3',\n 'top-end': 'top-0 end-0 p-3',\n 'middle-start': 'top-50 start-0 translate-middle-y p-3',\n 'middle-center': 'top-50 start-50 translate-middle p-3',\n 'middle-end': 'top-50 end-0 translate-middle-y p-3',\n 'bottom-start': 'bottom-0 start-0 p-3',\n 'bottom-center': 'bottom-0 start-50 translate-middle-x p-3',\n 'bottom-end': 'bottom-0 end-0 p-3'\n };\n \n return positionMap[this.options.position] || positionMap['top-end'];\n }\n\n\n\n /**\n * Show a success toast\n * @param {string} message - The message to display\n * @param {object} options - Additional options\n */\n success(message, options = {}) {\n return this.show(message, 'success', {\n icon: 'bi-check-circle-fill',\n ...options\n });\n }\n\n /**\n * Show an error toast\n * @param {string} message - The message to display\n * @param {object} options - Additional options\n */\n error(message, options = {}) {\n return this.show(message, 'error', {\n icon: 'bi-exclamation-triangle-fill',\n autohide: false, // Keep error toasts visible until manually dismissed\n ...options\n });\n }\n\n /**\n * Show an info toast\n * @param {string} message - The message to display\n * @param {object} options - Additional options\n */\n info(message, options = {}) {\n return this.show(message, 'info', {\n icon: 'bi-info-circle-fill',\n ...options\n });\n }\n\n /**\n * Show a warning toast\n * @param {string} message - The message to display\n * @param {object} options - Additional options\n */\n warning(message, options = {}) {\n return this.show(message, 'warning', {\n icon: 'bi-exclamation-triangle-fill',\n ...options\n });\n }\n\n /**\n * Show a plain toast without specific styling\n * @param {string} message - The message to display\n * @param {object} options - Additional options\n */\n plain(message, options = {}) {\n return this.show(message, 'plain', {\n ...options\n });\n }\n\n /**\n * Show a toast with specified type and options\n * @param {string} message - The message to display\n * @param {string} type - Toast type (success, error, info, warning)\n * @param {object} options - Additional options\n */\n show(message, type = 'info', options = {}) {\n // Enforce max toasts limit\n this.enforceMaxToasts();\n \n const toastId = `toast-${++this.toastCounter}`;\n const config = {\n title: this.getDefaultTitle(type),\n icon: this.getDefaultIcon(type),\n autohide: this.options.autohide,\n delay: this.options.defaultDelay,\n dismissible: true,\n ...options\n };\n\n const toastElement = this.createToastElement(toastId, message, type, config);\n this.container.appendChild(toastElement);\n\n // Initialize Bootstrap toast\n if (typeof bootstrap === 'undefined') {\n throw new Error('Bootstrap is required for ToastService. Make sure Bootstrap 5 is loaded.');\n }\n const bsToast = new bootstrap.Toast(toastElement, {\n autohide: config.autohide,\n delay: config.delay\n });\n\n // Store toast reference\n this.toasts.set(toastId, {\n element: toastElement,\n bootstrap: bsToast,\n type: type,\n message: message\n });\n\n // Setup cleanup on hide\n toastElement.addEventListener('hidden.bs.toast', () => {\n this.cleanup(toastId);\n });\n\n // Show the toast\n bsToast.show();\n\n return {\n id: toastId,\n hide: () => {\n try {\n bsToast.hide();\n } catch (error) {\n console.warn('Error hiding toast:', error);\n }\n },\n dispose: () => this.cleanup(toastId),\n updateProgress: options.updateProgress || null\n };\n }\n\n /**\n * Show a toast with a View component in the body\n * @param {View} view - The View component to display\n * @param {string} type - Toast type (success, error, info, warning, plain)\n * @param {object} options - Additional options\n */\n showView(view, type = 'info', options = {}) {\n // Enforce max toasts limit\n this.enforceMaxToasts();\n \n const toastId = `toast-${++this.toastCounter}`;\n const config = {\n title: options.title || this.getDefaultTitle(type),\n icon: options.icon || this.getDefaultIcon(type),\n autohide: this.options.autohide,\n delay: this.options.defaultDelay,\n dismissible: true,\n ...options\n };\n\n const toastElement = this.createViewToastElement(toastId, view, type, config);\n this.container.appendChild(toastElement);\n\n // Initialize Bootstrap toast\n if (typeof bootstrap === 'undefined') {\n throw new Error('Bootstrap is required for ToastService. Make sure Bootstrap 5 is loaded.');\n }\n const bsToast = new bootstrap.Toast(toastElement, {\n autohide: config.autohide,\n delay: config.delay\n });\n\n // Store toast reference with view\n this.toasts.set(toastId, {\n element: toastElement,\n bootstrap: bsToast,\n type: type,\n view: view,\n message: 'View toast'\n });\n\n // Setup cleanup on hide - dispose view properly\n toastElement.addEventListener('hidden.bs.toast', () => {\n this.cleanupView(toastId);\n });\n\n // Mount and render the view\n const bodyContainer = toastElement.querySelector('.toast-view-body');\n if (bodyContainer && view) {\n view.render(true, bodyContainer);\n }\n\n // Show the toast\n bsToast.show();\n\n return {\n id: toastId,\n view: view,\n hide: () => {\n try {\n bsToast.hide();\n } catch (error) {\n console.warn('Error hiding view toast:', error);\n }\n },\n dispose: () => this.cleanupView(toastId),\n updateProgress: (progressInfo) => {\n if (view && typeof view.updateProgress === 'function') {\n view.updateProgress(progressInfo);\n }\n }\n };\n }\n\n /**\n * Create toast DOM element\n */\n createToastElement(id, message, type, config) {\n const toast = document.createElement('div');\n toast.id = id;\n toast.className = `toast toast-service-${type}`;\n toast.setAttribute('role', 'alert');\n toast.setAttribute('aria-live', 'assertive');\n toast.setAttribute('aria-atomic', 'true');\n\n const header = config.title || config.icon ? this.createToastHeader(config, type) : '';\n const body = this.createToastBody(message, config.icon && !config.title);\n\n toast.innerHTML = `\n ${header}\n ${body}\n `;\n\n return toast;\n }\n\n /**\n * Create toast DOM element for View component\n */\n createViewToastElement(id, view, type, config) {\n const toast = document.createElement('div');\n toast.id = id;\n toast.className = `toast toast-service-${type}`;\n toast.setAttribute('role', 'alert');\n toast.setAttribute('aria-live', 'assertive');\n toast.setAttribute('aria-atomic', 'true');\n\n const header = config.title || config.icon ? this.createToastHeader(config, type) : '';\n const body = this.createViewToastBody();\n\n toast.innerHTML = `\n ${header}\n ${body}\n `;\n\n return toast;\n }\n\n /**\n * Create toast body for View component\n */\n createViewToastBody() {\n return `\n <div class=\"toast-body p-0\">\n <div class=\"toast-view-body p-3\"></div>\n </div>\n `;\n }\n\n /**\n * Create toast header with title and icon\n */\n createToastHeader(config, _type) {\n const iconHtml = config.icon ? \n `<i class=\"${config.icon} toast-service-icon me-2\"></i>` : '';\n \n const titleHtml = config.title ? \n `<strong class=\"me-auto\">${iconHtml}${this.escapeHtml(config.title)}</strong>` : '';\n\n const timeHtml = config.showTime ? \n `<small class=\"text-muted\">${this.getTimeString()}</small>` : '';\n\n const closeButton = config.dismissible ? \n `<button type=\"button\" class=\"btn-close toast-service-close\" data-bs-dismiss=\"toast\" aria-label=\"Close\"></button>` : '';\n\n if (!titleHtml && !timeHtml && !closeButton) {\n return '';\n }\n\n return `\n <div class=\"toast-header\">\n ${titleHtml}\n ${timeHtml}\n ${closeButton}\n </div>\n `;\n }\n\n /**\n * Create toast body with message\n */\n createToastBody(message, showIcon = false) {\n const iconHtml = showIcon ? \n `<i class=\"${this.getDefaultIcon('info')} toast-service-icon me-2\"></i>` : '';\n \n return `\n <div class=\"toast-body d-flex align-items-center\">\n ${iconHtml}\n <span>${this.escapeHtml(message)}</span>\n </div>\n `;\n }\n\n /**\n * Get default title for toast type\n */\n getDefaultTitle(type) {\n const titles = {\n success: 'Success',\n error: 'Error',\n warning: 'Warning',\n info: 'Information',\n plain: ''\n };\n return titles[type] || 'Notification';\n }\n\n /**\n * Get default icon for toast type\n */\n getDefaultIcon(type) {\n const icons = {\n success: 'bi-check-circle-fill',\n error: 'bi-exclamation-triangle-fill',\n warning: 'bi-exclamation-triangle-fill',\n info: 'bi-info-circle-fill',\n plain: ''\n };\n return icons[type] || 'bi-info-circle-fill';\n }\n\n /**\n * Enforce maximum number of toasts\n */\n enforceMaxToasts() {\n const activeToasts = Array.from(this.toasts.values());\n \n if (activeToasts.length >= this.options.maxToasts) {\n // Remove oldest toast\n const oldestId = this.toasts.keys().next().value;\n const oldest = this.toasts.get(oldestId);\n \n if (oldest) {\n oldest.bootstrap.hide();\n }\n }\n }\n\n /**\n * Clean up toast resources\n */\n cleanup(toastId) {\n const toast = this.toasts.get(toastId);\n \n if (toast) {\n // Dispose Bootstrap toast\n try {\n toast.bootstrap.dispose();\n } catch (e) {\n console.warn('Error disposing toast:', e);\n }\n \n // Remove from DOM\n if (toast.element && toast.element.parentNode) {\n toast.element.parentNode.removeChild(toast.element);\n }\n \n // Remove from tracking\n this.toasts.delete(toastId);\n }\n }\n\n /**\n * Clean up view toast resources with proper view disposal\n */\n cleanupView(toastId) {\n const toast = this.toasts.get(toastId);\n \n if (toast) {\n // Dispose view first if it exists\n if (toast.view && typeof toast.view.dispose === 'function') {\n try {\n toast.view.dispose();\n } catch (e) {\n console.warn('Error disposing view in toast:', e);\n }\n }\n \n // Dispose Bootstrap toast\n try {\n toast.bootstrap.dispose();\n } catch (e) {\n console.warn('Error disposing toast:', e);\n }\n \n // Remove from DOM\n if (toast.element && toast.element.parentNode) {\n toast.element.parentNode.removeChild(toast.element);\n }\n \n // Remove from tracking\n this.toasts.delete(toastId);\n }\n }\n\n /**\n * Hide all active toasts\n */\n hideAll() {\n this.toasts.forEach((toast, _id) => {\n toast.bootstrap.hide();\n });\n }\n\n /**\n * Clear all toasts immediately\n */\n clearAll() {\n this.toasts.forEach((toast, id) => {\n this.cleanup(id);\n });\n }\n\n /**\n * Get current time string\n */\n getTimeString() {\n return new Date().toLocaleTimeString([], { \n hour: '2-digit', \n minute: '2-digit' \n });\n }\n\n /**\n * Escape HTML to prevent XSS\n */\n escapeHtml(str) {\n const div = document.createElement('div');\n div.textContent = str;\n return div.innerHTML;\n }\n\n /**\n * Dispose of the entire toast service\n */\n dispose() {\n this.clearAll();\n \n if (this.container && this.container.parentNode) {\n this.container.parentNode.removeChild(this.container);\n }\n }\n\n /**\n * Get statistics about active toasts\n */\n getStats() {\n const stats = {\n total: this.toasts.size,\n byType: {}\n };\n \n this.toasts.forEach(toast => {\n stats.byType[toast.type] = (stats.byType[toast.type] || 0) + 1;\n });\n \n return stats;\n }\n\n /**\n * Set global options\n */\n setOptions(newOptions) {\n this.options = { ...this.options, ...newOptions };\n \n // Recreate container if position changed\n if (newOptions.position) {\n if (this.container) {\n this.container.className = `toast-container position-fixed ${this.getPositionClasses()}`;\n }\n }\n }\n}\n\nexport default ToastService;"],"names":["Page","View","constructor","options","tagName","className","pageName","id","toLowerCase","replace","super","this","route","title","pageIcon","icon","displayName","pageDescription","params","query","matched","isActive","pageOptions","description","requiresAuth","savedState","onParams","canEnter","permissions","user","getApp","activeUser","hasPermission","requiresGroup","activeGroup","onEnter","onInitView","restoreState","document","emit","page","getMetadata","onExit","captureState","name","onActionDefault","action","makeActive","showPage","onActionNavigate","event","element","preventDefault","dataset","scrollTop","formData","captureFormData","custom","captureCustomState","state","restoreFormData","restoreCustomState","data","querySelectorAll","forEach","field","type","checked","value","Object","entries","querySelector","radio","setMeta","meta","descMeta","createElement","head","appendChild","content","key","metaEl","showError","message","errorDiv","innerHTML","insertBefore","firstChild","setTimeout","parentNode","removeChild","showSuccess","successDiv","onBeforeRender","onAfterMount","body","classList","add","onBeforeDestroy","remove","navigate","app","router","window","MOJO","console","error","getRoute","startsWith","substring","syncUrl","force","updateBrowserUrl","trigger","define","definition","DefinedPage","template","Group","Model","endpoint","GroupList","Collection","ModelClass","size","GroupKinds","org","division","department","team","merchant","partner","client","iso","sales","reseller","location","region","project","inventory","test","misc","qa","GroupKindOptions","map","label","GroupForms","create","fields","required","placeholder","labelField","valueField","maxItems","emptyFetch","debounceMs","edit","cols","detailed","text","level","class","columns","xs","md","imageSize","width","height","help","EDIT_FORM","ADD_FORM","CREATE_FORM","User","permission","Array","isArray","some","p","isSysPermission","permissionToCheck","_hasPermission","member","get","hasPerm","UserList","PERMISSIONS","PERMISSION_FIELDS","UserForms","UserDataView","profile","format","activity","colSize","showEmptyValues","emptyValueText","dataViewColumns","summary","DATA_VIEW","UserDevice","getByDuid","duid","model","resp","rest","GET","success","UserDeviceList","UserDeviceLocation","UserDeviceLocationList","ContextMenu","config","contextMenu","context","renderTemplate","menuItems","items","length","triggerIcon","buttonClass","dropdownId","item","buildMenuItemHTML","join","separator","itemClass","danger","disabled","href","target","onActionMenuItemClick","getAttribute","menuItem","find","handler","parent","events","dispatch","closeDropdown","dropdownTrigger","dropdownInstance","bootstrap","Dropdown","getInstance","hide","containerId","position","autohide","defaultDelay","maxToasts","toasts","Map","toastCounter","init","createContainer","container","getElementById","getPositionClasses","style","zIndex","setAttribute","positionMap","show","info","warning","plain","enforceMaxToasts","toastId","getDefaultTitle","getDefaultIcon","delay","dismissible","toastElement","createToastElement","Error","bsToast","Toast","set","addEventListener","cleanup","warn","dispose","updateProgress","showView","view","createViewToastElement","cleanupView","bodyContainer","render","progressInfo","toast","header","createToastHeader","createToastBody","createViewToastBody","_type","iconHtml","titleHtml","escapeHtml","timeHtml","showTime","getTimeString","closeButton","showIcon","from","values","oldestId","keys","next","oldest","e","delete","hideAll","_id","clearAll","Date","toLocaleTimeString","hour","minute","str","div","textContent","getStats","stats","total","byType","setOptions","newOptions"],"mappings":"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"}
1
+ {"version":3,"file":"ContextMenu-C4_MWleT.js","sources":["../../src/core/Page.js","../../src/core/models/Group.js","../../src/core/models/User.js","../../src/core/views/feedback/ContextMenu.js","../../src/core/services/ToastService.js"],"sourcesContent":["/**\n * Page - Extends View with routing capabilities for MOJO framework\n * Handles URL routing, parameters, and page-specific actions\n *\n * Event Emitter notes:\n * - Uses EventEmitter via View base class.\n * - Use .emit/.on/.off/.once for all custom events.\n */\n\nimport View from '@core/View.js';\n\nclass Page extends View {\n constructor(options = {}) {\n // Set default tag name for pages\n options.tagName = options.tagName || 'main';\n options.className = options.className || 'mojo-page';\n\n // Set page ID based on page name\n const pageName = options.pageName || '';\n if (pageName && !options.id) {\n options.id = 'page_' + pageName.toLowerCase().replace(/\\s+/g, '_');\n }\n\n super(options);\n\n // Core page properties from design doc\n this.pageName = options.pageName || this.constructor.pageName || '';\n this.route = options.route || this.constructor.route || '';\n this.title = options.title || this.pageName || '';\n\n // Set page ID if not already set and we have a page_name from constructor\n if (!this.id && this.constructor.pageName && !options.pageName) {\n this.id = 'page_' + this.constructor.pageName.toLowerCase().replace(/\\s+/g, '_');\n }\n\n // Page metadata for event system\n this.pageIcon = options.icon || options.pageIcon || this.constructor.pageIcon || 'bi bi-file-text';\n this.displayName = options.displayName || this.constructor.displayName || this.pageName || '';\n this.pageDescription = options.pageDescription || this.constructor.pageDescription || '';\n\n // Routing state\n this.params = {};\n this.query = {};\n this.matched = false;\n this.isActive = false;\n\n // Page-specific options\n this.pageOptions = {\n title: options.title || this.pageName || 'Untitled Page',\n description: options.description || '',\n requiresAuth: options.requiresAuth || false,\n ...options.pageOptions\n };\n\n // State preservation\n this.savedState = null;\n\n console.log(`Page ${this.pageName} constructed with route: ${this.route}`);\n }\n\n /**\n * Handle route parameters - from design doc\n * @param {object} params - Route parameters\n * @param {object} query - Query string parameters\n */\n async onParams(params = {}, query = {}) {\n // const paramsChanged = JSON.stringify(params) !== JSON.stringify(this.params);\n // const queryChanged = JSON.stringify(query) !== JSON.stringify(this.query);\n\n this.params = params;\n this.query = query;\n\n // Only re-render if params actually changed and page is active\n // if (this.isActive && (paramsChanged || queryChanged)) {\n // console.log(`Page ${this.pageName} params changed, re-rendering`);\n // await this.render();\n // }\n }\n\n canEnter() {\n if (this.options.permissions) {\n const user = this.getApp().activeUser;\n if (!user || !user.hasPermission(this.options.permissions)) {\n return false;\n }\n }\n if (this.options.requiresGroup && !this.getApp().activeGroup) {\n return false;\n }\n return true;\n }\n\n /**\n * Called when entering this page (before render)\n * Override this method for initialization logic\n */\n async onEnter() {\n this.isActive = true;\n await this.onInitView();\n\n // Restore saved state if exists\n if (this.savedState) {\n this.restoreState(this.savedState);\n this.savedState = null;\n }\n\n // Set page title if provided\n if (this.pageOptions && this.pageOptions.title && typeof document !== 'undefined') {\n document.title = this.pageOptions.title;\n }\n\n // Emit activation event\n this.emit('activated', {\n page: this.getMetadata()\n });\n\n console.log(`Page ${this.pageName} entered`);\n }\n\n /**\n * Called when leaving this page (before cleanup)\n * Override this method for cleanup logic like removing listeners, clearing timers, etc.\n */\n async onExit() {\n // Save state before exit\n this.savedState = this.captureState();\n this.isActive = false;\n\n // Emit deactivation event\n this.emit('deactivated', {\n page: this.getMetadata()\n });\n console.log(`Page ${this.pageName} exiting`);\n }\n\n /**\n * Get page metadata for display and events\n * @returns {object} Page metadata\n */\n getMetadata() {\n return {\n name: this.pageName,\n displayName: this.displayName || this.pageName,\n icon: this.pageIcon,\n description: this.pageDescription,\n route: this.route,\n isActive: this.isActive\n };\n }\n\n /**\n * Handle default action - fallback from design doc\n */\n async onActionDefault(action) {\n console.log(`Default action '${action}' triggered on page: ${this.pageName}`);\n }\n\n async makeActive() {\n this.getApp().showPage(this);\n }\n\n async onActionNavigate(event, element) {\n event.preventDefault();\n const page = element.dataset.page;\n this.getApp().showPage(page);\n }\n\n /**\n * Capture current page state for preservation\n * @returns {object|null} Captured state\n */\n captureState() {\n if (!this.element) return null;\n\n return {\n scrollTop: this.element.scrollTop,\n formData: this.captureFormData(),\n custom: this.captureCustomState()\n };\n }\n\n /**\n * Restore saved state\n * @param {object} state - State to restore\n */\n restoreState(state) {\n if (!state || !this.element) return;\n\n this.element.scrollTop = state.scrollTop || 0;\n this.restoreFormData(state.formData);\n if (state.custom) {\n this.restoreCustomState(state.custom);\n }\n }\n\n /**\n * Capture form data from page\n * @returns {object} Form data\n */\n captureFormData() {\n const data = {};\n if (!this.element) return data;\n\n this.element.querySelectorAll('input, select, textarea').forEach(field => {\n if (field.name) {\n if (field.type === 'checkbox') {\n data[field.name] = field.checked;\n } else if (field.type === 'radio') {\n if (field.checked) {\n data[field.name] = field.value;\n }\n } else {\n data[field.name] = field.value;\n }\n }\n });\n\n return data;\n }\n\n /**\n * Restore form data to page\n * @param {object} formData - Form data to restore\n */\n restoreFormData(formData) {\n if (!formData || !this.element) return;\n\n Object.entries(formData).forEach(([name, value]) => {\n const field = this.element.querySelector(`[name=\"${name}\"]`);\n if (field) {\n if (field.type === 'checkbox') {\n field.checked = value;\n } else if (field.type === 'radio') {\n const radio = this.element.querySelector(`[name=\"${name}\"][value=\"${value}\"]`);\n if (radio) radio.checked = true;\n } else {\n field.value = value;\n }\n }\n });\n }\n\n /**\n * Capture custom state - override in subclasses\n * @returns {object} Custom state\n */\n captureCustomState() {\n return {};\n }\n\n /**\n * Restore custom state - override in subclasses\n * @param {object} state - Custom state to restore\n */\n restoreCustomState(state) {\n // Override in subclasses\n }\n\n\n\n /**\n * Set page metadata\n * @param {object} meta - Metadata object\n */\n setMeta(meta = {}) {\n if (typeof document === 'undefined') {\n return;\n }\n\n // Set title\n if (meta.title) {\n document.title = meta.title;\n this.pageOptions.title = meta.title;\n }\n\n // Set description\n if (meta.description) {\n let descMeta = document.querySelector('meta[name=\"description\"]');\n if (!descMeta) {\n descMeta = document.createElement('meta');\n descMeta.name = 'description';\n document.head.appendChild(descMeta);\n }\n descMeta.content = meta.description;\n this.pageOptions.description = meta.description;\n }\n\n // Set other meta tags\n Object.entries(meta).forEach(([key, value]) => {\n if (key !== 'title' && key !== 'description') {\n let metaEl = document.querySelector(`meta[name=\"${key}\"]`);\n if (!metaEl) {\n metaEl = document.createElement('meta');\n metaEl.name = key;\n document.head.appendChild(metaEl);\n }\n metaEl.content = value;\n }\n });\n }\n\n\n /**\n * Show error message with page context\n * @param {string} message - Error message\n */\n showError(message) {\n super.showError(message);\n\n // Page-specific error display can be implemented here\n if (this.element) {\n // Example: Add error to page\n const errorDiv = document.createElement('div');\n errorDiv.className = 'alert alert-danger alert-dismissible fade show';\n errorDiv.innerHTML = `\n ${message}\n <button type=\"button\" class=\"btn-close\" data-bs-dismiss=\"alert\" aria-label=\"Close\"></button>\n `;\n\n // Insert at top of page\n this.element.insertBefore(errorDiv, this.element.firstChild);\n\n // Auto-remove after 5 seconds\n setTimeout(() => {\n if (errorDiv.parentNode) {\n errorDiv.parentNode.removeChild(errorDiv);\n }\n }, 5000);\n }\n }\n\n /**\n * Show success message with page context\n * @param {string} message - Success message\n */\n showSuccess(message) {\n super.showSuccess(message);\n\n // Page-specific success display\n if (this.element) {\n const successDiv = document.createElement('div');\n successDiv.className = 'alert alert-success alert-dismissible fade show';\n successDiv.innerHTML = `\n ${message}\n <button type=\"button\" class=\"btn-close\" data-bs-dismiss=\"alert\" aria-label=\"Close\"></button>\n `;\n\n // Insert at top of page\n this.element.insertBefore(successDiv, this.element.firstChild);\n\n // Auto-remove after 3 seconds\n setTimeout(() => {\n if (successDiv.parentNode) {\n successDiv.parentNode.removeChild(successDiv);\n }\n }, 3000);\n }\n }\n\n /**\n * Page-specific before render hook\n */\n async onBeforeRender() {\n await super.onBeforeRender();\n\n // Set page metadata before rendering\n this.setMeta({\n title: this.pageOptions.title,\n description: this.pageOptions.description\n });\n }\n\n /**\n * Page-specific after mount hook\n */\n async onAfterMount() {\n await super.onAfterMount();\n\n // Add page-specific class to body\n if (typeof document !== 'undefined' && this.pageName) {\n document.body.classList.add(`page-${this.pageName.toLowerCase().replace(/\\s+/g, '-')}`);\n }\n }\n\n /**\n * Page-specific before destroy hook\n */\n async onBeforeDestroy() {\n await super.onBeforeDestroy();\n\n // Remove page-specific class from body\n if (typeof document !== 'undefined' && this.pageName) {\n document.body.classList.remove(`page-${this.pageName.toLowerCase().replace(/\\s+/g, '-')}`);\n }\n }\n\n /**\n * Navigate to another page using the app's router\n * @param {string} route - Route to navigate to\n * @param {object} params - Route parameters\n * @param {object} options - Navigation options\n */\n navigate(route, params = {}, options = {}) {\n // Delegate to app's router\n if (this.app && this.app.router) {\n return this.app.router.navigate(route, options);\n }\n\n // Fallback to MOJO global router\n if (typeof window !== 'undefined' && window.MOJO?.router) {\n return window.MOJO.router.navigate(route, options);\n }\n\n console.error('No router available for navigation');\n }\n\n getRoute() {\n if (this.route) {\n let route = this.route;\n if (typeof route === 'string' && route.startsWith('/')) {\n route = route.substring(1);\n }\n return route;\n }\n return this.pageName;\n }\n\n syncUrl(force = true) {\n this.updateBrowserUrl(this.query, false, false);\n }\n\n updateBrowserUrl(query = null, replace = false, trigger = false) {\n this.getApp();\n // we need to do this to normalize the URL\n // const targetPath = this.app.buildPagePath(this, this.params, query);\n // const { pageName, queryParams } = this.app.router.parseInput(targetPath);\n this.app.router.updateBrowserUrl(this.getRoute(), query, replace, trigger);\n }\n\n /**\n * Static method to define a page class with metadata\n * @param {object} definition - Page class definition\n * @returns {class} Page class\n */\n static define(definition) {\n class DefinedPage extends Page {\n constructor(options = {}) {\n super({\n ...definition,\n ...options\n });\n }\n }\n\n // Copy static properties\n DefinedPage.template = definition.template;\n DefinedPage.pageName = definition.pageName;\n DefinedPage.route = definition.route;\n\n return DefinedPage;\n }\n}\n\nexport default Page;\n","\nimport Collection from '@core/Collection.js';\nimport Model from '@core/Model.js';\n\n/**\n * Group Model - Represents an organization, team, or group entity\n *\n * Features:\n * - Hierarchical group support (parent/child relationships)\n * - Member management\n * - Search and filtering capabilities\n * - Role-based permissions within groups\n * - Metadata and settings management\n */\nclass Group extends Model {\n constructor(data = {}) {\n super(data, {\n endpoint: '/api/group'\n });\n }\n}\n\n/**\n * GroupCollection - Enhanced collection for managing groups with advanced search and filtering\n */\nclass GroupList extends Collection {\n constructor(options = {}) {\n super({\n ModelClass: Group,\n endpoint: '/api/group',\n size: 10,\n ...options\n });\n }\n}\n\nconst GroupKinds = {\n 'org': 'Organization',\n 'division': 'Division',\n 'department': 'Department',\n 'team': 'Team',\n 'merchant': 'Merchant',\n 'partner': 'Partner',\n 'client': 'Client',\n 'iso': 'ISO',\n 'sales': 'Sales',\n 'reseller': 'Reseller',\n 'location': 'Location',\n 'region': 'Region',\n 'route': 'Route',\n 'project': 'Project',\n \"inventory\": \"Inventory\",\n 'test': 'Testing',\n 'misc': 'Miscellaneous',\n 'qa': 'Quality Assurance'\n};\n\n// Convert GroupKinds to select options\nconst GroupKindOptions = Object.entries(GroupKinds).map(([key, label]) => ({\n value: key,\n label: label\n}));\n\n/**\n * Form configurations for group management\n */\nconst GroupForms = {\n create: {\n title: 'Create Group',\n fields: [\n {\n name: 'name',\n type: 'text',\n label: 'Group Name',\n required: true,\n placeholder: 'Enter group name'\n },\n {\n name: 'kind',\n type: 'select',\n label: 'Group Kind',\n required: true,\n options: GroupKindOptions\n },\n {\n type: 'collection',\n name: 'parent',\n label: 'Parent Group',\n Collection: GroupList, // Collection class\n labelField: 'name', // Field to display in dropdown\n valueField: 'id', // Field to use as value\n maxItems: 10, // Max items to show in dropdown\n placeholder: 'Search groups...',\n emptyFetch: false,\n debounceMs: 300, // Search debounce delay\n }\n ]\n },\n\n edit: {\n title: 'Edit Group',\n fields: [\n {\n name: 'name',\n type: 'text',\n label: 'Group Name',\n required: true,\n placeholder: 'Enter group name',\n },\n {\n name: 'kind',\n type: 'select',\n label: 'Group Kind',\n required: true,\n options: GroupKindOptions\n },\n {\n type: 'collection',\n name: 'parent',\n label: 'Parent Group',\n Collection: GroupList, // Collection class\n labelField: 'name', // Field to display in dropdown\n valueField: 'id', // Field to use as value\n maxItems: 10, // Max items to show in dropdown\n placeholder: 'Search groups...',\n emptyFetch: false,\n debounceMs: 300, // Search debounce delay\n },\n {\n name: 'metadata.domain',\n type: 'text',\n label: 'Default Domain',\n placeholder: 'Enter Domain',\n },\n {\n name: 'metadata.portal',\n type: 'text',\n label: 'Default Portal',\n placeholder: 'Enter Portal URL',\n },\n {\n name: 'is_active',\n type: 'switch',\n label: 'Is Active',\n cols: 4\n },\n ]\n },\n\n detailed: {\n title: 'Group Details',\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 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 columns: 12\n },\n {\n name: 'is_active',\n type: 'switch',\n label: 'Is Active',\n columns: 12\n },\n ]\n },\n\n // Profile Details\n {\n type: 'group',\n columns: { xs: 12, md: 8 },\n title: 'Details',\n fields: [\n {\n name: 'name',\n type: 'text',\n label: 'Group Name',\n required: true,\n placeholder: 'Enter group name',\n columns: 12\n },\n {\n name: 'kind',\n type: 'select',\n label: 'Group Kind',\n required: true,\n columns: 12,\n options: [\n { value: 'org', label: 'Organization' },\n { value: 'team', label: 'Team' },\n { value: 'department', label: 'Department' },\n { value: 'merchant', label: 'Merchant' },\n { value: 'iso', label: 'ISO' },\n { value: 'group', label: 'Group' }\n ]\n },\n {\n type: 'collection',\n name: 'parent',\n label: 'Parent Group',\n Collection: GroupList, // Collection class\n labelField: 'name', // Field to display in dropdown\n valueField: 'id', // Field to use as value\n maxItems: 10, // Max items to show in dropdown\n placeholder: 'Search groups...',\n emptyFetch: false,\n debounceMs: 300, // Search debounce delay\n columns: 12\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: 'metadata.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: 'metadata.eod_hour',\n label: 'End of Day Hour',\n columns: 6,\n options: [\n { value: 0, text: 'Midnight' },\n { value: 1, text: '1 AM' },\n { value: 2, text: '2 AM' },\n { value: 3, text: '3 AM' },\n { value: 4, text: '4 AM' },\n { value: 5, text: '5 AM' },\n { value: 6, text: '6 AM' },\n { value: 7, text: '7 AM' },\n { value: 8, text: '8 AM' },\n { value: 9, text: '9 AM' },\n { value: 10, text: '10 AM' },\n { value: 11, text: '11 AM' },\n { value: 12, text: '12 PM' },\n { value: 13, text: '1 PM' },\n { value: 14, text: '2 PM' },\n { value: 15, text: '3 PM' },\n { value: 16, text: '4 PM' },\n { value: 17, text: '5 PM' },\n { value: 18, text: '6 PM' },\n { value: 19, text: '7 PM' },\n { value: 20, text: '8 PM' },\n { value: 21, text: '9 PM' },\n { value: 22, text: '10 PM' },\n { value: 23, text: '11 PM' }\n ]\n }\n ]\n },\n {\n type: \"text\",\n label: \"Email Template (Prefix)\",\n name: \"metadata.email_template\",\n columns: 12\n }\n ]\n },\n};\n\nGroup.EDIT_FORM = GroupForms.edit;\nGroup.ADD_FORM = GroupForms.create;\nGroup.CREATE_FORM = GroupForms.create; // Alias for compatibility\nGroup.GroupKindOptions = GroupKindOptions;\nGroup.GroupKinds = GroupKinds;\nexport { Group, GroupList, GroupForms };\n","import Collection from '@core/Collection.js';\nimport Model from '@core/Model.js';\n\nimport { GroupList } from './Group.js';\n\nclass User extends Model {\n constructor(data = {}) {\n super(data, {\n endpoint: '/api/user'\n });\n }\n\n hasPermission(permission) {\n if (Array.isArray(permission)) {\n return permission.some(p => this.hasPermission(p));\n }\n\n // Check if permission has \"sys.\" prefix\n const isSysPermission = permission.startsWith('sys.');\n const permissionToCheck = isSysPermission ? permission.substring(4) : permission;\n\n if (this._hasPermission(permissionToCheck)) {\n return true;\n }\n\n // Only check member permissions if it's not a system permission\n if (!isSysPermission && this.member && this.member.hasPermission(permission)) {\n return true;\n }\n\n return false;\n }\n\n _hasPermission(permission) {\n const permissions = this.get(\"permissions\");\n if (!permissions) {\n return false;\n }\n return permissions[permission] == true;\n }\n\n hasPerm(p) {\n return this.hasPermission(p);\n }\n}\n\nclass UserList extends Collection {\n constructor(options = {}) {\n super({\n ModelClass: User,\n endpoint: '/api/user',\n ...options\n });\n }\n}\n\nUser.PERMISSIONS = [\n { name: \"manage_users\", label: \"Manage Users\" },\n { name: \"view_users\", label: \"View Users\" },\n { name: \"view_groups\", label: \"View Groups\" },\n { name: \"manage_groups\", label: \"Manage Groups\" },\n { name: \"view_metrics\", label: \"View System Metrics\" },\n { name: \"manage_metrics\", label: \"Manage System Metrics\" },\n { name: \"view_logs\", label: \"View Logs\" },\n { name: \"view_incidents\", label: \"View Incidents\" },\n { name: \"manage_incidents\", label: \"Manage Incidents\" },\n { name: \"view_tickets\", label: \"View Tickets\" },\n { name: \"manage_tickets\", label: \"Manage Tickets\" },\n { name: \"view_admin\", label: \"View Admin\" },\n { name: \"view_jobs\", label: \"View Jobs\" },\n { name: \"manage_jobs\", label: \"Manage Jobs\" },\n { name: \"view_global\", label: \"View Global\" },\n { name: \"manage_notifications\", label: \"Manage Notifications\" },\n { name: \"manage_files\", label: \"Manage Files\" },\n { name: \"force_single_session\", label: \"Force Single Session\" },\n { name: \"file_vault\", label: \"Access File Vault\" },\n { name: \"manage_aws\", label: \"Manage AWS\" },\n { name: \"manage_docit\", label: \"Manage DocIt\" }\n];\n\n\nUser.PERMISSION_FIELDS = [\n ...User.PERMISSIONS.map(permission => ({\n name: `permissions.${permission.name}`,\n type: 'switch',\n label: permission.label,\n columns: 4\n }))\n];\n\nconst UserForms = {\n create: {\n title: 'Create User',\n fields: [\n { name: 'email', type: 'text', label: 'Email', required: true },\n { name: 'phone_number', type: 'text', label: 'Phone number', columns: 12 },\n { name: 'display_name', type: 'text', label: 'Display Name' }\n ]\n },\n edit: {\n title: 'Edit User',\n fields: [\n { name: 'email', type: 'email', label: 'Email', columns: 12 },\n { name: 'display_name', type: 'text', label: 'Display Name', columns: 12},\n { name: 'phone_number', type: 'text', label: 'Phone number', columns: 12 },\n { type: 'collection', name: 'org', label: 'Organization', Collection: GroupList, labelField: 'name', valueField: 'id', columns: 12 },\n ]\n },\n permissions: {\n title: 'Edit Permissions',\n fields: User.PERMISSION_FIELDS\n }\n};\n\n\n// DataView configuration for User model\nconst UserDataView = {\n // Basic user profile view\n profile: {\n title: 'User Profile',\n columns: 2,\n fields: [\n {\n name: 'id',\n label: 'User ID',\n type: 'number',\n columns: 4\n },\n {\n name: 'last_login',\n label: 'Last Login',\n type: 'datetime',\n format: 'relative',\n columns: 4\n },\n {\n name: 'last_activity',\n label: 'Last Activity',\n type: 'datetime',\n format: 'relative',\n columns: 4\n },\n {\n name: 'username',\n label: 'Username',\n type: 'text',\n format: 'lowercase',\n columns: 4\n },\n {\n name: 'display_name',\n label: 'Display Name',\n type: 'text',\n columns: 4\n },\n\n {\n name: 'email',\n label: 'Email',\n type: 'email',\n columns: 12\n },\n\n {\n name: 'org.name',\n label: 'Organization',\n type: 'text',\n columns: 6\n },\n {\n name: 'phone_number',\n label: 'Phone Number',\n type: 'text',\n columns: 6\n }\n ]\n },\n\n // Activity tracking view\n activity: {\n title: 'User Activity',\n columns: 2,\n fields: [\n {\n name: 'last_login',\n label: 'Last Login',\n type: 'datetime',\n format: 'relative',\n colSize: 6\n },\n {\n name: 'last_activity',\n label: 'Last Activity',\n type: 'datetime',\n format: 'relative',\n colSize: 6\n }\n ]\n },\n\n // Comprehensive view with all data\n detailed: {\n title: 'Detailed User Information',\n columns: 2,\n showEmptyValues: true,\n emptyValueText: 'Not set',\n fields: [\n // Basic Info Section\n {\n name: 'id',\n label: 'User ID',\n type: 'number',\n colSize: 3\n },\n {\n name: 'display_name',\n label: 'Display Name',\n type: 'text',\n format: 'capitalize|default(\"Unnamed User\")',\n colSize: 9\n },\n {\n name: 'username',\n label: 'Username',\n type: 'text',\n format: 'lowercase',\n colSize: 6\n },\n {\n name: 'email',\n label: 'Email Address',\n type: 'email',\n colSize: 6\n },\n {\n name: 'phone_number',\n label: 'Phone Number',\n type: 'phone',\n format: 'phone|default(\"Not provided\")',\n colSize: 6\n },\n {\n name: 'is_active',\n label: 'Account Status',\n type: 'boolean',\n colSize: 6\n },\n\n // Activity Info\n {\n name: 'last_login',\n label: 'Last Login',\n type: 'datetime',\n format: 'relative',\n colSize: 6\n },\n {\n name: 'last_activity',\n label: 'Last Activity',\n type: 'datetime',\n format: 'relative',\n colSize: 6\n },\n\n // Avatar Info\n {\n name: 'avatar.url',\n label: 'Avatar',\n type: 'url',\n colSize: 12\n },\n\n // Complex Data (will use full width automatically)\n {\n name: 'permissions',\n label: 'User Permissions',\n type: 'dataview',\n dataViewColumns: 2,\n showEmptyValues: false\n },\n {\n name: 'metadata',\n label: 'User Metadata',\n type: 'dataview',\n dataViewColumns: 1\n },\n {\n name: 'avatar',\n label: 'Avatar Details',\n type: 'dataview',\n dataViewColumns: 1\n }\n ]\n },\n\n // Permissions-focused view\n permissions: {\n title: 'User Permissions',\n columns: 1,\n fields: [\n {\n name: 'display_name',\n label: 'User',\n type: 'text',\n format: 'capitalize',\n columns: 12\n },\n {\n name: 'permissions',\n label: 'Assigned Permissions',\n type: 'dataview',\n dataViewColumns: 3,\n showEmptyValues: false,\n colSize: 12\n }\n ]\n },\n\n // Compact summary view\n summary: {\n title: 'User Summary',\n columns: 3,\n fields: [\n {\n name: 'display_name',\n label: 'Name',\n type: 'text',\n format: 'capitalize|truncate(30)'\n },\n {\n name: 'email',\n label: 'Email',\n type: 'email'\n },\n {\n name: 'is_active',\n label: 'Status',\n type: 'boolean'\n },\n {\n name: 'last_activity',\n label: 'Last Seen',\n type: 'datetime',\n format: 'relative',\n colSize: 12\n }\n ]\n }\n};\n\nUser.DATA_VIEW = UserDataView.detailed;\nUser.EDIT_FORM = UserForms.edit;\nUser.ADD_FORM = UserForms.create;\n\n/* =========================\n * UserDevice\n * ========================= */\nclass UserDevice extends Model {\n constructor(data = {}) {\n super(data, {\n endpoint: '/api/user/device',\n });\n }\n\n static async getByDuid(duid) {\n const model = new UserDevice();\n const resp = await model.rest.GET('/api/user/device/lookup', { duid: duid });\n if (resp.success && resp.data && resp.data.data) {\n // A direct lookup should return a single object\n return new UserDevice(resp.data.data);\n }\n return null;\n }\n}\n\nclass UserDeviceList extends Collection {\n constructor(options = {}) {\n super({\n ModelClass: UserDevice,\n endpoint: '/api/user/device',\n ...options,\n });\n }\n}\n\n/* =========================\n * UserDeviceLocation\n * ========================= */\nclass UserDeviceLocation extends Model {\n constructor(data = {}) {\n super(data, {\n endpoint: '/api/user/device/location',\n });\n }\n}\n\nclass UserDeviceLocationList extends Collection {\n constructor(options = {}) {\n super({\n ModelClass: UserDeviceLocation,\n endpoint: '/api/user/device/location',\n ...options,\n });\n }\n}\n\nexport { User, UserList, UserForms, UserDataView, UserDevice, UserDeviceList, UserDeviceLocation, UserDeviceLocationList };\n","/**\n * ContextMenu - A reusable context menu component for MOJO\n *\n * Renders a Bootstrap 5 dropdown menu based on a configuration object.\n * This component is designed to be easily embedded in any other View.\n * It supports the same configuration syntax as the Dialog's contextMenu.\n *\n * Features:\n * - Renders a dropdown button with a configurable icon.\n * - Generates menu items from a configuration array.\n * - Supports dividers, icons, labels, and links.\n * - Handles actions via inline handlers or by emitting an 'action' event.\n *\n * @example\n * const contextMenu = new ContextMenu({\n * config: {\n * icon: 'bi-gear', // Optional: custom trigger icon\n * items: [\n * { label: 'Edit', action: 'edit', icon: 'bi-pencil' },\n * { label: 'Delete', action: 'delete', icon: 'bi-trash', danger: true },\n * { type: 'divider' },\n * {\n * label: 'Custom Action',\n * action: 'custom',\n * icon: 'bi-star',\n * handler: (context) => {\n * console.log('Inline handler called with context:', context);\n * }\n * }\n * ]\n * },\n * context: { id: 123, name: 'My Item' } // Optional data to pass to handlers/events\n * });\n *\n * // Listen for actions from the parent view\n * contextMenu.on('action', (data) => {\n * console.log(`Action '${data.action}' triggered for context:`, data.context);\n * if (data.action === 'edit') {\n * // handle edit\n * }\n * });\n */\n\nimport View from '@core/View.js';\n\nclass ContextMenu extends View {\n constructor(options = {}) {\n super({\n tagName: 'div',\n className: 'context-menu-view dropdown',\n ...options\n });\n\n this.config = options.contextMenu || options.config || {};\n this.context = options.context || {}; // Optional data to pass to handlers/events\n }\n\n /**\n * Build the dropdown menu HTML from the configuration.\n */\n async renderTemplate() {\n const menuItems = this.config.items || [];\n if (menuItems.length === 0) {\n return ''; // Don't render anything if there are no items\n }\n\n const triggerIcon = this.config.icon || 'bi-three-dots-horizontal';\n const buttonClass = this.config.buttonClass || 'btn btn-link text-secondary ps-3 pe-0 pt-0 pb-1';\n const dropdownId = `context-menu-${this.id}`;\n\n const menuItemsHtml = menuItems.map(item => this.buildMenuItemHTML(item)).join('');\n\n return `\n <button class=\"${buttonClass}\" type=\"button\" id=\"${dropdownId}\" data-bs-toggle=\"dropdown\" aria-expanded=\"false\">\n <i class=\"${triggerIcon}\"></i>\n </button>\n <ul class=\"dropdown-menu dropdown-menu-end\" aria-labelledby=\"${dropdownId}\">\n ${menuItemsHtml}\n </ul>\n `;\n }\n\n /**\n * Build the HTML for a single menu item.\n * @param {object} item - The menu item configuration.\n * @returns {string} The HTML string for the list item.\n */\n buildMenuItemHTML(item) {\n if (item.type === 'divider' || item.separator) {\n return '<li><hr class=\"dropdown-divider\"></li>';\n }\n\n const icon = item.icon ? `<i class=\"${item.icon} me-2\"></i>` : '';\n const label = item.label || '';\n const itemClass = `dropdown-item ${item.danger ? 'text-danger' : ''} ${item.disabled ? 'disabled' : ''}`;\n const action = item.action || '';\n\n if (item.href) {\n return `<li><a class=\"${itemClass}\" href=\"${item.href}\" target=\"${item.target || '_self'}\">${icon}${label}</a></li>`;\n }\n\n return `<li><a class=\"${itemClass}\" href=\"#\" data-action=\"menu-item-click\" data-item-action=\"${action}\">${icon}${label}</a></li>`;\n }\n\n /**\n * Handle clicks on menu items.\n * @param {Event} event - The click event.\n * @param {HTMLElement} element - The clicked anchor element.\n */\n async onActionMenuItemClick(event, element) {\n event.preventDefault();\n const action = element.getAttribute('data-item-action');\n if (!action) return;\n\n const menuItem = this.config.items.find(item => item.action === action);\n if (!menuItem || menuItem.disabled) return;\n\n // Support for inline handlers\n if (typeof menuItem.handler === 'function') {\n menuItem.handler(this.context, event, element);\n } else {\n // Emit a general event for parent views to listen to\n // this.emit('action', {\n // action: action,\n // context: this.context,\n // sourceEvent: event\n // });\n this.parent.events.dispatch(action, event, element);\n }\n this.closeDropdown();\n }\n\n closeDropdown() {\n const dropdownTrigger = this.element.querySelector('[data-bs-toggle=\"dropdown\"]');\n if (dropdownTrigger) {\n const dropdownInstance = window.bootstrap?.Dropdown.getInstance(dropdownTrigger);\n dropdownInstance?.hide();\n }\n }\n}\n\nexport default ContextMenu;\n","/**\n * ToastService - Bootstrap 5 Toast Notification Service\n * Provides methods to display toast notifications with different types and options\n *\n * Features:\n * - Bootstrap 5 toast integration\n * - Multiple toast types (success, error, info, warning)\n * - Auto-dismiss with customizable delays\n * - Toast container management\n * - Event integration\n * - Proper cleanup and memory management\n *\n * @example\n * const toastService = new ToastService();\n * toastService.success('Operation completed successfully!');\n * toastService.error('Something went wrong');\n * toastService.info('FYI: This is informational');\n * toastService.warning('Please be careful');\n */\n\nclass ToastService {\n constructor(options = {}) {\n this.options = {\n containerId: 'toast-container',\n position: 'top-end', // top-start, top-center, top-end, middle-start, etc.\n autohide: true,\n defaultDelay: 5000, // 5 seconds\n maxToasts: 5, // Maximum number of toasts to show at once\n ...options\n };\n\n this.toasts = new Map(); // Track active toasts\n this.toastCounter = 0; // For unique IDs\n \n this.init();\n }\n\n /**\n * Initialize the toast service\n */\n init() {\n this.createContainer();\n }\n\n /**\n * Create the toast container if it doesn't exist\n */\n createContainer() {\n let container = document.getElementById(this.options.containerId);\n \n if (!container) {\n container = document.createElement('div');\n container.id = this.options.containerId;\n container.className = `toast-container position-fixed ${this.getPositionClasses()}`;\n container.style.zIndex = '1070'; // Bootstrap toast z-index\n container.setAttribute('aria-live', 'polite');\n container.setAttribute('aria-atomic', 'true');\n \n document.body.appendChild(container);\n }\n \n this.container = container;\n }\n\n /**\n * Get CSS classes for toast positioning\n */\n getPositionClasses() {\n const positionMap = {\n 'top-start': 'top-0 start-0 p-3',\n 'top-center': 'top-0 start-50 translate-middle-x p-3',\n 'top-end': 'top-0 end-0 p-3',\n 'middle-start': 'top-50 start-0 translate-middle-y p-3',\n 'middle-center': 'top-50 start-50 translate-middle p-3',\n 'middle-end': 'top-50 end-0 translate-middle-y p-3',\n 'bottom-start': 'bottom-0 start-0 p-3',\n 'bottom-center': 'bottom-0 start-50 translate-middle-x p-3',\n 'bottom-end': 'bottom-0 end-0 p-3'\n };\n \n return positionMap[this.options.position] || positionMap['top-end'];\n }\n\n\n\n /**\n * Show a success toast\n * @param {string} message - The message to display\n * @param {object} options - Additional options\n */\n success(message, options = {}) {\n return this.show(message, 'success', {\n icon: 'bi-check-circle-fill',\n ...options\n });\n }\n\n /**\n * Show an error toast\n * @param {string} message - The message to display\n * @param {object} options - Additional options\n */\n error(message, options = {}) {\n return this.show(message, 'error', {\n icon: 'bi-exclamation-triangle-fill',\n autohide: false, // Keep error toasts visible until manually dismissed\n ...options\n });\n }\n\n /**\n * Show an info toast\n * @param {string} message - The message to display\n * @param {object} options - Additional options\n */\n info(message, options = {}) {\n return this.show(message, 'info', {\n icon: 'bi-info-circle-fill',\n ...options\n });\n }\n\n /**\n * Show a warning toast\n * @param {string} message - The message to display\n * @param {object} options - Additional options\n */\n warning(message, options = {}) {\n return this.show(message, 'warning', {\n icon: 'bi-exclamation-triangle-fill',\n ...options\n });\n }\n\n /**\n * Show a plain toast without specific styling\n * @param {string} message - The message to display\n * @param {object} options - Additional options\n */\n plain(message, options = {}) {\n return this.show(message, 'plain', {\n ...options\n });\n }\n\n /**\n * Show a toast with specified type and options\n * @param {string} message - The message to display\n * @param {string} type - Toast type (success, error, info, warning)\n * @param {object} options - Additional options\n */\n show(message, type = 'info', options = {}) {\n // Enforce max toasts limit\n this.enforceMaxToasts();\n \n const toastId = `toast-${++this.toastCounter}`;\n const config = {\n title: this.getDefaultTitle(type),\n icon: this.getDefaultIcon(type),\n autohide: this.options.autohide,\n delay: this.options.defaultDelay,\n dismissible: true,\n ...options\n };\n\n const toastElement = this.createToastElement(toastId, message, type, config);\n this.container.appendChild(toastElement);\n\n // Initialize Bootstrap toast\n if (typeof bootstrap === 'undefined') {\n throw new Error('Bootstrap is required for ToastService. Make sure Bootstrap 5 is loaded.');\n }\n const bsToast = new bootstrap.Toast(toastElement, {\n autohide: config.autohide,\n delay: config.delay\n });\n\n // Store toast reference\n this.toasts.set(toastId, {\n element: toastElement,\n bootstrap: bsToast,\n type: type,\n message: message\n });\n\n // Setup cleanup on hide\n toastElement.addEventListener('hidden.bs.toast', () => {\n this.cleanup(toastId);\n });\n\n // Show the toast\n bsToast.show();\n\n return {\n id: toastId,\n hide: () => {\n try {\n bsToast.hide();\n } catch (error) {\n console.warn('Error hiding toast:', error);\n }\n },\n dispose: () => this.cleanup(toastId),\n updateProgress: options.updateProgress || null\n };\n }\n\n /**\n * Show a toast with a View component in the body\n * @param {View} view - The View component to display\n * @param {string} type - Toast type (success, error, info, warning, plain)\n * @param {object} options - Additional options\n */\n showView(view, type = 'info', options = {}) {\n // Enforce max toasts limit\n this.enforceMaxToasts();\n \n const toastId = `toast-${++this.toastCounter}`;\n const config = {\n title: options.title || this.getDefaultTitle(type),\n icon: options.icon || this.getDefaultIcon(type),\n autohide: this.options.autohide,\n delay: this.options.defaultDelay,\n dismissible: true,\n ...options\n };\n\n const toastElement = this.createViewToastElement(toastId, view, type, config);\n this.container.appendChild(toastElement);\n\n // Initialize Bootstrap toast\n if (typeof bootstrap === 'undefined') {\n throw new Error('Bootstrap is required for ToastService. Make sure Bootstrap 5 is loaded.');\n }\n const bsToast = new bootstrap.Toast(toastElement, {\n autohide: config.autohide,\n delay: config.delay\n });\n\n // Store toast reference with view\n this.toasts.set(toastId, {\n element: toastElement,\n bootstrap: bsToast,\n type: type,\n view: view,\n message: 'View toast'\n });\n\n // Setup cleanup on hide - dispose view properly\n toastElement.addEventListener('hidden.bs.toast', () => {\n this.cleanupView(toastId);\n });\n\n // Mount and render the view\n const bodyContainer = toastElement.querySelector('.toast-view-body');\n if (bodyContainer && view) {\n view.render(true, bodyContainer);\n }\n\n // Show the toast\n bsToast.show();\n\n return {\n id: toastId,\n view: view,\n hide: () => {\n try {\n bsToast.hide();\n } catch (error) {\n console.warn('Error hiding view toast:', error);\n }\n },\n dispose: () => this.cleanupView(toastId),\n updateProgress: (progressInfo) => {\n if (view && typeof view.updateProgress === 'function') {\n view.updateProgress(progressInfo);\n }\n }\n };\n }\n\n /**\n * Create toast DOM element\n */\n createToastElement(id, message, type, config) {\n const toast = document.createElement('div');\n toast.id = id;\n toast.className = `toast toast-service-${type}`;\n toast.setAttribute('role', 'alert');\n toast.setAttribute('aria-live', 'assertive');\n toast.setAttribute('aria-atomic', 'true');\n\n const header = config.title || config.icon ? this.createToastHeader(config, type) : '';\n const body = this.createToastBody(message, config.icon && !config.title);\n\n toast.innerHTML = `\n ${header}\n ${body}\n `;\n\n return toast;\n }\n\n /**\n * Create toast DOM element for View component\n */\n createViewToastElement(id, view, type, config) {\n const toast = document.createElement('div');\n toast.id = id;\n toast.className = `toast toast-service-${type}`;\n toast.setAttribute('role', 'alert');\n toast.setAttribute('aria-live', 'assertive');\n toast.setAttribute('aria-atomic', 'true');\n\n const header = config.title || config.icon ? this.createToastHeader(config, type) : '';\n const body = this.createViewToastBody();\n\n toast.innerHTML = `\n ${header}\n ${body}\n `;\n\n return toast;\n }\n\n /**\n * Create toast body for View component\n */\n createViewToastBody() {\n return `\n <div class=\"toast-body p-0\">\n <div class=\"toast-view-body p-3\"></div>\n </div>\n `;\n }\n\n /**\n * Create toast header with title and icon\n */\n createToastHeader(config, _type) {\n const iconHtml = config.icon ? \n `<i class=\"${config.icon} toast-service-icon me-2\"></i>` : '';\n \n const titleHtml = config.title ? \n `<strong class=\"me-auto\">${iconHtml}${this.escapeHtml(config.title)}</strong>` : '';\n\n const timeHtml = config.showTime ? \n `<small class=\"text-muted\">${this.getTimeString()}</small>` : '';\n\n const closeButton = config.dismissible ? \n `<button type=\"button\" class=\"btn-close toast-service-close\" data-bs-dismiss=\"toast\" aria-label=\"Close\"></button>` : '';\n\n if (!titleHtml && !timeHtml && !closeButton) {\n return '';\n }\n\n return `\n <div class=\"toast-header\">\n ${titleHtml}\n ${timeHtml}\n ${closeButton}\n </div>\n `;\n }\n\n /**\n * Create toast body with message\n */\n createToastBody(message, showIcon = false) {\n const iconHtml = showIcon ? \n `<i class=\"${this.getDefaultIcon('info')} toast-service-icon me-2\"></i>` : '';\n \n return `\n <div class=\"toast-body d-flex align-items-center\">\n ${iconHtml}\n <span>${this.escapeHtml(message)}</span>\n </div>\n `;\n }\n\n /**\n * Get default title for toast type\n */\n getDefaultTitle(type) {\n const titles = {\n success: 'Success',\n error: 'Error',\n warning: 'Warning',\n info: 'Information',\n plain: ''\n };\n return titles[type] || 'Notification';\n }\n\n /**\n * Get default icon for toast type\n */\n getDefaultIcon(type) {\n const icons = {\n success: 'bi-check-circle-fill',\n error: 'bi-exclamation-triangle-fill',\n warning: 'bi-exclamation-triangle-fill',\n info: 'bi-info-circle-fill',\n plain: ''\n };\n return icons[type] || 'bi-info-circle-fill';\n }\n\n /**\n * Enforce maximum number of toasts\n */\n enforceMaxToasts() {\n const activeToasts = Array.from(this.toasts.values());\n \n if (activeToasts.length >= this.options.maxToasts) {\n // Remove oldest toast\n const oldestId = this.toasts.keys().next().value;\n const oldest = this.toasts.get(oldestId);\n \n if (oldest) {\n oldest.bootstrap.hide();\n }\n }\n }\n\n /**\n * Clean up toast resources\n */\n cleanup(toastId) {\n const toast = this.toasts.get(toastId);\n \n if (toast) {\n // Dispose Bootstrap toast\n try {\n toast.bootstrap.dispose();\n } catch (e) {\n console.warn('Error disposing toast:', e);\n }\n \n // Remove from DOM\n if (toast.element && toast.element.parentNode) {\n toast.element.parentNode.removeChild(toast.element);\n }\n \n // Remove from tracking\n this.toasts.delete(toastId);\n }\n }\n\n /**\n * Clean up view toast resources with proper view disposal\n */\n cleanupView(toastId) {\n const toast = this.toasts.get(toastId);\n \n if (toast) {\n // Dispose view first if it exists\n if (toast.view && typeof toast.view.dispose === 'function') {\n try {\n toast.view.dispose();\n } catch (e) {\n console.warn('Error disposing view in toast:', e);\n }\n }\n \n // Dispose Bootstrap toast\n try {\n toast.bootstrap.dispose();\n } catch (e) {\n console.warn('Error disposing toast:', e);\n }\n \n // Remove from DOM\n if (toast.element && toast.element.parentNode) {\n toast.element.parentNode.removeChild(toast.element);\n }\n \n // Remove from tracking\n this.toasts.delete(toastId);\n }\n }\n\n /**\n * Hide all active toasts\n */\n hideAll() {\n this.toasts.forEach((toast, _id) => {\n toast.bootstrap.hide();\n });\n }\n\n /**\n * Clear all toasts immediately\n */\n clearAll() {\n this.toasts.forEach((toast, id) => {\n this.cleanup(id);\n });\n }\n\n /**\n * Get current time string\n */\n getTimeString() {\n return new Date().toLocaleTimeString([], { \n hour: '2-digit', \n minute: '2-digit' \n });\n }\n\n /**\n * Escape HTML to prevent XSS\n */\n escapeHtml(str) {\n const div = document.createElement('div');\n div.textContent = str;\n return div.innerHTML;\n }\n\n /**\n * Dispose of the entire toast service\n */\n dispose() {\n this.clearAll();\n \n if (this.container && this.container.parentNode) {\n this.container.parentNode.removeChild(this.container);\n }\n }\n\n /**\n * Get statistics about active toasts\n */\n getStats() {\n const stats = {\n total: this.toasts.size,\n byType: {}\n };\n \n this.toasts.forEach(toast => {\n stats.byType[toast.type] = (stats.byType[toast.type] || 0) + 1;\n });\n \n return stats;\n }\n\n /**\n * Set global options\n */\n setOptions(newOptions) {\n this.options = { ...this.options, ...newOptions };\n \n // Recreate container if position changed\n if (newOptions.position) {\n if (this.container) {\n this.container.className = `toast-container position-fixed ${this.getPositionClasses()}`;\n }\n }\n }\n}\n\nexport default ToastService;"],"names":["Page","View","constructor","options","tagName","className","pageName","id","toLowerCase","replace","super","this","route","title","pageIcon","icon","displayName","pageDescription","params","query","matched","isActive","pageOptions","description","requiresAuth","savedState","onParams","canEnter","permissions","user","getApp","activeUser","hasPermission","requiresGroup","activeGroup","onEnter","onInitView","restoreState","document","emit","page","getMetadata","onExit","captureState","name","onActionDefault","action","makeActive","showPage","onActionNavigate","event","element","preventDefault","dataset","scrollTop","formData","captureFormData","custom","captureCustomState","state","restoreFormData","restoreCustomState","data","querySelectorAll","forEach","field","type","checked","value","Object","entries","querySelector","radio","setMeta","meta","descMeta","createElement","head","appendChild","content","key","metaEl","showError","message","errorDiv","innerHTML","insertBefore","firstChild","setTimeout","parentNode","removeChild","showSuccess","successDiv","onBeforeRender","onAfterMount","body","classList","add","onBeforeDestroy","remove","navigate","app","router","window","MOJO","console","error","getRoute","startsWith","substring","syncUrl","force","updateBrowserUrl","trigger","define","definition","DefinedPage","template","Group","Model","endpoint","GroupList","Collection","ModelClass","size","GroupKinds","org","division","department","team","merchant","partner","client","iso","sales","reseller","location","region","project","inventory","test","misc","qa","GroupKindOptions","map","label","GroupForms","create","fields","required","placeholder","labelField","valueField","maxItems","emptyFetch","debounceMs","edit","cols","detailed","text","level","class","columns","xs","md","imageSize","width","height","help","EDIT_FORM","ADD_FORM","CREATE_FORM","User","permission","Array","isArray","some","p","isSysPermission","permissionToCheck","_hasPermission","member","get","hasPerm","UserList","PERMISSIONS","PERMISSION_FIELDS","UserForms","UserDataView","profile","format","activity","colSize","showEmptyValues","emptyValueText","dataViewColumns","summary","DATA_VIEW","UserDevice","getByDuid","duid","model","resp","rest","GET","success","UserDeviceList","UserDeviceLocation","UserDeviceLocationList","ContextMenu","config","contextMenu","context","renderTemplate","menuItems","items","length","triggerIcon","buttonClass","dropdownId","item","buildMenuItemHTML","join","separator","itemClass","danger","disabled","href","target","onActionMenuItemClick","getAttribute","menuItem","find","handler","parent","events","dispatch","closeDropdown","dropdownTrigger","dropdownInstance","bootstrap","Dropdown","getInstance","hide","containerId","position","autohide","defaultDelay","maxToasts","toasts","Map","toastCounter","init","createContainer","container","getElementById","getPositionClasses","style","zIndex","setAttribute","positionMap","show","info","warning","plain","enforceMaxToasts","toastId","getDefaultTitle","getDefaultIcon","delay","dismissible","toastElement","createToastElement","Error","bsToast","Toast","set","addEventListener","cleanup","warn","dispose","updateProgress","showView","view","createViewToastElement","cleanupView","bodyContainer","render","progressInfo","toast","header","createToastHeader","createToastBody","createViewToastBody","_type","iconHtml","titleHtml","escapeHtml","timeHtml","showTime","getTimeString","closeButton","showIcon","from","values","oldestId","keys","next","oldest","e","delete","hideAll","_id","clearAll","Date","toLocaleTimeString","hour","minute","str","div","textContent","getStats","stats","total","byType","setOptions","newOptions"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import { V as View } from "./Rest-BoKp2Hj4.js";
2
- import { C as Collection, M as Model } from "./Collection-DJaa8dhS.js";
1
+ import { V as View } from "./Rest-ChN4Ntac.js";
2
+ import { C as Collection, M as Model } from "./Collection-G5_fJcpB.js";
3
3
  class Page extends View {
4
4
  constructor(options = {}) {
5
5
  options.tagName = options.tagName || "main";
@@ -1530,4 +1530,4 @@ export {
1530
1530
  UserDeviceLocationList as i,
1531
1531
  Group$1 as j
1532
1532
  };
1533
- //# sourceMappingURL=ContextMenu-CvLNRuJb.js.map
1533
+ //# sourceMappingURL=ContextMenu-CMoik8q6.js.map