web-mojo 2.2.12 → 2.2.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin.cjs.js +1 -1
- package/dist/admin.es.js +4 -4
- package/dist/auth.cjs.js +1 -1
- package/dist/auth.es.js +1 -1
- package/dist/charts.cjs.js +1 -1
- package/dist/charts.es.js +1 -1
- package/dist/chunks/{ChatView-CQnDGafI.js → ChatView-DGulpthL.js} +2 -2
- package/dist/chunks/{ChatView-CQnDGafI.js.map → ChatView-DGulpthL.js.map} +1 -1
- package/dist/chunks/{ChatView-ppMlENSa.js → ChatView-eFzjsHBL.js} +6 -6
- package/dist/chunks/{ChatView-ppMlENSa.js.map → ChatView-eFzjsHBL.js.map} +1 -1
- package/dist/chunks/{Collection-BQxqHtRi.js → Collection-CTkDG1NZ.js} +2 -2
- package/dist/chunks/{Collection-BQxqHtRi.js.map → Collection-CTkDG1NZ.js.map} +1 -1
- package/dist/chunks/{ContextMenu-BNFU-kG4.js → ContextMenu-Capwv7d-.js} +2 -2
- package/dist/chunks/{ContextMenu-BNFU-kG4.js.map → ContextMenu-Capwv7d-.js.map} +1 -1
- package/dist/chunks/{ListView-B96JeG4g.js → ListView-CNkYumcc.js} +2 -2
- package/dist/chunks/{ListView-B96JeG4g.js.map → ListView-CNkYumcc.js.map} +1 -1
- package/dist/chunks/{TokenManager-TEF4Gmwu.js → TokenManager-CBXqj6Iw.js} +3 -3
- package/dist/chunks/{TokenManager-TEF4Gmwu.js.map → TokenManager-CBXqj6Iw.js.map} +1 -1
- package/dist/chunks/{version-C2aAPoA6.js → version-DCTYSNWj.js} +4 -4
- package/dist/chunks/{version-C2aAPoA6.js.map → version-DCTYSNWj.js.map} +1 -1
- package/dist/chunks/{version-CiqJg8U3.js → version-DnlcM3tJ.js} +2 -2
- package/dist/chunks/{version-CiqJg8U3.js.map → version-DnlcM3tJ.js.map} +1 -1
- package/dist/docit.cjs.js +1 -1
- package/dist/docit.es.js +4 -4
- package/dist/index.cjs.js +1 -1
- package/dist/index.es.js +8 -8
- package/dist/lightbox.cjs.js +1 -1
- package/dist/lightbox.es.js +1 -1
- package/dist/map.es.js +1 -1
- package/dist/timeline.es.js +2 -2
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContextMenu-BNFU-kG4.js","sources":["../../src/core/Page.js","../../src/core/services/ToastService.js","../../src/core/models/Group.js","../../src/core/models/User.js","../../src/core/views/feedback/ContextMenu.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","/**\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;","\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"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ContextMenu-Capwv7d-.js","sources":["../../src/core/Page.js","../../src/core/services/ToastService.js","../../src/core/models/Group.js","../../src/core/models/User.js","../../src/core/views/feedback/ContextMenu.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","/**\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;","\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"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { V as View } from "./Rest-0oRgqNjX.js";
|
|
2
|
-
import { C as Collection } from "./Collection-
|
|
2
|
+
import { C as Collection } from "./Collection-CTkDG1NZ.js";
|
|
3
3
|
class ListViewItem extends View {
|
|
4
4
|
constructor(options = {}) {
|
|
5
5
|
super({
|
|
@@ -492,4 +492,4 @@ export {
|
|
|
492
492
|
ListViewItem as L,
|
|
493
493
|
ListView as a
|
|
494
494
|
};
|
|
495
|
-
//# sourceMappingURL=ListView-
|
|
495
|
+
//# sourceMappingURL=ListView-CNkYumcc.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ListView-B96JeG4g.js","sources":["../../src/core/views/list/ListViewItem.js","../../src/core/views/list/ListView.js"],"sourcesContent":["/**\n * ListViewItem - Individual item view for ListView\n *\n * Each item is its own View with its own model, allowing for\n * independent re-rendering when the model changes.\n *\n * Events:\n * - 'item:click' - Emitted when item is clicked\n * - 'item:select' - Emitted when item is selected\n * - 'item:deselect' - Emitted when item is deselected\n *\n * @example\n * const item = new ListViewItem({\n * model: userModel,\n * template: '<div class=\"user-item\">{{name}} - {{email}}</div>'\n * });\n */\n\nimport View from '@core/View.js';\n\nclass ListViewItem extends View {\n constructor(options = {}) {\n super({\n className: 'list-view-item',\n ...options\n });\n\n // Item-specific properties\n this.selected = false;\n this.index = options.index ?? 0;\n this.listView = options.listView ?? null;\n\n // Default template if none provided\n if (!this.template) {\n this.template = `\n <div class=\"list-item-content\" data-action=\"select\">\n {{#model}}\n {{#id}}<span class=\"item-id\">{{id}}</span>{{/id}}\n {{#name}}<span class=\"item-name\">{{name}}</span>{{/name}}\n {{#title}}<span class=\"item-title\">{{title}}</span>{{/title}}\n {{#label}}<span class=\"item-label\">{{label}}</span>{{/label}}\n {{#description}}<p class=\"item-description\">{{description}}</p>{{/description}}\n {{/model}}\n {{^model}}\n <span class=\"item-empty\">No data</span>\n {{/model}}\n </div>\n `;\n }\n }\n\n /**\n * Handle item selection action\n */\n async onActionSelect(event, _element) {\n event.stopPropagation();\n\n if (this.selected) {\n this.deselect();\n } else {\n this.select();\n }\n }\n\n /**\n * Select this item\n */\n select() {\n if (this.selected) return;\n\n this.selected = true;\n this.addClass('selected');\n\n // Emit selection event with item data\n this.emit('item:select', {\n item: this,\n model: this.model,\n index: this.index,\n data: this.model?.toJSON ? this.model.toJSON() : this.model\n });\n\n // Notify parent ListView if available\n if (this.listView) {\n this.listView.emit('item:select', {\n item: this,\n model: this.model,\n index: this.index,\n data: this.model?.toJSON ? this.model.toJSON() : this.model\n });\n }\n }\n\n /**\n * Deselect this item\n */\n deselect() {\n if (!this.selected) return;\n\n this.selected = false;\n this.removeClass('selected');\n\n // Emit deselection event\n this.emit('item:deselect', {\n item: this,\n model: this.model,\n index: this.index,\n data: this.model?.toJSON ? this.model.toJSON() : this.model\n });\n\n // Notify parent ListView if available\n if (this.listView) {\n this.listView.emit('item:deselect', {\n item: this,\n model: this.model,\n index: this.index,\n data: this.model?.toJSON ? this.model.toJSON() : this.model\n });\n }\n }\n\n /**\n * Handle click events on the item\n */\n async onActionDefault(action, _event, _element) {\n // Emit click event for any action not specifically handled\n this.emit('item:click', {\n item: this,\n model: this.model,\n index: this.index,\n action: action,\n data: this.model?.toJSON ? this.model.toJSON() : this.model\n });\n\n // Notify parent ListView if available\n if (this.listView) {\n this.listView.emit('item:click', {\n item: this,\n model: this.model,\n index: this.index,\n action: action,\n data: this.model?.toJSON ? this.model.toJSON() : this.model\n });\n }\n }\n\n /**\n * Set the item's index in the list\n */\n setIndex(index) {\n this.index = index;\n this.element.setAttribute('data-index', index);\n return this;\n }\n\n /**\n * Update the item's selection state\n */\n setSelected(selected) {\n if (selected) {\n this.select();\n } else {\n this.deselect();\n }\n return this;\n }\n\n /**\n * Override destroy to clean up references\n */\n async destroy() {\n // Remove reference to parent ListView\n this.listView = null;\n\n // Call parent destroy\n await super.destroy();\n }\n}\n\nexport default ListViewItem;\n","/**\n * ListView - Visual list component for Collections\n *\n * Manages a collection of ListViewItem views, each with its own model.\n * When a model changes, only its corresponding ListViewItem re-renders.\n *\n * Events:\n * - 'item:click' - Emitted when any item is clicked\n * - 'item:select' - Emitted when an item is selected\n * - 'item:deselect' - Emitted when an item is deselected\n * - 'selection:change' - Emitted when selection changes\n * - 'list:empty' - Emitted when list becomes empty\n * - 'list:loaded' - Emitted when list is populated\n *\n * @example\n * // Basic usage with custom item template\n * const listView = new ListView({\n * collection: userCollection,\n * itemTemplate: '<div class=\"user-item\">{{name}} - {{email}}</div>',\n * selectionMode: 'single'\n * });\n *\n * // Custom template with model fields\n * const productList = new ListView({\n * collection: productCollection,\n * itemTemplate: `\n * <div class=\"product-card\" data-action=\"select\">\n * <h4>{{name}}</h4>\n * <p class=\"price\">{{price|currency}}</p>\n * <p>{{description|truncate(100)}}</p>\n * </div>\n * `,\n * selectionMode: 'multiple'\n * });\n *\n * // Using custom item class with template\n * const customList = new ListView({\n * collection: myCollection,\n * itemClass: CustomListItem, // Your custom ListViewItem subclass\n * itemTemplate: '<div>{{title}}</div>', // Passed as 'template' to itemClass constructor\n * selectionMode: 'none'\n * });\n *\n * // Dynamic template update\n * listView.setItemTemplate('<div class=\"compact\">{{name}}</div>', true);\n */\n\nimport View from '@core/View.js';\nimport Collection from '@core/Collection.js';\nimport ListViewItem from './ListViewItem.js';\n\nclass ListView extends View {\n constructor(options = {}) {\n super({\n className: 'list-view',\n template: `\n <div class=\"list-view-container\">\n {{#loading}}\n <div class=\"list-loading\">\n <div class=\"spinner-border spinner-border-sm\" role=\"status\">\n <span class=\"visually-hidden\">Loading...</span>\n </div>\n Loading...\n </div>\n {{/loading}}\n {{^loading}}\n {{#isEmpty}}\n <div class=\"list-empty\">\n {{emptyMessage}}\n </div>\n {{/isEmpty}}\n {{^isEmpty}}\n <div class=\"list-items\" data-container=\"items\"></div>\n {{/isEmpty}}\n {{/loading}}\n </div>\n `,\n ...options\n });\n\n // ListView specific properties\n this.collection = null;\n this.itemViews = new Map(); // Map of model.id -> ListViewItem\n this.selectedItems = new Set(); // Set of selected item IDs\n\n // Configuration\n this.itemTemplate = options.itemTemplate || null; // Template passed to each item's view\n this.itemClass = options.itemClass || ListViewItem; // Class for creating item views\n this.selectionMode = options.selectionMode || 'none'; // none, single, multiple\n this.emptyMessage = options.emptyMessage || 'No items to display';\n this.loading = false;\n this.isEmpty = true;\n\n }\n\n /**\n * Override onInit to set up initial state\n */\n async onInit() {\n // Initial render will happen automatically\n this._initCollection(this.options.collection || this.options.Collection);\n }\n\n\n /**\n * Initialize the collection\n */\n _initCollection(collectionOrClass) {\n if (!collectionOrClass) {\n console.log('Collection not provided');\n return;\n };\n\n // Check if it's already a Collection instance\n if (collectionOrClass instanceof Collection) {\n this.setCollection(collectionOrClass);\n }\n // Check if it's a Collection class\n else if (typeof collectionOrClass === 'function') {\n const collection = new collectionOrClass();\n this.setCollection(collection);\n }\n // Check if it's an array of data\n else if (Array.isArray(collectionOrClass)) {\n const collection = new Collection(null, {}, collectionOrClass);\n this.setCollection(collection);\n }\n }\n\n /**\n * Set the collection for this list view\n */\n setCollection(collection) {\n if (this.collection === collection) return this;\n\n // Clean up old collection listeners\n if (this.collection) {\n this.collection.off('add', this._onModelsAdded, this);\n this.collection.off('remove', this._onModelsRemoved, this);\n this.collection.off('reset', this._onCollectionReset, this);\n this.collection.off('fetch:start', this._onFetchStart, this);\n this.collection.off('fetch:end', this._onFetchEnd, this);\n }\n\n this.collection = collection;\n\n if (this.options.defaultQuery && !this.options.collectionParams) {\n this.collection.params = { ...this.collection.params, ...this.options.defaultQuery };\n }\n\n if (this.options.collectionParams) {\n this.collection.params = { ...this.collection.params, ...this.options.collectionParams };\n }\n\n // Set up new collection listeners\n if (this.collection) {\n this.collection.on('add', this._onModelsAdded, this);\n this.collection.on('remove', this._onModelsRemoved, this);\n this.collection.on('reset', this._onCollectionReset, this);\n this.collection.on('fetch:start', this._onFetchStart, this);\n this.collection.on('fetch:end', this._onFetchEnd, this);\n\n // Build items for existing models\n this._buildItems();\n }\n\n return this;\n }\n\n async _renderChildren() {\n await super._renderChildren();\n const itemsContainer = this.getChildElement(\"items\");\n if (!itemsContainer) {\n // console.warn('ListView: items container not found');\n return;\n }\n this.forEachItem((item, index) => {\n itemsContainer.appendChild(item.element);\n item.render(false);\n });\n }\n\n /**\n * Build item views for all models in collection\n */\n _buildItems() {\n // Clear existing items\n this._clearItems();\n\n if (!this.collection || this.collection.isEmpty()) {\n this.isEmpty = true;\n this.emit('list:empty');\n return;\n }\n\n this.isEmpty = false;\n\n // Create item views for each model\n this.collection.forEach((model, index) => {\n this._createItemView(model, index);\n });\n\n this.emit('list:loaded', { count: this.collection.length() });\n\n // Render if already mounted\n if (this.isMounted()) {\n this.render();\n }\n }\n\n /**\n * Create an item view for a model\n * The itemTemplate is passed as the template option to the itemClass constructor\n */\n _createItemView(model, index) {\n // Don't create duplicate views\n if (this.itemViews.has(model.id)) return;\n\n const itemView = new this.itemClass({\n model: model,\n index: index,\n listView: this,\n template: this.itemTemplate, // Pass the itemTemplate to the item view\n });\n\n // Store the item view\n this.itemViews.set(model.id, itemView);\n\n // Set up item event listeners\n itemView.on('item:select', this._onItemSelect.bind(this));\n itemView.on('item:deselect', this._onItemDeselect.bind(this));\n\n return itemView;\n }\n\n /**\n * Clear all item views\n */\n _clearItems() {\n this.forEachItem(itemView => {\n this.removeChild(itemView.id);\n });\n this.itemViews.clear();\n this.selectedItems.clear();\n }\n\n /**\n * Handle models added to collection\n */\n _onModelsAdded(event) {\n const { models } = event;\n\n models.forEach(model => {\n const index = this.collection.models.indexOf(model);\n this._createItemView(model, index);\n });\n\n this.isEmpty = this.collection.isEmpty();\n\n // Re-render to show new items\n if (!this.loading && this.isMounted()) {\n this.render();\n }\n }\n\n /**\n * Handle models removed from collection\n */\n _onModelsRemoved(event) {\n const { models } = event;\n\n models.forEach(model => {\n const itemView = this.itemViews.get(model.id);\n if (itemView) {\n this.removeChild(itemView.id);\n this.itemViews.delete(model.id);\n this.selectedItems.delete(model.id);\n }\n });\n\n this.isEmpty = this.collection.isEmpty();\n\n // Re-render to update display\n if (!this.loading && this.isMounted()) {\n this.render();\n }\n\n if (this.isEmpty) {\n this.emit('list:empty');\n }\n }\n\n /**\n * Handle collection reset\n */\n _onCollectionReset(_event) {\n this._buildItems();\n }\n\n /**\n * Handle fetch start\n */\n _onFetchStart() {\n this.loading = true;\n if (this.isMounted()) {\n this.render();\n }\n }\n\n /**\n * Handle fetch end\n */\n _onFetchEnd() {\n this.loading = false;\n if (this.isMounted()) {\n this.render();\n }\n }\n\n /**\n * Handle item selection\n */\n _onItemSelect(event) {\n const { model, item } = event;\n\n if (this.selectionMode === 'none') {\n item.deselect();\n return;\n }\n\n if (this.selectionMode === 'single') {\n // Deselect all other items\n this.itemViews.forEach((view, id) => {\n if (id !== model.id && view.selected) {\n view.deselect();\n }\n });\n this.selectedItems.clear();\n }\n\n this.selectedItems.add(model.id);\n\n this.emit('selection:change', {\n selected: Array.from(this.selectedItems),\n item: item,\n model: model\n });\n }\n\n /**\n * Handle item deselection\n */\n _onItemDeselect(event) {\n const { model } = event;\n\n this.selectedItems.delete(model.id);\n\n this.emit('selection:change', {\n selected: Array.from(this.selectedItems),\n item: event.item,\n model: model\n });\n }\n\n /**\n * Get selected items\n */\n getSelectedItems() {\n const selected = [];\n this.selectedItems.forEach(id => {\n const itemView = this.itemViews.get(id);\n if (itemView) {\n selected.push({\n view: itemView,\n model: itemView.model,\n data: itemView.model?.toJSON ? itemView.model.toJSON() : itemView.model\n });\n }\n });\n return selected;\n }\n\n /**\n * Iterate over each item view in the list\n * @param {function} callback - Function to execute for each item (itemView, model, index)\n * @param {object} thisArg - Optional value to use as this when executing callback\n * @returns {ListView} Returns the ListView for chaining\n */\n forEachItem(callback, thisArg) {\n if (typeof callback !== 'function') {\n throw new TypeError('Callback must be a function');\n }\n\n let index = 0;\n this.itemViews.forEach((itemView, modelId) => {\n callback.call(thisArg, itemView, itemView.model, index++);\n });\n\n return this;\n }\n\n /**\n * Clear selection\n */\n clearSelection() {\n this.forEachItem(itemView => {\n if (itemView.selected) {\n itemView.deselect();\n }\n });\n this.selectedItems.clear();\n\n this.emit('selection:change', {\n selected: []\n });\n }\n\n /**\n * Select item by model ID\n */\n selectItem(modelId) {\n const itemView = this.itemViews.get(modelId);\n if (itemView) {\n itemView.select();\n }\n return this;\n }\n\n /**\n * Deselect item by model ID\n */\n deselectItem(modelId) {\n const itemView = this.itemViews.get(modelId);\n if (itemView) {\n itemView.deselect();\n }\n return this;\n }\n\n /**\n * Set or update the item template\n * @param {string} template - New template string for items\n * @param {boolean} rerender - Whether to re-render existing items with new template\n * @returns {ListView} Returns the ListView for chaining\n */\n setItemTemplate(template, rerender = false) {\n this.itemTemplate = template;\n\n if (rerender && this.itemViews.size > 0) {\n // Update template for all existing item views\n this.forEachItem((itemView) => {\n itemView.setTemplate(template);\n if (itemView.isMounted()) {\n itemView.render();\n }\n });\n }\n\n return this;\n }\n\n async onAfterMount() {\n await super.onAfterMount();\n if (this.collection && (this.options.fetchOnMount || !this.collection.lastFetchTime)) {\n this.collection.fetch();\n }\n }\n\n /**\n * Refresh the list (re-fetch if collection supports it)\n */\n async refresh() {\n if (this.collection && this.collection.restEnabled) {\n return await this.collection.fetch();\n }\n this._buildItems();\n }\n\n /**\n * Override destroy to clean up\n */\n async destroy() {\n // Clean up collection listeners\n if (this.collection) {\n this.collection.off('add', this._onModelsAdded, this);\n this.collection.off('remove', this._onModelsRemoved, this);\n this.collection.off('reset', this._onCollectionReset, this);\n this.collection.off('fetch:start', this._onFetchStart, this);\n this.collection.off('fetch:end', this._onFetchEnd, this);\n }\n\n // Clear items\n this._clearItems();\n\n // Call parent destroy\n await super.destroy();\n }\n}\n\nexport default ListView;\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ListView-CNkYumcc.js","sources":["../../src/core/views/list/ListViewItem.js","../../src/core/views/list/ListView.js"],"sourcesContent":["/**\n * ListViewItem - Individual item view for ListView\n *\n * Each item is its own View with its own model, allowing for\n * independent re-rendering when the model changes.\n *\n * Events:\n * - 'item:click' - Emitted when item is clicked\n * - 'item:select' - Emitted when item is selected\n * - 'item:deselect' - Emitted when item is deselected\n *\n * @example\n * const item = new ListViewItem({\n * model: userModel,\n * template: '<div class=\"user-item\">{{name}} - {{email}}</div>'\n * });\n */\n\nimport View from '@core/View.js';\n\nclass ListViewItem extends View {\n constructor(options = {}) {\n super({\n className: 'list-view-item',\n ...options\n });\n\n // Item-specific properties\n this.selected = false;\n this.index = options.index ?? 0;\n this.listView = options.listView ?? null;\n\n // Default template if none provided\n if (!this.template) {\n this.template = `\n <div class=\"list-item-content\" data-action=\"select\">\n {{#model}}\n {{#id}}<span class=\"item-id\">{{id}}</span>{{/id}}\n {{#name}}<span class=\"item-name\">{{name}}</span>{{/name}}\n {{#title}}<span class=\"item-title\">{{title}}</span>{{/title}}\n {{#label}}<span class=\"item-label\">{{label}}</span>{{/label}}\n {{#description}}<p class=\"item-description\">{{description}}</p>{{/description}}\n {{/model}}\n {{^model}}\n <span class=\"item-empty\">No data</span>\n {{/model}}\n </div>\n `;\n }\n }\n\n /**\n * Handle item selection action\n */\n async onActionSelect(event, _element) {\n event.stopPropagation();\n\n if (this.selected) {\n this.deselect();\n } else {\n this.select();\n }\n }\n\n /**\n * Select this item\n */\n select() {\n if (this.selected) return;\n\n this.selected = true;\n this.addClass('selected');\n\n // Emit selection event with item data\n this.emit('item:select', {\n item: this,\n model: this.model,\n index: this.index,\n data: this.model?.toJSON ? this.model.toJSON() : this.model\n });\n\n // Notify parent ListView if available\n if (this.listView) {\n this.listView.emit('item:select', {\n item: this,\n model: this.model,\n index: this.index,\n data: this.model?.toJSON ? this.model.toJSON() : this.model\n });\n }\n }\n\n /**\n * Deselect this item\n */\n deselect() {\n if (!this.selected) return;\n\n this.selected = false;\n this.removeClass('selected');\n\n // Emit deselection event\n this.emit('item:deselect', {\n item: this,\n model: this.model,\n index: this.index,\n data: this.model?.toJSON ? this.model.toJSON() : this.model\n });\n\n // Notify parent ListView if available\n if (this.listView) {\n this.listView.emit('item:deselect', {\n item: this,\n model: this.model,\n index: this.index,\n data: this.model?.toJSON ? this.model.toJSON() : this.model\n });\n }\n }\n\n /**\n * Handle click events on the item\n */\n async onActionDefault(action, _event, _element) {\n // Emit click event for any action not specifically handled\n this.emit('item:click', {\n item: this,\n model: this.model,\n index: this.index,\n action: action,\n data: this.model?.toJSON ? this.model.toJSON() : this.model\n });\n\n // Notify parent ListView if available\n if (this.listView) {\n this.listView.emit('item:click', {\n item: this,\n model: this.model,\n index: this.index,\n action: action,\n data: this.model?.toJSON ? this.model.toJSON() : this.model\n });\n }\n }\n\n /**\n * Set the item's index in the list\n */\n setIndex(index) {\n this.index = index;\n this.element.setAttribute('data-index', index);\n return this;\n }\n\n /**\n * Update the item's selection state\n */\n setSelected(selected) {\n if (selected) {\n this.select();\n } else {\n this.deselect();\n }\n return this;\n }\n\n /**\n * Override destroy to clean up references\n */\n async destroy() {\n // Remove reference to parent ListView\n this.listView = null;\n\n // Call parent destroy\n await super.destroy();\n }\n}\n\nexport default ListViewItem;\n","/**\n * ListView - Visual list component for Collections\n *\n * Manages a collection of ListViewItem views, each with its own model.\n * When a model changes, only its corresponding ListViewItem re-renders.\n *\n * Events:\n * - 'item:click' - Emitted when any item is clicked\n * - 'item:select' - Emitted when an item is selected\n * - 'item:deselect' - Emitted when an item is deselected\n * - 'selection:change' - Emitted when selection changes\n * - 'list:empty' - Emitted when list becomes empty\n * - 'list:loaded' - Emitted when list is populated\n *\n * @example\n * // Basic usage with custom item template\n * const listView = new ListView({\n * collection: userCollection,\n * itemTemplate: '<div class=\"user-item\">{{name}} - {{email}}</div>',\n * selectionMode: 'single'\n * });\n *\n * // Custom template with model fields\n * const productList = new ListView({\n * collection: productCollection,\n * itemTemplate: `\n * <div class=\"product-card\" data-action=\"select\">\n * <h4>{{name}}</h4>\n * <p class=\"price\">{{price|currency}}</p>\n * <p>{{description|truncate(100)}}</p>\n * </div>\n * `,\n * selectionMode: 'multiple'\n * });\n *\n * // Using custom item class with template\n * const customList = new ListView({\n * collection: myCollection,\n * itemClass: CustomListItem, // Your custom ListViewItem subclass\n * itemTemplate: '<div>{{title}}</div>', // Passed as 'template' to itemClass constructor\n * selectionMode: 'none'\n * });\n *\n * // Dynamic template update\n * listView.setItemTemplate('<div class=\"compact\">{{name}}</div>', true);\n */\n\nimport View from '@core/View.js';\nimport Collection from '@core/Collection.js';\nimport ListViewItem from './ListViewItem.js';\n\nclass ListView extends View {\n constructor(options = {}) {\n super({\n className: 'list-view',\n template: `\n <div class=\"list-view-container\">\n {{#loading}}\n <div class=\"list-loading\">\n <div class=\"spinner-border spinner-border-sm\" role=\"status\">\n <span class=\"visually-hidden\">Loading...</span>\n </div>\n Loading...\n </div>\n {{/loading}}\n {{^loading}}\n {{#isEmpty}}\n <div class=\"list-empty\">\n {{emptyMessage}}\n </div>\n {{/isEmpty}}\n {{^isEmpty}}\n <div class=\"list-items\" data-container=\"items\"></div>\n {{/isEmpty}}\n {{/loading}}\n </div>\n `,\n ...options\n });\n\n // ListView specific properties\n this.collection = null;\n this.itemViews = new Map(); // Map of model.id -> ListViewItem\n this.selectedItems = new Set(); // Set of selected item IDs\n\n // Configuration\n this.itemTemplate = options.itemTemplate || null; // Template passed to each item's view\n this.itemClass = options.itemClass || ListViewItem; // Class for creating item views\n this.selectionMode = options.selectionMode || 'none'; // none, single, multiple\n this.emptyMessage = options.emptyMessage || 'No items to display';\n this.loading = false;\n this.isEmpty = true;\n\n }\n\n /**\n * Override onInit to set up initial state\n */\n async onInit() {\n // Initial render will happen automatically\n this._initCollection(this.options.collection || this.options.Collection);\n }\n\n\n /**\n * Initialize the collection\n */\n _initCollection(collectionOrClass) {\n if (!collectionOrClass) {\n console.log('Collection not provided');\n return;\n };\n\n // Check if it's already a Collection instance\n if (collectionOrClass instanceof Collection) {\n this.setCollection(collectionOrClass);\n }\n // Check if it's a Collection class\n else if (typeof collectionOrClass === 'function') {\n const collection = new collectionOrClass();\n this.setCollection(collection);\n }\n // Check if it's an array of data\n else if (Array.isArray(collectionOrClass)) {\n const collection = new Collection(null, {}, collectionOrClass);\n this.setCollection(collection);\n }\n }\n\n /**\n * Set the collection for this list view\n */\n setCollection(collection) {\n if (this.collection === collection) return this;\n\n // Clean up old collection listeners\n if (this.collection) {\n this.collection.off('add', this._onModelsAdded, this);\n this.collection.off('remove', this._onModelsRemoved, this);\n this.collection.off('reset', this._onCollectionReset, this);\n this.collection.off('fetch:start', this._onFetchStart, this);\n this.collection.off('fetch:end', this._onFetchEnd, this);\n }\n\n this.collection = collection;\n\n if (this.options.defaultQuery && !this.options.collectionParams) {\n this.collection.params = { ...this.collection.params, ...this.options.defaultQuery };\n }\n\n if (this.options.collectionParams) {\n this.collection.params = { ...this.collection.params, ...this.options.collectionParams };\n }\n\n // Set up new collection listeners\n if (this.collection) {\n this.collection.on('add', this._onModelsAdded, this);\n this.collection.on('remove', this._onModelsRemoved, this);\n this.collection.on('reset', this._onCollectionReset, this);\n this.collection.on('fetch:start', this._onFetchStart, this);\n this.collection.on('fetch:end', this._onFetchEnd, this);\n\n // Build items for existing models\n this._buildItems();\n }\n\n return this;\n }\n\n async _renderChildren() {\n await super._renderChildren();\n const itemsContainer = this.getChildElement(\"items\");\n if (!itemsContainer) {\n // console.warn('ListView: items container not found');\n return;\n }\n this.forEachItem((item, index) => {\n itemsContainer.appendChild(item.element);\n item.render(false);\n });\n }\n\n /**\n * Build item views for all models in collection\n */\n _buildItems() {\n // Clear existing items\n this._clearItems();\n\n if (!this.collection || this.collection.isEmpty()) {\n this.isEmpty = true;\n this.emit('list:empty');\n return;\n }\n\n this.isEmpty = false;\n\n // Create item views for each model\n this.collection.forEach((model, index) => {\n this._createItemView(model, index);\n });\n\n this.emit('list:loaded', { count: this.collection.length() });\n\n // Render if already mounted\n if (this.isMounted()) {\n this.render();\n }\n }\n\n /**\n * Create an item view for a model\n * The itemTemplate is passed as the template option to the itemClass constructor\n */\n _createItemView(model, index) {\n // Don't create duplicate views\n if (this.itemViews.has(model.id)) return;\n\n const itemView = new this.itemClass({\n model: model,\n index: index,\n listView: this,\n template: this.itemTemplate, // Pass the itemTemplate to the item view\n });\n\n // Store the item view\n this.itemViews.set(model.id, itemView);\n\n // Set up item event listeners\n itemView.on('item:select', this._onItemSelect.bind(this));\n itemView.on('item:deselect', this._onItemDeselect.bind(this));\n\n return itemView;\n }\n\n /**\n * Clear all item views\n */\n _clearItems() {\n this.forEachItem(itemView => {\n this.removeChild(itemView.id);\n });\n this.itemViews.clear();\n this.selectedItems.clear();\n }\n\n /**\n * Handle models added to collection\n */\n _onModelsAdded(event) {\n const { models } = event;\n\n models.forEach(model => {\n const index = this.collection.models.indexOf(model);\n this._createItemView(model, index);\n });\n\n this.isEmpty = this.collection.isEmpty();\n\n // Re-render to show new items\n if (!this.loading && this.isMounted()) {\n this.render();\n }\n }\n\n /**\n * Handle models removed from collection\n */\n _onModelsRemoved(event) {\n const { models } = event;\n\n models.forEach(model => {\n const itemView = this.itemViews.get(model.id);\n if (itemView) {\n this.removeChild(itemView.id);\n this.itemViews.delete(model.id);\n this.selectedItems.delete(model.id);\n }\n });\n\n this.isEmpty = this.collection.isEmpty();\n\n // Re-render to update display\n if (!this.loading && this.isMounted()) {\n this.render();\n }\n\n if (this.isEmpty) {\n this.emit('list:empty');\n }\n }\n\n /**\n * Handle collection reset\n */\n _onCollectionReset(_event) {\n this._buildItems();\n }\n\n /**\n * Handle fetch start\n */\n _onFetchStart() {\n this.loading = true;\n if (this.isMounted()) {\n this.render();\n }\n }\n\n /**\n * Handle fetch end\n */\n _onFetchEnd() {\n this.loading = false;\n if (this.isMounted()) {\n this.render();\n }\n }\n\n /**\n * Handle item selection\n */\n _onItemSelect(event) {\n const { model, item } = event;\n\n if (this.selectionMode === 'none') {\n item.deselect();\n return;\n }\n\n if (this.selectionMode === 'single') {\n // Deselect all other items\n this.itemViews.forEach((view, id) => {\n if (id !== model.id && view.selected) {\n view.deselect();\n }\n });\n this.selectedItems.clear();\n }\n\n this.selectedItems.add(model.id);\n\n this.emit('selection:change', {\n selected: Array.from(this.selectedItems),\n item: item,\n model: model\n });\n }\n\n /**\n * Handle item deselection\n */\n _onItemDeselect(event) {\n const { model } = event;\n\n this.selectedItems.delete(model.id);\n\n this.emit('selection:change', {\n selected: Array.from(this.selectedItems),\n item: event.item,\n model: model\n });\n }\n\n /**\n * Get selected items\n */\n getSelectedItems() {\n const selected = [];\n this.selectedItems.forEach(id => {\n const itemView = this.itemViews.get(id);\n if (itemView) {\n selected.push({\n view: itemView,\n model: itemView.model,\n data: itemView.model?.toJSON ? itemView.model.toJSON() : itemView.model\n });\n }\n });\n return selected;\n }\n\n /**\n * Iterate over each item view in the list\n * @param {function} callback - Function to execute for each item (itemView, model, index)\n * @param {object} thisArg - Optional value to use as this when executing callback\n * @returns {ListView} Returns the ListView for chaining\n */\n forEachItem(callback, thisArg) {\n if (typeof callback !== 'function') {\n throw new TypeError('Callback must be a function');\n }\n\n let index = 0;\n this.itemViews.forEach((itemView, modelId) => {\n callback.call(thisArg, itemView, itemView.model, index++);\n });\n\n return this;\n }\n\n /**\n * Clear selection\n */\n clearSelection() {\n this.forEachItem(itemView => {\n if (itemView.selected) {\n itemView.deselect();\n }\n });\n this.selectedItems.clear();\n\n this.emit('selection:change', {\n selected: []\n });\n }\n\n /**\n * Select item by model ID\n */\n selectItem(modelId) {\n const itemView = this.itemViews.get(modelId);\n if (itemView) {\n itemView.select();\n }\n return this;\n }\n\n /**\n * Deselect item by model ID\n */\n deselectItem(modelId) {\n const itemView = this.itemViews.get(modelId);\n if (itemView) {\n itemView.deselect();\n }\n return this;\n }\n\n /**\n * Set or update the item template\n * @param {string} template - New template string for items\n * @param {boolean} rerender - Whether to re-render existing items with new template\n * @returns {ListView} Returns the ListView for chaining\n */\n setItemTemplate(template, rerender = false) {\n this.itemTemplate = template;\n\n if (rerender && this.itemViews.size > 0) {\n // Update template for all existing item views\n this.forEachItem((itemView) => {\n itemView.setTemplate(template);\n if (itemView.isMounted()) {\n itemView.render();\n }\n });\n }\n\n return this;\n }\n\n async onAfterMount() {\n await super.onAfterMount();\n if (this.collection && (this.options.fetchOnMount || !this.collection.lastFetchTime)) {\n this.collection.fetch();\n }\n }\n\n /**\n * Refresh the list (re-fetch if collection supports it)\n */\n async refresh() {\n if (this.collection && this.collection.restEnabled) {\n return await this.collection.fetch();\n }\n this._buildItems();\n }\n\n /**\n * Override destroy to clean up\n */\n async destroy() {\n // Clean up collection listeners\n if (this.collection) {\n this.collection.off('add', this._onModelsAdded, this);\n this.collection.off('remove', this._onModelsRemoved, this);\n this.collection.off('reset', this._onCollectionReset, this);\n this.collection.off('fetch:start', this._onFetchStart, this);\n this.collection.off('fetch:end', this._onFetchEnd, this);\n }\n\n // Clear items\n this._clearItems();\n\n // Call parent destroy\n await super.destroy();\n }\n}\n\nexport default ListView;\n"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { V as View } from "./Rest-0oRgqNjX.js";
|
|
2
2
|
import { D as Dialog } from "./Dialog-RzLLLfJD.js";
|
|
3
|
-
import { G as GroupList } from "./ContextMenu-
|
|
3
|
+
import { G as GroupList } from "./ContextMenu-Capwv7d-.js";
|
|
4
4
|
class ResultsView extends View {
|
|
5
5
|
constructor(options = {}) {
|
|
6
6
|
super({
|
|
@@ -977,7 +977,7 @@ class TopNav extends View {
|
|
|
977
977
|
await this.groupSelectorButton.onActionShowSelector(event);
|
|
978
978
|
return true;
|
|
979
979
|
}
|
|
980
|
-
const { GroupList: GroupList2 } = await import("./ContextMenu-
|
|
980
|
+
const { GroupList: GroupList2 } = await import("./ContextMenu-Capwv7d-.js").then((n) => n.j);
|
|
981
981
|
const tempSelector = new GroupSelectorButton({
|
|
982
982
|
Collection: GroupList2,
|
|
983
983
|
currentGroup: this.getApp()?.activeGroup
|
|
@@ -1420,4 +1420,4 @@ export {
|
|
|
1420
1420
|
TokenManager as T,
|
|
1421
1421
|
TopNav as a
|
|
1422
1422
|
};
|
|
1423
|
-
//# sourceMappingURL=TokenManager-
|
|
1423
|
+
//# sourceMappingURL=TokenManager-CBXqj6Iw.js.map
|