web-mojo 2.1.995 → 2.1.1044

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/README.md +19 -16
  2. package/dist/admin.cjs.js +1 -1
  3. package/dist/admin.cjs.js.map +1 -1
  4. package/dist/admin.es.js +739 -24
  5. package/dist/admin.es.js.map +1 -1
  6. package/dist/auth.cjs.js +1 -1
  7. package/dist/auth.cjs.js.map +1 -1
  8. package/dist/auth.css +305 -266
  9. package/dist/auth.es.js +537 -2175
  10. package/dist/auth.es.js.map +1 -1
  11. package/dist/charts.cjs.js +1 -1
  12. package/dist/charts.es.js +3 -2
  13. package/dist/charts.es.js.map +1 -1
  14. package/dist/chunks/ChatView-Bvkdj-lq.js +2 -0
  15. package/dist/chunks/ChatView-Bvkdj-lq.js.map +1 -0
  16. package/dist/chunks/{ChatView-Bk3XGtNh.js → ChatView-DBgQzOyI.js} +14 -6
  17. package/dist/chunks/ChatView-DBgQzOyI.js.map +1 -0
  18. package/dist/chunks/{ContextMenu-BuEqfeZS.js → ContextMenu-hQH_6Pyi.js} +349 -2
  19. package/dist/chunks/ContextMenu-hQH_6Pyi.js.map +1 -0
  20. package/dist/chunks/ContextMenu-snx9Dd1s.js +3 -0
  21. package/dist/chunks/ContextMenu-snx9Dd1s.js.map +1 -0
  22. package/dist/chunks/{DataView-OUqaLmGB.js → DataView-CWejLV3B.js} +2 -1
  23. package/dist/chunks/DataView-CWejLV3B.js.map +1 -0
  24. package/dist/chunks/DataView-D7j4IWyS.js +2 -0
  25. package/dist/chunks/DataView-D7j4IWyS.js.map +1 -0
  26. package/dist/chunks/Dialog-7T8ENHYD.js +2 -0
  27. package/dist/chunks/Dialog-7T8ENHYD.js.map +1 -0
  28. package/dist/chunks/{Dialog-BiVgKzSK.js → Dialog-BcJG5Vta.js} +1358 -4
  29. package/dist/chunks/Dialog-BcJG5Vta.js.map +1 -0
  30. package/dist/chunks/MetricsMiniChartWidget-CN1HPnWf.js +2 -0
  31. package/dist/chunks/{MetricsMiniChartWidget-Esvv-lFp.js.map → MetricsMiniChartWidget-CN1HPnWf.js.map} +1 -1
  32. package/dist/chunks/{MetricsMiniChartWidget-CCroU6BZ.js → MetricsMiniChartWidget-DALWxrzu.js} +2 -2
  33. package/dist/chunks/{MetricsMiniChartWidget-CCroU6BZ.js.map → MetricsMiniChartWidget-DALWxrzu.js.map} +1 -1
  34. package/dist/chunks/{PDFViewer-NeL91Gon.js → PDFViewer-CgdSGU1n.js} +2 -2
  35. package/dist/chunks/{PDFViewer-NeL91Gon.js.map → PDFViewer-CgdSGU1n.js.map} +1 -1
  36. package/dist/chunks/{PDFViewer-D4uo3oiA.js → PDFViewer-DtJIlPXi.js} +2 -2
  37. package/dist/chunks/{PDFViewer-D4uo3oiA.js.map → PDFViewer-DtJIlPXi.js.map} +1 -1
  38. package/dist/chunks/{TopNav-CYTDmhAF.js → TokenManager-BanwFrq7.js} +368 -5
  39. package/dist/chunks/TokenManager-BanwFrq7.js.map +1 -0
  40. package/dist/chunks/TokenManager-DIEFCQ3B.js +2 -0
  41. package/dist/chunks/TokenManager-DIEFCQ3B.js.map +1 -0
  42. package/dist/chunks/version-BaFu2yii.js +38 -0
  43. package/dist/chunks/version-BaFu2yii.js.map +1 -0
  44. package/dist/chunks/version-WMgX72-y.js +2 -0
  45. package/dist/chunks/version-WMgX72-y.js.map +1 -0
  46. package/dist/css/web-mojo.css +1 -17
  47. package/dist/docit.cjs.js +1 -1
  48. package/dist/docit.cjs.js.map +1 -1
  49. package/dist/docit.es.js +4 -6
  50. package/dist/docit.es.js.map +1 -1
  51. package/dist/index.cjs.js +1 -1
  52. package/dist/index.cjs.js.map +1 -1
  53. package/dist/index.es.js +29 -31
  54. package/dist/index.es.js.map +1 -1
  55. package/dist/lightbox.cjs.js +1 -1
  56. package/dist/lightbox.cjs.js.map +1 -1
  57. package/dist/lightbox.es.js +4 -3
  58. package/dist/lightbox.es.js.map +1 -1
  59. package/package.json +1 -1
  60. package/dist/chunks/ChatView-Bk3XGtNh.js.map +0 -1
  61. package/dist/chunks/ChatView-Bz_YZdHd.js +0 -2
  62. package/dist/chunks/ChatView-Bz_YZdHd.js.map +0 -1
  63. package/dist/chunks/ContextMenu-BuEqfeZS.js.map +0 -1
  64. package/dist/chunks/ContextMenu-DcLhcYMp.js +0 -3
  65. package/dist/chunks/ContextMenu-DcLhcYMp.js.map +0 -1
  66. package/dist/chunks/DataView-CdDY9ijM.js +0 -2
  67. package/dist/chunks/DataView-CdDY9ijM.js.map +0 -1
  68. package/dist/chunks/DataView-OUqaLmGB.js.map +0 -1
  69. package/dist/chunks/Dialog-BiVgKzSK.js.map +0 -1
  70. package/dist/chunks/Dialog-DmIPK_Bi.js +0 -2
  71. package/dist/chunks/Dialog-DmIPK_Bi.js.map +0 -1
  72. package/dist/chunks/MetricsMiniChartWidget-Esvv-lFp.js +0 -2
  73. package/dist/chunks/Page-CvbwEoLv.js +0 -2
  74. package/dist/chunks/Page-CvbwEoLv.js.map +0 -1
  75. package/dist/chunks/Page-Deq4y2Kq.js +0 -351
  76. package/dist/chunks/Page-Deq4y2Kq.js.map +0 -1
  77. package/dist/chunks/TokenManager-CAZNcCMs.js +0 -366
  78. package/dist/chunks/TokenManager-CAZNcCMs.js.map +0 -1
  79. package/dist/chunks/TokenManager-CJBYcVqs.js +0 -2
  80. package/dist/chunks/TokenManager-CJBYcVqs.js.map +0 -1
  81. package/dist/chunks/TopNav-23B5R-dl.js +0 -2
  82. package/dist/chunks/TopNav-23B5R-dl.js.map +0 -1
  83. package/dist/chunks/TopNav-CYTDmhAF.js.map +0 -1
  84. package/dist/chunks/WebApp-CQKxglmg.js +0 -2
  85. package/dist/chunks/WebApp-CQKxglmg.js.map +0 -1
  86. package/dist/chunks/WebApp-CWuDQOYo.js +0 -1388
  87. package/dist/chunks/WebApp-CWuDQOYo.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"DataView-OUqaLmGB.js","sources":["../../src/core/views/data/DataView.js"],"sourcesContent":["/**\n * DataView - Key/Value data display component for MOJO framework\n * Extends View to display object data in a responsive grid layout with intelligent formatting support\n *\n * Features:\n * - Automatic field generation from data with intelligent type inference\n * - Smart DataFormatter pipe chains (e.g., \"date('MMM D, YYYY')|capitalize\")\n * - Contextual formatting based on field names and values\n * - Support for complex pipe chains like \"truncate(100)|capitalize|badge\"\n * - Nested DataView support with type=\"dataview\" for complex objects\n * - Custom format overrides with fluent API\n * - No format collision: custom field.format completely overrides DataView formatting\n *\n * Format Behavior:\n * - No field.format: DataView applies type-based HTML formatting (badges, links, etc.)\n * - With field.format: DataFormatter handles ALL formatting, DataView only escapes HTML\n *\n * Example Usage:\n * ```javascript\n * const dataView = new DataView({\n * data: {\n * name: 'john doe',\n * email: 'john@example.com',\n * createdAt: '2024-01-15T10:30:00Z',\n * price: 99.99,\n * description: 'A very long description that should be truncated...',\n * isActive: true\n * }\n * });\n *\n * // Auto-inferred formats (DataView adds HTML styling):\n * // name: \"truncate(50)|capitalize\"\n * // email: no format → DataView creates mailto: link\n * // createdAt: \"date('MMM D, YYYY')\"\n * // price: \"currency\"\n * // description: \"truncate(200)\"\n * // isActive: no format → DataView creates badge styling\n *\n * // Custom format overrides (DataFormatter handles ALL formatting):\n * dataView\n * .setFieldFormat('name', 'uppercase|truncate(20)') // No DataView HTML styling\n * .setFieldFormat('email', 'email|uppercase') // No mailto: link\n * .setFieldFormat('isActive', 'boolean|uppercase') // No badge styling\n * .setFieldFormats({\n * description: 'truncate(50)|capitalize',\n * createdAt: 'relative'\n * });\n *\n * // Nested DataView for complex objects:\n * dataView.setFieldFormat('permissions', null); // Clear auto-format\n * // Then configure field: { name: 'permissions', type: 'dataview', label: 'User Permissions' }\n * ```\n */\n\nimport View from '@core/View.js';\nimport dataFormatter from '@core/utils/DataFormatter.js';\n\nclass DataView extends View {\n constructor(options = {}) {\n // Extract DataView-specific options\n const {\n data,\n model,\n fields,\n columns,\n responsive,\n showEmptyValues,\n emptyValueText,\n ...viewOptions\n } = options;\n\n // Set default view options\n super({\n tagName: 'div',\n className: 'data-view',\n ...viewOptions\n });\n\n // Core properties\n this.data = data || {};\n this.fields = fields || [];\n this.model = model || null;\n\n // If a model is provided, use it as data source\n if (this.model) {\n this.data = this.model;\n }\n\n // DataView-specific configuration\n this.dataViewOptions = {\n columns: columns || 2,\n responsive: responsive !== false, // Default to true\n showEmptyValues: showEmptyValues || false,\n emptyValueText: emptyValueText || '—',\n rowClass: 'row g-3',\n itemClass: 'data-view-item',\n labelClass: 'data-view-label fw-semibold text-muted small text-uppercase',\n valueClass: 'data-view-value'\n };\n }\n\n /**\n * Lifecycle hook - prepare data and fields before rendering\n */\n async onBeforeRender() {\n\n // Auto-generate fields from data if none provided\n if (this.fields.length === 0 && this.getData()) {\n this.generateFieldsFromData();\n }\n }\n\n /**\n * Override renderTemplate to generate HTML directly\n * @returns {string} Complete HTML string\n */\n async renderTemplate() {\n const items = this.buildItemsHTML();\n\n return `\n <div class=\"${this.dataViewOptions.rowClass}\">\n ${items}\n </div>\n `;\n }\n\n /**\n * Auto-generate field definitions from data object with intelligent type inference\n */\n generateFieldsFromData() {\n const dataObj = this.getData();\n\n if (dataObj && typeof dataObj === 'object') {\n this.fields = Object.keys(dataObj).map(key => {\n const value = dataObj[key];\n const fieldType = this.inferFieldType(value, key);\n const formatter = this.inferFormatter(value, key, fieldType);\n\n return {\n name: key,\n label: this.formatLabel(key),\n type: fieldType,\n format: formatter,\n formatter: formatter // Alias for consistency with TableView\n };\n });\n }\n }\n\n /**\n * Format field name into a readable label\n * @param {string} name - Field name\n * @returns {string} Formatted label\n */\n formatLabel(name) {\n return name\n .replace(/([A-Z])/g, ' $1') // Add space before capital letters\n .replace(/[_-]/g, ' ') // Replace underscores and hyphens with spaces\n .replace(/\\b\\w/g, l => l.toUpperCase()) // Title case\n .trim();\n }\n\n /**\n * Infer field type from value and key with improved intelligence\n * @param {*} value - Field value\n * @param {string} key - Field key\n * @returns {string} Field type\n */\n inferFieldType(value, key = '') {\n if (value === null || value === undefined) return 'text';\n\n const keyLower = key.toLowerCase();\n const type = typeof value;\n\n // Date/time patterns\n if (keyLower.includes('date') || keyLower.includes('time') ||\n keyLower.includes('created') || keyLower.includes('updated') ||\n keyLower.includes('modified') || keyLower.includes('last_login') ||\n keyLower.includes('expires') || keyLower.includes('last_activity')) {\n return 'datetime';\n }\n\n // Email patterns\n if (keyLower.includes('email') || keyLower.includes('mail')) {\n return 'email';\n }\n\n // URL patterns\n if (keyLower.includes('url') || keyLower.includes('link') ||\n keyLower.includes('website') || keyLower.includes('homepage')) {\n return 'url';\n }\n\n // Phone patterns\n if (keyLower.includes('phone') || keyLower.includes('tel') ||\n keyLower.includes('mobile') || keyLower.includes('cell')) {\n return 'phone';\n }\n\n // Currency/price patterns\n if (keyLower.includes('price') || keyLower.includes('cost') ||\n keyLower.includes('amount') || keyLower.includes('fee') ||\n keyLower.includes('salary') || keyLower.includes('revenue')) {\n return 'currency';\n }\n\n // File size patterns\n if (keyLower.includes('size') || keyLower.includes('bytes')) {\n return 'filesize';\n }\n\n // Percentage patterns\n if (keyLower.includes('percent') || keyLower.includes('rate') ||\n keyLower.includes('ratio') && type === 'number') {\n return 'percent';\n }\n\n // Type-based inference\n if (type === 'boolean') return 'boolean';\n if (type === 'number') return 'number';\n\n if (type === 'object') {\n if (Array.isArray(value)) return 'array';\n if (value && value.renditions) return 'file';\n\n // Check if object should be displayed as nested DataView\n if (this.shouldUseDataView(value, keyLower)) {\n return 'dataview';\n }\n\n return 'object';\n }\n\n if (type === 'string') {\n // Pattern matching for strings\n if (value.includes('@') && value.includes('.')) return 'email';\n if (value.match(/^\\d{4}-\\d{2}-\\d{2}/)) return 'date';\n if (value.match(/^https?:\\/\\//)) return 'url';\n if (value.match(/^\\+?[\\d\\s\\-\\(\\)]+$/)) return 'phone';\n }\n\n return 'text';\n }\n\n /**\n * Infer appropriate formatter based on type and context\n * @param {*} value - Field value\n * @param {string} key - Field key\n * @param {string} fieldType - Inferred field type\n * @returns {string|null} Formatter pipe string\n */\n inferFormatter(value, key, fieldType) {\n const keyLower = key.toLowerCase();\n const formatters = [];\n\n switch (fieldType) {\n case 'datetime':\n if (keyLower.includes('time') && !keyLower.includes('date')) {\n formatters.push('time');\n } else if (keyLower.includes('relative') || keyLower.includes('ago') || keyLower.includes('last_')) {\n formatters.push('relative');\n } else if (keyLower.includes('created') || keyLower.includes('updated') || keyLower.includes('modified')) {\n formatters.push('date(\"MMM D, YYYY\")');\n } else {\n formatters.push('date(\"MMMM D, YYYY\")');\n }\n break;\n\n case 'date':\n if (keyLower.includes('birth') || keyLower.includes('dob')) {\n formatters.push('date(\"MMMM D, YYYY\")');\n } else {\n formatters.push('date(\"MMM D, YYYY\")');\n }\n break;\n\n case 'email':\n // Don't apply email formatter - DataView handles mailto: links automatically\n break;\n\n case 'url':\n // Don't apply url formatter - DataView handles clickable links automatically\n break;\n\n case 'phone':\n formatters.push('phone');\n break;\n\n case 'currency':\n formatters.push('currency');\n // Add currency symbol detection if needed\n if (keyLower.includes('eur') || keyLower.includes('euro')) {\n formatters[formatters.length - 1] = 'currency(\"EUR\")';\n } else if (keyLower.includes('gbp') || keyLower.includes('pound')) {\n formatters[formatters.length - 1] = 'currency(\"GBP\")';\n }\n break;\n\n case 'filesize':\n formatters.push('filesize');\n break;\n\n case 'percent':\n formatters.push('percent');\n break;\n\n case 'number':\n // Smart number formatting with pipe chains\n if (typeof value === 'number') {\n if (keyLower.includes('count') || keyLower.includes('total') || keyLower.includes('followers') || keyLower.includes('views')) {\n if (value >= 1000) {\n formatters.push('compact');\n } else {\n formatters.push('number');\n }\n } else if (keyLower.includes('score') || keyLower.includes('rating')) {\n formatters.push('number');\n // Add decimal places for scores\n if (value % 1 !== 0) {\n formatters[formatters.length - 1] = 'number(1)';\n }\n } else if (keyLower.includes('version') || keyLower.includes('id')) {\n // Don't format IDs and versions\n return null;\n } else {\n formatters.push('number');\n }\n }\n break;\n\n case 'boolean':\n // Don't apply boolean formatter - DataView handles badge styling automatically\n break;\n\n case 'text':\n // Smart text formatting with contextual pipe chains\n if (typeof value === 'string') {\n // Handle different text contexts\n if (keyLower.includes('description') || keyLower.includes('content') || keyLower.includes('body')) {\n if (value.length > 200) {\n formatters.push('truncate(200)');\n } else if (value.length > 100) {\n formatters.push('truncate(100)');\n }\n } else if (keyLower.includes('summary') || keyLower.includes('excerpt')) {\n if (value.length > 150) {\n formatters.push('truncate(150)');\n }\n } else if (keyLower.includes('name') || keyLower.includes('title') || keyLower.includes('label')) {\n formatters.push('capitalize');\n if (value.length > 50) {\n formatters.unshift('truncate(50)'); // Truncate first, then capitalize\n }\n } else if (keyLower.includes('slug') || keyLower.includes('handle') || keyLower.includes('username')) {\n formatters.push('slug');\n } else if (keyLower.includes('code') || keyLower.includes('token') || keyLower.includes('key')) {\n // Show codes/tokens with masking if long\n if (value.length > 20) {\n formatters.push('mask');\n }\n } else {\n // Generic text handling\n if (value.length > 100) {\n formatters.push('truncate(100)');\n }\n }\n }\n break;\n\n case 'array':\n case 'object':\n // Don't apply json formatter - DataView handles JSON display automatically\n break;\n\n case 'dataview':\n // Don't apply any formatter - nested DataView handles its own formatting\n break;\n\n default:\n // Handle any missed cases with basic text formatting\n if (typeof value === 'string' && value.length > 100) {\n formatters.push('truncate(100)');\n }\n break;\n }\n\n return formatters.length > 0 ? formatters.join('|') : null;\n }\n\n /**\n * Determine if an object should be displayed as nested DataView vs JSON\n * @param {object} value - Object value to check\n * @param {string} keyLower - Lowercase field key\n * @returns {boolean} True if should use DataView\n */\n shouldUseDataView(value, keyLower) {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return false;\n }\n\n // Check for common patterns that benefit from DataView display\n const dataViewPatterns = [\n 'permissions', 'perms', 'access', 'rights',\n 'settings', 'config', 'configuration', 'options',\n 'profile', 'info', 'details', 'data',\n 'metadata', 'meta', 'attributes', 'props',\n 'preferences', 'prefs', 'user_data',\n 'contact', 'address', 'location',\n 'stats', 'statistics', 'metrics', 'counts'\n ];\n\n if (window.utils && window.utils.isObject(value) && value.id) {\n return true;\n }\n\n // Check if key matches common patterns\n const matchesPattern = dataViewPatterns.some(pattern => keyLower.includes(pattern));\n\n if (matchesPattern) {\n // Additional checks to ensure it's suitable for DataView\n const keys = Object.keys(value);\n\n // Good candidates: objects with multiple simple key-value pairs\n if (keys.length >= 2 && keys.length <= 20) {\n const hasComplexNesting = keys.some(k =>\n typeof value[k] === 'object' &&\n value[k] !== null &&\n !Array.isArray(value[k]) &&\n Object.keys(value[k]).length > 3\n );\n\n // Use DataView if not too deeply nested\n if (!hasComplexNesting) {\n return true;\n }\n }\n }\n\n return false;\n }\n\n /**\n * Get data object (handles both raw objects and Models)\n * @returns {object} Data object\n */\n getData() {\n if (this.model && this.model.attributes) {\n return { ...this.model.attributes };\n }\n return this.data || {};\n }\n\n /**\n * Get field value with formatting support\n * @param {object} field - Field definition\n * @returns {*} Field value (formatted if specified)\n */\n getFieldValue(field) {\n let value;\n let key = field.name || field.key;\n let formatString = field.format || field.formatter;\n\n // Check if the name field contains a pipe (e.g., 'is_tor|status_text')\n // This allows inline formatter syntax in the name field\n if (key && key.includes('|')) {\n const parts = key.split('|');\n key = parts[0].trim();\n // If no explicit formatter was set, use the one from the name\n if (!formatString) {\n formatString = parts.slice(1).join('|').trim();\n }\n }\n\n // Get raw value from data source\n if (this.model && typeof this.model.get === 'function') {\n // For models, get raw value first, then apply formatting separately\n // This ensures we don't break pipe chains by concatenating strings\n value = this.model.get(key);\n } else {\n // Plain object access\n value = this.getData()[key];\n }\n\n // Apply formatting using DataFormatter pipe system if specified\n // Support both 'format' and 'formatter' for consistency with TableView\n if (formatString) {\n value = dataFormatter.pipe(value, formatString);\n }\n\n // Handle empty values\n if (value === null || value === undefined || value === '') {\n return this.dataViewOptions.showEmptyValues ? this.dataViewOptions.emptyValueText : null;\n }\n\n // Apply template if provided\n if (field.template) {\n const modelData = this.model ? this.model : this.data;\n return this.renderTemplateString(field.template, modelData);\n }\n\n return value;\n }\n\n /**\n * Render a template string with data from a model or object.\n * Replaces {{key}} and {{nested.key}} placeholders.\n * @param {string} templateString - The template string.\n * @param {object} data - The data object or model.\n * @returns {string} The rendered string.\n */\n renderTemplateString(templateString, data) {\n if (!templateString || !data) {\n return '';\n }\n\n // Regex to find all {{...}} placeholders\n return templateString.replace(/\\{\\{([^}]+)\\}\\}/g, (match, key) => {\n const trimmedKey = key.trim();\n let value;\n\n // Handle potential formatters in the template key\n const parts = trimmedKey.split('|');\n const dataKey = parts[0];\n const formatters = parts.slice(1).join('|');\n\n // Get value from model or plain object\n if (this.model && typeof this.model.get === 'function') {\n value = this.model.get(dataKey);\n } else {\n // Handle nested keys for plain objects\n value = dataKey.split('.').reduce((o, i) => (o ? o[i] : undefined), data);\n }\n\n // Apply formatters if any\n if (formatters) {\n value = dataFormatter.pipe(value, formatters);\n }\n\n return value !== undefined && value !== null ? value : '';\n });\n }\n\n /**\n * Generate column classes based on configuration\n * @param {object} field - Field definition\n * @returns {string} CSS classes\n */\n getColumnClasses(field) {\n let classes = this.getColumnSizeClasses(field);\n if (field.justify == \"right\") {\n classes += ` d-flex justify-content-end`;\n } else if (field.justify == \"center\") {\n classes += ` d-flex justify-content-center`;\n }\n return classes;\n }\n\n /**\n * Generate column size classes based on configuration\n * @param {object} field - Field definition\n * @returns {string} CSS classes\n */\n getColumnSizeClasses(field) {\n // JSON objects and nested DataViews always use full width for better display\n if (field.type === 'array' || field.type === 'object' || field.type === 'dataview') {\n return 'col-12';\n }\n\n const colSize = field.columns || field.colSize || field.cols || Math.floor(12 / this.dataViewOptions.columns);\n\n if (this.dataViewOptions.responsive) {\n // Responsive breakpoints: 1 column on small, configured on larger screens\n return `col-12 col-md-${colSize}`;\n }\n\n return `col-${colSize}`;\n }\n\n /**\n * Build HTML for all data items\n * @returns {string} Items HTML\n */\n buildItemsHTML() {\n return this.fields\n .map(field => this.buildItemHTML(field))\n .filter(Boolean) // Remove empty items\n .join('');\n }\n\n /**\n * Build HTML for a single data item\n * @param {object} field - Field definition\n * @returns {string} Item HTML\n */\n buildItemHTML(field) {\n const value = this.getFieldValue(field);\n\n // Skip fields with no value if showEmptyValues is false\n if (value === null && !this.dataViewOptions.showEmptyValues) {\n return '';\n }\n\n const label = field.label || this.formatLabel(field.name);\n const colClasses = this.getColumnClasses(field);\n\n return `\n <div class=\"${colClasses}\">\n <div class=\"${this.dataViewOptions.itemClass} ${field.className}\" data-field=\"${field.name}\">\n ${this.buildLabelHTML(label, field)}\n ${this.buildValueHTML(value, field)}\n </div>\n </div>\n `;\n }\n\n /**\n * Build label HTML\n * @param {string} label - Label text\n * @param {object} field - Field definition\n * @returns {string} Label HTML\n */\n buildLabelHTML(label, field) {\n const labelClass = field.labelClass || this.dataViewOptions.labelClass;\n return `<div class=\"${labelClass}\">${this.escapeHtml(label)}:</div>`;\n }\n\n /**\n * Build value HTML with type-specific formatting\n * @param {*} value - Field value\n * @param {object} field - Field definition\n * @returns {string} Value HTML\n */\n buildValueHTML(value, field) {\n const valueClass = field.valueClass || this.dataViewOptions.valueClass;\n const displayValue = this.formatDisplayValue(value, field);\n return `<div class=\"${valueClass}\">${displayValue}</div>`;\n }\n\n /**\n * Format value for display with enhanced type handling\n * @param {*} value - Formatted value from DataFormatter (or raw if no format)\n * @param {object} field - Field definition\n * @returns {string} Formatted display value with HTML markup\n */\n formatDisplayValue(value, field) {\n if (value === null || value === undefined) {\n return this.dataViewOptions.emptyValueText;\n }\n\n // If a template was used, the value is already the final HTML. Return it directly.\n if (field.template) {\n return String(value);\n }\n\n // If a custom format is specified, trust the DataFormatter output.\n // Support both 'format' and 'formatter' for consistency with TableView\n const formatString = field.format || field.formatter;\n if (formatString) {\n // If a formatter is explicitly specified, render its output as HTML\n // The DataFormatter is responsible for proper escaping when needed\n return String(value);\n }\n\n // No custom format - apply DataView's default type-specific HTML formatting\n // Get original raw value for special cases\n const rawValue = this.getData()[field.name];\n\n // Handle types that need special HTML presentation (only when no custom format)\n switch (field.type) {\n case 'boolean':\n // Use standard boolean badges (no custom format was applied)\n return rawValue ?\n '<span class=\"badge bg-success\">Yes</span>' :\n '<span class=\"badge bg-secondary\">No</span>';\n\n case 'email':\n // Create clickable email links (no custom format was applied)\n const emailStr = String(value);\n return `<a href=\"mailto:${this.escapeHtml(emailStr)}\" class=\"text-decoration-none\">${this.escapeHtml(emailStr)}</a>`;\n\n case 'url':\n // Create clickable URL links (no custom format was applied)\n const urlStr = String(value);\n return `<a href=\"${this.escapeHtml(urlStr)}\" target=\"_blank\" rel=\"noopener\" class=\"text-decoration-none\">${this.escapeHtml(urlStr)} <i class=\"bi bi-box-arrow-up-right\"></i></a>`;\n\n case 'array':\n case 'object':\n // Display as JSON with special HTML formatting (no custom format was applied)\n return this.formatAsJson(rawValue);\n\n case 'dataview':\n // Create nested DataView for complex objects\n return this.formatAsDataView(rawValue, field);\n\n case 'phone':\n // Create tel: links for phone numbers (no custom format was applied)\n const phoneStr = String(value);\n const telHref = phoneStr.replace(/[^\\d\\+]/g, ''); // Clean for tel: link\n return `<a href=\"tel:${telHref}\" class=\"text-decoration-none\">${this.escapeHtml(phoneStr)}</a>`;\n\n default:\n // For all other types with no custom format, just escape and return\n return this.escapeHtml(String(value));\n }\n }\n\n /**\n * Format object/array values as styled JSON\n * @param {*} value - Object or array value\n * @returns {string} Formatted JSON HTML\n */\n formatAsJson(value) {\n try {\n const jsonString = JSON.stringify(value, null, 2);\n const escapedJson = this.escapeHtml(jsonString);\n const lines = jsonString.split('\\n').length;\n const isLarge = lines > 10 || jsonString.length > 500;\n const uniqueId = `json-${Math.random().toString(36).substr(2, 9)}`;\n\n // Create collapsible JSON display for large objects\n if (isLarge) {\n const preview = JSON.stringify(value).substring(0, 100) + (JSON.stringify(value).length > 100 ? '...' : '');\n const escapedPreview = this.escapeHtml(preview);\n\n return `\n <div class=\"json-container\">\n <div class=\"d-flex align-items-center justify-content-between mb-1\">\n <small class=\"text-muted\">${Array.isArray(value) ? 'Array' : 'Object'} (${lines} lines)</small>\n <div class=\"btn-group btn-group-sm\" role=\"group\">\n <button type=\"button\" class=\"btn btn-outline-secondary btn-sm json-toggle\" data-bs-toggle=\"collapse\" data-bs-target=\"#${uniqueId}\" aria-expanded=\"false\">\n <i class=\"bi bi-eye\"></i> Show\n </button>\n <button type=\"button\" class=\"btn btn-outline-secondary btn-sm json-copy\" data-json='${this.escapeHtml(jsonString)}' title=\"Copy JSON\">\n <i class=\"bi bi-clipboard\"></i>\n </button>\n </div>\n </div>\n <div class=\"json-preview bg-light p-2 rounded small border\" style=\"font-family: 'Courier New', monospace;\">\n <code class=\"text-muted\">${escapedPreview}</code>\n </div>\n <div class=\"collapse mt-2\" id=\"${uniqueId}\">\n <pre class=\"json-display p-3 rounded small mb-0\" style=\"max-height: 400px; overflow-y: auto; white-space: pre-wrap; font-family: 'Courier New', monospace;\"><code>${this.syntaxHighlightJson(escapedJson)}</code></pre>\n </div>\n </div>\n `;\n } else {\n // Small objects - show directly with copy button\n return `\n <div class=\"json-container\">\n <div class=\"d-flex align-items-center justify-content-between mb-1\">\n <small class=\"text-muted\">${Array.isArray(value) ? 'Array' : 'Object'}</small>\n <button type=\"button\" class=\"btn btn-outline-secondary btn-sm json-copy\" data-json='${this.escapeHtml(jsonString)}' title=\"Copy JSON\">\n <i class=\"bi bi-clipboard\"></i>\n </button>\n </div>\n <pre class=\"json-display bg-light p-2 rounded small mb-0 border\" style=\"white-space: pre-wrap; font-family: 'Courier New', monospace;\"><code>${this.syntaxHighlightJson(escapedJson)}</code></pre>\n </div>\n `;\n }\n } catch (error) {\n // Fallback for objects that can't be stringified\n return `<span class=\"text-muted fst-italic\">[Object: ${typeof value}] - Cannot display as JSON</span>`;\n }\n }\n\n /**\n * Apply basic syntax highlighting to JSON\n * @param {string} json - Escaped JSON string\n * @returns {string} JSON with basic syntax highlighting\n */\n syntaxHighlightJson(json) {\n return json\n .replace(/(\"([^\"\\\\]|\\\\.)*\")\\s*:/g, '<span style=\"color: #0969da;\">$1</span>:') // Keys (blue)\n .replace(/:\\s*(\"([^\"\\\\]|\\\\.)*\")/g, ': <span style=\"color: #0a3069;\">$1</span>') // String values (dark blue)\n .replace(/:\\s*(true|false)/g, ': <span style=\"color: #8250df;\">$1</span>') // Booleans (purple)\n .replace(/:\\s*(null)/g, ': <span style=\"color: #656d76;\">$1</span>') // Null (gray)\n .replace(/:\\s*(-?\\d+\\.?\\d*)/g, ': <span style=\"color: #0550ae;\">$1</span>'); // Numbers (blue)\n }\n\n /**\n * Bind events including JSON interaction handlers\n */\n bindEvents() {\n super.bindEvents();\n\n if (!this.element) return;\n\n // Add click handler for field interactions\n this.element.addEventListener('click', (e) => {\n const fieldElement = e.target.closest('[data-field]');\n if (fieldElement) {\n const fieldName = fieldElement.dataset.field;\n const field = this.fields.find(f => f.name === fieldName);\n this.emit('field:click', { field, fieldName, element: fieldElement, event: e });\n }\n\n // Handle JSON copy button clicks\n if (e.target.closest('.json-copy')) {\n e.preventDefault();\n e.stopPropagation();\n this.handleJsonCopy(e.target.closest('.json-copy'));\n }\n\n // Handle JSON toggle button clicks\n if (e.target.closest('.json-toggle')) {\n this.handleJsonToggle(e.target.closest('.json-toggle'));\n }\n });\n }\n\n /**\n * Handle copying JSON to clipboard\n * @param {HTMLElement} button - Copy button element\n */\n handleJsonCopy(button) {\n const jsonData = button.getAttribute('data-json');\n if (!jsonData) return;\n\n try {\n // Use modern clipboard API if available\n if (navigator.clipboard && window.isSecureContext) {\n navigator.clipboard.writeText(jsonData).then(() => {\n this.showCopyFeedback(button);\n });\n } else {\n // Fallback for older browsers\n const textarea = document.createElement('textarea');\n textarea.value = jsonData;\n document.body.appendChild(textarea);\n textarea.select();\n document.execCommand('copy');\n document.body.removeChild(textarea);\n this.showCopyFeedback(button);\n }\n } catch (error) {\n console.warn('Failed to copy JSON:', error);\n }\n }\n\n /**\n * Handle JSON toggle button state\n * @param {HTMLElement} button - Toggle button element\n */\n handleJsonToggle(button) {\n const icon = button.querySelector('i');\n const isExpanded = button.getAttribute('aria-expanded') === 'true';\n\n // Update button text and icon\n setTimeout(() => {\n if (isExpanded) {\n icon.className = 'bi bi-eye-slash';\n button.innerHTML = '<i class=\"bi bi-eye-slash\"></i> Hide';\n } else {\n icon.className = 'bi bi-eye';\n button.innerHTML = '<i class=\"bi bi-eye\"></i> Show';\n }\n }, 10);\n }\n\n /**\n * Show visual feedback for successful copy\n * @param {HTMLElement} button - Copy button element\n */\n showCopyFeedback(button) {\n const originalIcon = button.querySelector('i').className;\n const icon = button.querySelector('i');\n\n // Show success state\n icon.className = 'bi bi-check text-success';\n button.classList.add('btn-success');\n button.classList.remove('btn-outline-secondary');\n\n // Reset after 1 second\n setTimeout(() => {\n icon.className = originalIcon;\n button.classList.remove('btn-success');\n button.classList.add('btn-outline-secondary');\n }, 1000);\n }\n\n /**\n * Format complex objects as nested DataView\n * @param {object} value - Object value to display as DataView\n * @param {object} field - Field definition\n * @returns {string} Formatted DataView HTML\n */\n formatAsDataView(value, field) {\n if (!value || typeof value !== 'object') {\n return `<span class=\"text-muted fst-italic\">No data available</span>`;\n }\n\n try {\n // Create nested DataView instance\n const nestedView = new (this.constructor)({\n data: value,\n columns: field.dataViewColumns || 2,\n showEmptyValues: field.showEmptyValues ?? true,\n emptyValueText: field.emptyValueText || 'Not set',\n // Pass any other dataView-specific options from field config\n ...(field.dataViewOptions || {})\n });\n\n nestedView.onInit();\n nestedView.generateFieldsFromData();\n // Generate the nested DataView HTML\n const nestedHtml = nestedView.buildItemsHTML();\n\n // Wrap in a styled container with optional label\n // const labelHtml = field.label ?\n // `<h6 class=\"fw-semibold text-muted mb-3 border-bottom pb-2\">${this.escapeHtml(field.label)}</h6>` :\n // '';\n\n return `\n <div class=\"nested-dataview border rounded p-3 bg-light\">\n <div class=\"${nestedView.dataViewOptions.rowClass}\">\n ${nestedHtml}\n </div>\n </div>\n `;\n } catch (error) {\n console.error('Error creating nested DataView:', error);\n return `<span class=\"text-danger\">Error displaying nested data</span>`;\n }\n }\n\n /**\n * Update the data and re-render\n * @param {object} newData - New data object\n * @returns {Promise<DataView>} Promise resolving to this instance\n */\n async updateData(newData) {\n this.data = newData;\n\n // If model is provided, update it instead\n if (this.model && typeof this.model.set === 'function') {\n this.model.set(newData);\n }\n\n // Clear fields to trigger regeneration on next render\n if (this.fields.length > 0 && !this.options.fields) {\n this.fields = [];\n }\n\n await this.render();\n this.emit('data:updated', { data: newData });\n return this;\n }\n\n /**\n * Update field configuration and re-render\n * @param {array} newFields - New field configuration\n * @returns {Promise<DataView>} Promise resolving to this instance\n */\n async updateFields(newFields) {\n this.fields = newFields;\n await this.render();\n this.emit('fields:updated', { fields: newFields });\n return this;\n }\n\n /**\n * Update configuration and re-render\n * @param {object} newOptions - New configuration options\n * @returns {Promise<DataView>} Promise resolving to this instance\n */\n async updateConfig(newOptions) {\n this.dataViewOptions = { ...this.dataViewOptions, ...newOptions };\n await this.render();\n this.emit('config:updated', { options: this.dataViewOptions });\n return this;\n }\n\n /**\n * Refresh data from model if available\n * @returns {Promise<DataView>} Promise resolving to this instance\n */\n async refresh() {\n if (this.model && typeof this.model.fetch === 'function') {\n try {\n await this.model.fetch();\n this.emit('data:refreshed', { model: this.model });\n } catch (error) {\n this.emit('error', { error, message: 'Failed to refresh data' });\n throw error;\n }\n }\n return this;\n }\n\n /**\n * Get current data\n * @returns {object} Current data object\n */\n getCurrentData() {\n return this.getData();\n }\n\n /**\n * Get field definition by name\n * @param {string} name - Field name\n * @returns {object|null} Field definition\n */\n getField(name) {\n return this.fields.find(field => field.name === name) || null;\n }\n\n /**\n * Set custom format for a specific field\n * @param {string} fieldName - Name of the field\n * @param {string} format - Pipe format string (e.g., \"currency|uppercase\")\n * @returns {DataView} This instance for chaining\n */\n setFieldFormat(fieldName, format) {\n const field = this.getField(fieldName);\n if (field) {\n field.format = format;\n field.formatter = format; // Keep both in sync\n } else {\n // Create new field if it doesn't exist\n this.fields.push({\n name: fieldName,\n label: this.formatLabel(fieldName),\n type: this.inferFieldType(this.getData()[fieldName], fieldName),\n format: format,\n formatter: format // Keep both in sync\n });\n }\n return this;\n }\n\n /**\n * Add additional formatter to existing field format pipe chain\n * @param {string} fieldName - Name of the field\n * @param {string} formatter - Formatter to add (e.g., \"uppercase\", \"truncate(50)\")\n * @returns {DataView} This instance for chaining\n */\n addFormatPipe(fieldName, formatter) {\n const field = this.getField(fieldName);\n if (field) {\n if (field.format) {\n field.format += `|${formatter}`;\n field.formatter = field.format; // Keep both in sync\n } else {\n field.format = formatter;\n field.formatter = formatter; // Keep both in sync\n }\n }\n return this;\n }\n\n /**\n * Clear custom format for a field (revert to auto-inferred format)\n * @param {string} fieldName - Name of the field\n * @returns {DataView} This instance for chaining\n */\n clearFieldFormat(fieldName) {\n const field = this.getField(fieldName);\n if (field) {\n const data = this.getData();\n const inferred = this.inferFormatter(data[fieldName], fieldName, field.type);\n field.format = inferred;\n field.formatter = inferred; // Keep both in sync\n }\n return this;\n }\n\n /**\n * Get formatted value for a specific field without rendering\n * @param {string} fieldName - Name of the field\n * @param {*} value - Optional value to format (uses current data if not provided)\n * @returns {*} Formatted value\n */\n getFormattedValue(fieldName, value = null) {\n const field = this.getField(fieldName);\n if (!field) return null;\n\n const targetValue = value !== null ? value : this.getData()[fieldName];\n\n // Support both 'format' and 'formatter' for consistency with TableView\n const formatString = field.format || field.formatter;\n if (formatString && targetValue != null) {\n return dataFormatter.pipe(targetValue, formatString);\n }\n\n return targetValue;\n }\n\n /**\n * Set multiple field formats at once\n * @param {object} formats - Object mapping field names to format strings\n * @returns {DataView} This instance for chaining\n */\n setFieldFormats(formats) {\n Object.entries(formats).forEach(([fieldName, format]) => {\n this.setFieldFormat(fieldName, format);\n });\n return this;\n }\n\n /**\n * Get all current field formats as an object\n * @returns {object} Object mapping field names to their current formats\n */\n getFieldFormats() {\n const formats = {};\n this.fields.forEach(field => {\n const formatString = field.format || field.formatter;\n if (formatString) {\n formats[field.name] = formatString;\n }\n });\n return formats;\n }\n\n /**\n * Set up model event listeners if model is provided\n */\n onInit() {\n super.onInit();\n\n // Listen for model changes\n if (this.model && typeof this.model.on === 'function') {\n this.model.on('change', () => {\n this.render();\n });\n }\n }\n\n /**\n * Static factory method\n * @param {object} options - DataView options\n * @returns {DataView} New DataView instance\n */\n static create(options = {}) {\n return new DataView(options);\n }\n}\n\nexport default DataView;\n"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"Dialog-BiVgKzSK.js","sources":["../../src/core/views/feedback/Dialog.js"],"sourcesContent":["/**\n * Dialog - Complete Bootstrap 5 Modal component for MOJO framework\n * Supports all Bootstrap 5 modal features including sizes, fullscreen, scrollable, etc.\n * Can accept View instances as body content\n */\n\nimport View from '@core/View.js';\n\n\nclass Dialog extends View {\n static _openDialogs = [];\n static _baseZIndex = {\n backdrop: 1050,\n modal: 1055\n };\n\n /**\n * Check if there's a fullscreen table and return appropriate z-index\n */\n static getFullscreenAwareZIndex() {\n const fullscreenTable = document.querySelector('.table-fullscreen');\n if (fullscreenTable) {\n // Fullscreen table uses z-index 9999, so modals should be much higher\n return {\n backdrop: 10040,\n modal: 10050\n };\n }\n return this._baseZIndex;\n }\n\n static _busyIndicator = null;\n static _busyCounter = 0;\n static _busyTimeout = null;\n\n /**\n * Fix all backdrop stacking - ensures proper layering of all open modals\n */\n static fixAllBackdropStacking() {\n const backdrops = document.querySelectorAll('.modal-backdrop');\n const openDialogs = Dialog._openDialogs;\n \n if (backdrops.length === 0 || openDialogs.length === 0) return;\n \n // Sort dialogs by z-index to get correct stacking order\n const sortedDialogs = [...openDialogs].sort((a, b) => \n (a._dialogZIndex || 0) - (b._dialogZIndex || 0)\n );\n \n // Set backdrop z-indices to create proper stacking\n // Each backdrop should cover all previous modals but stay below its own modal\n backdrops.forEach((backdrop, index) => {\n if (index < sortedDialogs.length) {\n const dialog = sortedDialogs[index];\n const backdropZIndex = dialog._dialogZIndex - 5;\n backdrop.style.zIndex = backdropZIndex;\n \n // Move backdrop to correct container\n const fullscreenElement = document.querySelector('.table-fullscreen');\n const targetContainer = fullscreenElement || document.body;\n \n if (backdrop.parentNode !== targetContainer) {\n targetContainer.appendChild(backdrop);\n }\n }\n });\n }\n\n /**\n * Update backdrop stacking for all open dialogs\n */\n static updateAllBackdropStacking() {\n Dialog.fixAllBackdropStacking();\n }\n\n /**\n * Shows a full-screen busy indicator.\n * Manages a counter for nested calls, only showing one indicator.\n * @param {object} options - Options { timeout, message }\n */\n static showBusy(options = {}) {\n const { timeout = 30000, message = 'Loading...' } = options;\n\n this._busyCounter++;\n\n if (this._busyCounter === 1) {\n if (this._busyTimeout) {\n clearTimeout(this._busyTimeout);\n }\n\n if (!this._busyIndicator) {\n const zIndexBase = this.getFullscreenAwareZIndex();\n const busyZIndex = zIndexBase.modal + 1000; // Higher than any modal\n \n this._busyIndicator = document.createElement('div');\n this._busyIndicator.className = 'mojo-busy-indicator';\n this._busyIndicator.innerHTML = `\n <div class=\"mojo-busy-spinner\">\n <div class=\"spinner-border text-light\" role=\"status\">\n <span class=\"visually-hidden\">Loading...</span>\n </div>\n <p class=\"mojo-busy-message mt-3 text-light\">${message}</p>\n </div>\n <style>\n .mojo-busy-indicator {\n position: fixed; top: 0; left: 0; width: 100vw; height: 100vh;\n background-color: rgba(0, 0, 0, 0.5); z-index: ${busyZIndex};\n display: flex; align-items: center; justify-content: center;\n opacity: 0; transition: opacity 0.15s linear;\n }\n .mojo-busy-indicator.show { opacity: 1; }\n .mojo-busy-spinner .spinner-border { width: 3rem; height: 3rem; }\n </style>\n `;\n document.body.appendChild(this._busyIndicator);\n }\n\n const msgElement = this._busyIndicator.querySelector('.mojo-busy-message');\n if (msgElement) msgElement.textContent = message;\n\n setTimeout(() => this._busyIndicator.classList.add('show'), 10);\n\n this._busyTimeout = setTimeout(() => {\n console.error('Busy indicator timed out.');\n this.hideBusy(true); // Force hide\n this.alert({\n title: 'Operation Timed Out',\n message: 'The operation took too long. Please check your connection and try again.',\n type: 'danger'\n });\n }, timeout);\n }\n }\n\n /**\n * Hides the full-screen busy indicator.\n * Decrements the counter and only hides when the counter reaches zero.\n * @param {boolean} force - If true, forces the indicator to hide immediately.\n */\n static hideBusy(force = false) {\n if (force) {\n this._busyCounter = 0;\n } else {\n this._busyCounter--;\n }\n\n if (this._busyCounter <= 0) {\n this._busyCounter = 0;\n if (this._busyTimeout) {\n clearTimeout(this._busyTimeout);\n this._busyTimeout = null;\n }\n\n if (this._busyIndicator) {\n this._busyIndicator.classList.remove('show');\n setTimeout(() => {\n if (this._busyIndicator && this._busyCounter === 0) {\n this._busyIndicator.remove();\n this._busyIndicator = null;\n }\n }, 150);\n }\n }\n }\n\n constructor(options = {}) {\n // Generate unique ID if not provided\n const modalId = options.id || `modal-${Date.now()}`;\n\n super({\n ...options,\n id: modalId, // Pass the ID to parent constructor\n tagName: 'div',\n className: `modal ${options.fade !== false ? 'fade' : ''} ${options.className || ''}`,\n attributes: {\n tabindex: '-1',\n 'aria-hidden': 'true',\n 'aria-labelledby': options.labelledBy || `${modalId}-label`,\n 'aria-describedby': options.describedBy || null,\n ...options.attributes\n }\n });\n\n // Store modal ID for internal use\n this.modalId = modalId;\n\n // Dialog configuration\n this.title = options.title || '';\n this.titleId = `${this.modalId}-label`;\n\n // Size options: sm, md (default), lg, xl, fullscreen, auto\n // Or responsive fullscreen: fullscreen-sm-down, fullscreen-md-down, etc.\n // 'auto' enables dynamic sizing based on content dimensions\n this.size = options.size || '';\n\n // Layout options\n this.centered = options.centered !== undefined ? options.centered : false;\n this.scrollable = options.scrollable !== undefined ? options.scrollable : false;\n // Auto-sizing: dynamically size modal based on content dimensions\n // Can be enabled with autoSize: true or size: 'auto'\n // Waits for modal animation to complete before measuring content\n this.autoSize = options.autoSize || options.size === 'auto'; // Auto-size modal based on content dimensions\n\n // Bootstrap modal options\n this.backdrop = options.backdrop !== undefined ? options.backdrop : true; // true, false, 'static'\n this.keyboard = options.keyboard !== undefined ? options.keyboard : true;\n this.focus = options.focus !== undefined ? options.focus : true;\n\n // Content\n this.header = options.header !== undefined ? options.header : true;\n this.headerContent = options.headerContent || null;\n this.closeButton = options.closeButton !== undefined ? options.closeButton : true;\n this.contextMenu = options.contextMenu || null;\n\n // Enhanced body handling - support View, Promise<View>, or function returning View\n this.body = options.body || options.content || '';\n this.bodyView = null; // Will hold View instance if body is a View\n this.bodyClass = options.bodyClass || '';\n this.noBodyPadding = options.noBodyPadding || false; // Remove default modal-body padding\n\n // Auto-sizing constraints - only used when autoSize is enabled\n this.minWidth = options.minWidth || 300; // Minimum modal width (px)\n this.minHeight = options.minHeight || 200; // Minimum modal height (px)\n this.maxWidthPercent = options.maxWidthPercent || 0.9; // Max width as % of viewport\n this.maxHeightPercent = options.maxHeightPercent || 0.8; // Max height as % of viewport\n\n // Handle different body types\n this._processBodyContent(this.body);\n\n this.footer = options.footer || null;\n this.footerView = null; // Will hold View instance if footer is a View\n this.footerClass = options.footerClass || '';\n\n // Handle different footer types\n this._processFooterContent(this.footer);\n\n // Buttons configuration\n this.buttons = options.buttons || null;\n\n // Callbacks for Bootstrap events\n this.onShow = options.onShow || null; // show.bs.modal\n this.onShown = options.onShown || null; // shown.bs.modal\n this.onHide = options.onHide || null; // hide.bs.modal\n this.onHidden = options.onHidden || null; // hidden.bs.modal\n this.onHidePrevented = options.onHidePrevented || null; // hidePrevented.bs.modal\n\n // Auto show on creation\n this.autoShow = options.autoShow !== undefined ? options.autoShow : false;\n\n // Bootstrap modal instance\n this.modal = null;\n\n // Related target (button that triggered the modal)\n this.relatedTarget = options.relatedTarget || null;\n }\n\n /**\n * Process body content to detect and handle View instances\n */\n _processBodyContent(body) {\n if (body && body.render) {\n this.bodyView = body;\n this.body = ''; // Clear string body\n this.addChild(this.bodyView); // Add as child for proper lifecycle\n } else if (typeof body === 'function') {\n // Support lazy View creation\n try {\n const result = body();\n if (result instanceof View) {\n this.bodyView = result;\n this.body = '';\n this.addChild(this.bodyView);\n } else if (result instanceof Promise) {\n // Mark for async processing\n this.bodyPromise = result;\n this.body = '<div class=\"text-center\"><div class=\"spinner-border spinner-border-sm\"></div></div>';\n } else {\n this.body = result;\n }\n } catch (error) {\n console.error('Error processing body function:', error);\n this.body = body;\n }\n } else {\n this.body = body;\n }\n }\n\n /**\n * Process footer content to detect and handle View instances\n */\n _processFooterContent(footer) {\n if (footer instanceof View) {\n this.footerView = footer;\n this.footer = null;\n this.addChild(this.footerView);\n } else if (typeof footer === 'function') {\n // Support lazy View creation\n try {\n const result = footer();\n if (result instanceof View) {\n this.footerView = result;\n this.footer = null;\n this.addChild(this.footerView);\n } else if (result instanceof Promise) {\n // Mark for async processing\n this.footerPromise = result;\n this.footer = '<div class=\"text-center\"><div class=\"spinner-border spinner-border-sm\"></div></div>';\n } else {\n this.footer = result;\n }\n } catch (error) {\n console.error('Error processing footer function:', error);\n this.footer = footer;\n }\n } else {\n this.footer = footer;\n }\n }\n\n /**\n * Get dialog template with all Bootstrap 5 features\n */\n async getTemplate() {\n // Build dialog classes\n const dialogClasses = ['modal-dialog'];\n\n // Add size class (excluding 'auto' which uses default sizing)\n if (this.size && this.size !== 'auto') {\n if (this.size.startsWith('fullscreen')) {\n // Fullscreen or responsive fullscreen\n dialogClasses.push(`modal-${this.size}`);\n } else if (['sm', 'lg', 'xl'].includes(this.size)) {\n // Standard sizes\n dialogClasses.push(`modal-${this.size}`);\n }\n }\n\n // Add centered class\n if (this.centered) {\n dialogClasses.push('modal-dialog-centered');\n }\n\n // Add scrollable class\n if (this.scrollable) {\n dialogClasses.push('modal-dialog-scrollable');\n }\n\n return `\n <div class=\"${dialogClasses.join(' ')}\">\n <div class=\"modal-content\">\n ${await this.buildHeader()}\n ${await this.buildBody()}\n ${await this.buildFooter()}\n </div>\n </div>\n `;\n }\n\n /**\n * Build modal header\n */\n async buildHeader() {\n if (!this.header) {\n return '';\n }\n\n if (this.headerContent) {\n return `<div class=\"modal-header\">${this.headerContent}</div>`;\n }\n\n // Build context menu or close button\n let headerActions = '';\n if (this.contextMenu && this.contextMenu.items && this.contextMenu.items.length > 0) {\n headerActions = await this.buildContextMenu();\n } else if (this.closeButton) {\n headerActions = '<button type=\"button\" class=\"btn-close\" data-bs-dismiss=\"modal\" aria-label=\"Close\"></button>';\n }\n\n return `\n <div class=\"modal-header\">\n ${this.title ? `<h5 class=\"modal-title\" id=\"${this.titleId}\">${this.title}</h5>` : ''}\n ${headerActions}\n </div>\n `;\n }\n\n async buildContextMenu() {\n const menuItems = await this.filterContextMenuItems();\n if (menuItems.length === 0) {\n // If no items pass permission checks, show regular close button\n return this.closeButton ? '<button type=\"button\" class=\"btn-close\" data-bs-dismiss=\"modal\" aria-label=\"Close\"></button>' : '';\n }\n\n const triggerIcon = this.contextMenu.icon || 'bi-three-dots-vertical';\n const buttonClass = this.contextMenu.buttonClass || 'btn btn-link p-1 mojo-modal-context-menu-btn';\n\n const menuItemsHtml = menuItems.map(item => {\n if (item.type === 'divider') {\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\n if (item.href) {\n return `<li><a class=\"dropdown-item\" href=\"${item.href}\"${item.target ? ` target=\"${item.target}\"` : ''}>${icon}${label}</a></li>`;\n } else if (item.action) {\n const dataAttrs = Object.keys(item)\n .filter(key => key.startsWith('data-'))\n .map(key => `${key}=\"${item[key]}\"`)\n .join(' ');\n return `<li><a class=\"dropdown-item\" data-action=\"${item.action}\" ${dataAttrs}>${icon}${label}</a></li>`;\n }\n\n return '';\n }).join('');\n\n return `\n <div class=\"dropdown\">\n <button class=\"${buttonClass}\" type=\"button\" data-bs-toggle=\"dropdown\" aria-expanded=\"false\">\n <i class=\"${triggerIcon}\"></i>\n </button>\n <ul class=\"dropdown-menu dropdown-menu-end\">\n ${menuItemsHtml}\n </ul>\n </div>\n `;\n }\n\n async filterContextMenuItems() {\n if (!this.contextMenu || !this.contextMenu.items) {\n return [];\n }\n\n const filteredItems = [];\n\n for (const item of this.contextMenu.items) {\n // Always include dividers\n if (item.type === 'divider') {\n filteredItems.push(item);\n continue;\n }\n\n // Check permissions if specified\n if (item.permissions) {\n try {\n const app = this.getApp?.();\n let user = null;\n\n if (app) {\n user = app.activeUser || app.getState?.('activeUser');\n }\n\n // Also check window.getApp as fallback for mock systems\n if (!user && typeof window !== 'undefined' && window.getApp) {\n try {\n const globalApp = window.getApp();\n user = globalApp?.activeUser;\n } catch (e) {\n // Ignore global app errors\n }\n }\n\n if (user && user.hasPermission) {\n if (!user.hasPermission(item.permissions)) {\n continue; // Skip this item\n }\n } else {\n // If no permission system available, skip items with permission requirements\n continue;\n }\n } catch (error) {\n console.warn('Error checking permissions for context menu item:', error);\n continue;\n }\n }\n\n filteredItems.push(item);\n }\n\n return filteredItems;\n }\n\n /**\n * Build modal body\n */\n async buildBody() {\n // If we have a View instance as body\n if (this.bodyView) {\n this.bodyView.replaceById = true;\n const bodyClass = this.noBodyPadding ? `modal-body p-0 ${this.bodyClass}` : `modal-body ${this.bodyClass}`;\n return `<div class=\"${bodyClass}\" data-view-container=\"body\">\n <!-- View will be mounted here -->\n <div id=\"${this.bodyView.id}\"></div>\n </div>`;\n }\n\n // Regular string/HTML body\n if (!this.body && this.body !== '') {\n return '';\n }\n\n const bodyClass = this.noBodyPadding ? `modal-body p-0 ${this.bodyClass}` : `modal-body ${this.bodyClass}`;\n return `\n <div class=\"${bodyClass}\">\n ${this.body}\n </div>\n `;\n }\n\n /**\n * Build modal footer\n */\n async buildFooter() {\n // If we have a View instance as footer\n if (this.footerView) {\n return `<div class=\"modal-footer ${this.footerClass}\" data-view-container=\"footer\"></div>`;\n }\n\n // Custom footer content\n if (this.footer !== null && typeof this.footer === 'string') {\n return `<div class=\"modal-footer ${this.footerClass}\">${this.footer}</div>`;\n }\n\n // Build footer from buttons\n if (this.buttons && this.buttons.length > 0) {\n const buttonsHtml = this.buttons.map(btn => {\n const dismissAttr = btn.dismiss ? 'data-bs-dismiss=\"modal\"' : '';\n const actionAttr = btn.action ? `data-action=\"${btn.action}\"` : '';\n const idAttr = btn.id ? `id=\"${btn.id}\"` : '';\n const disabledAttr = btn.disabled ? 'disabled' : '';\n\n return `\n <button type=\"${btn.type || 'button'}\"\n class=\"btn ${btn.class || 'btn-secondary'}\"\n ${idAttr}\n ${dismissAttr}\n ${actionAttr}\n ${disabledAttr}>\n ${btn.icon ? `<i class=\"bi ${btn.icon} me-1\"></i>` : ''}\n ${btn.text || 'Button'}\n </button>\n `;\n }).join('');\n\n return `<div class=\"modal-footer ${this.footerClass}\">${buttonsHtml}</div>`;\n }\n\n // No footer\n return '';\n }\n\n\n /**\n * Override mount to not require a container for dialogs\n * Dialogs are appended to body or fullscreen element\n */\n async mount(_container = null) {\n if (this.mounted || this.destroyed) {\n return;\n }\n\n // For dialogs, we only need the element, not a container\n if (!this.element) {\n throw new Error('Cannot mount dialog without element');\n }\n\n // Call lifecycle hooks\n await this.onBeforeMount();\n\n // Append to fullscreen element if it exists, otherwise to body\n const fullscreenElement = document.querySelector('.table-fullscreen');\n const targetContainer = fullscreenElement || document.body;\n targetContainer.appendChild(this.element);\n\n // Bind DOM events\n this.bindEvents();\n\n // Set mounted flag\n this.mounted = true;\n\n // Call after mount (this initializes Bootstrap modal)\n await this.onAfterMount();\n\n // Emit mounted event\n this.emit('mounted', { view: this });\n\n return this;\n }\n\n /**\n * After render - prepare for View instances and apply syntax highlighting\n */\n async onAfterRender() {\n await super.onAfterRender();\n\n // Apply Prism syntax highlighting if available and there are code blocks\n if (window.Prism && this.element) {\n const codeBlocks = this.element.querySelectorAll('pre code');\n if (codeBlocks.length > 0) {\n // Use Prism's highlightAllUnder to highlight code within this dialog\n window.Prism.highlightAllUnder(this.element);\n }\n }\n\n // Child views will be mounted in onAfterMount when element is in DOM\n\n // Apply auto-sizing after rendering if enabled\n if (this.autoSize) {\n this.setupAutoSizing();\n }\n }\n\n /**\n * After mount - initialize Bootstrap modal and mount child views\n */\n async onAfterMount() {\n await super.onAfterMount();\n\n if (typeof window !== 'undefined' && window.bootstrap && window.bootstrap.Modal) {\n // Set data attributes if needed\n if (this.backdrop === 'static') {\n this.element.setAttribute('data-bs-backdrop', 'static');\n }\n if (!this.keyboard) {\n this.element.setAttribute('data-bs-keyboard', 'false');\n }\n\n // Initialize Bootstrap modal with options\n this.modal = new window.bootstrap.Modal(this.element, {\n backdrop: this.backdrop,\n keyboard: this.keyboard,\n focus: this.focus\n });\n\n // Bind Bootstrap events\n this.bindBootstrapEvents();\n\n // Auto show if requested\n if (this.autoShow) {\n this.show(this.relatedTarget);\n }\n }\n }\n\n /**\n * Setup auto-sizing - wait for modal animation to complete\n */\n setupAutoSizing() {\n if (!this.element) return;\n\n // Listen for modal shown event to apply sizing after animation\n this.element.addEventListener('shown.bs.modal', () => {\n this.applyAutoSizing();\n }, { once: true });\n\n // Fallback: apply immediately if modal is already shown or no animation\n setTimeout(() => {\n if (this.isShown()) {\n this.applyAutoSizing();\n }\n }, 100);\n }\n\n /**\n * Apply auto-sizing based on content dimensions\n */\n applyAutoSizing() {\n if (!this.element) return;\n\n try {\n const modalDialog = this.element.querySelector('.modal-dialog');\n const modalContent = this.element.querySelector('.modal-content');\n const modalBody = this.element.querySelector('.modal-body');\n\n if (!modalDialog || !modalContent || !modalBody) {\n console.warn('Dialog auto-sizing: Required elements not found');\n return;\n }\n\n // Wait for child views to fully render\n if (this.bodyView && !this.bodyView.element) {\n setTimeout(() => this.applyAutoSizing(), 50);\n return;\n }\n\n // Store original styles for restoration\n const originalStyles = {\n dialogMaxWidth: modalDialog.style.maxWidth,\n dialogWidth: modalDialog.style.width,\n contentWidth: modalContent.style.width,\n contentMaxHeight: modalContent.style.maxHeight,\n bodyOverflow: modalBody.style.overflowY\n };\n\n // Temporarily remove size constraints to measure natural content size\n modalDialog.style.maxWidth = 'none';\n modalDialog.style.width = 'auto';\n modalContent.style.width = 'auto';\n modalContent.style.maxHeight = 'none';\n\n // Force layout recalculation\n modalContent.offsetHeight;\n\n // Measure content dimensions after forced layout\n const contentRect = modalContent.getBoundingClientRect();\n\n // Calculate viewport constraints with margins\n const viewportMargin = 40;\n const maxWidth = Math.min(\n window.innerWidth * this.maxWidthPercent,\n window.innerWidth - viewportMargin\n );\n const maxHeight = Math.min(\n window.innerHeight * this.maxHeightPercent,\n window.innerHeight - viewportMargin\n );\n\n // Calculate optimal dimensions with padding for content\n let optimalWidth = Math.max(this.minWidth, Math.ceil(contentRect.width + 20));\n let optimalHeight = Math.max(this.minHeight, Math.ceil(contentRect.height));\n\n // Apply viewport constraints\n optimalWidth = Math.min(optimalWidth, maxWidth);\n const heightExceedsMax = contentRect.height > maxHeight;\n\n // Apply the calculated size\n modalDialog.style.maxWidth = `${optimalWidth}px`;\n modalDialog.style.width = `${optimalWidth}px`;\n\n // Handle height overflow with scrolling\n if (heightExceedsMax) {\n modalContent.style.maxHeight = `${maxHeight}px`;\n modalBody.style.overflowY = 'auto';\n optimalHeight = maxHeight;\n }\n\n // Store the applied dimensions\n this.autoSizedWidth = optimalWidth;\n this.autoSizedHeight = optimalHeight;\n this._originalStyles = originalStyles;\n\n } catch (error) {\n console.error('Error in dialog auto-sizing:', error);\n // Fallback: ensure modal is still usable\n this.element.querySelector('.modal-dialog').style.maxWidth = '';\n }\n }\n\n /**\n * Reset auto-sizing and restore original modal dimensions\n */\n resetAutoSizing() {\n if (!this.autoSize || !this._originalStyles || !this.element) return;\n\n try {\n const modalDialog = this.element.querySelector('.modal-dialog');\n const modalContent = this.element.querySelector('.modal-content');\n const modalBody = this.element.querySelector('.modal-body');\n\n if (modalDialog && modalContent && modalBody) {\n // Restore original styles\n modalDialog.style.maxWidth = this._originalStyles.dialogMaxWidth || '';\n modalDialog.style.width = this._originalStyles.dialogWidth || '';\n modalContent.style.width = this._originalStyles.contentWidth || '';\n modalContent.style.maxHeight = this._originalStyles.contentMaxHeight || '';\n modalBody.style.overflowY = this._originalStyles.bodyOverflow || '';\n\n // Clear stored dimensions\n delete this.autoSizedWidth;\n delete this.autoSizedHeight;\n delete this._originalStyles;\n }\n } catch (error) {\n console.error('Error resetting dialog auto-sizing:', error);\n }\n }\n\n /**\n * Bind Bootstrap modal events\n */\n bindBootstrapEvents() {\n // show.bs.modal\n this.element.addEventListener('show.bs.modal', (e) => {\n // Manage stacking for multiple dialogs with fullscreen awareness\n const stackIndex = Dialog._openDialogs.length;\n const zIndexBase = Dialog.getFullscreenAwareZIndex();\n const newZIndex = zIndexBase.modal + (stackIndex * 20);\n this.element.style.zIndex = newZIndex;\n \n // Store z-index on this dialog for later reference\n this._dialogZIndex = newZIndex;\n this._backdropZIndex = newZIndex - 10; // Ensure backdrop covers previous modals\n \n Dialog._openDialogs.push(this);\n\n if (this.onShow) this.onShow(e);\n this.emit('show', {\n dialog: this,\n relatedTarget: e.relatedTarget\n });\n });\n\n // shown.bs.modal\n this.element.addEventListener('shown.bs.modal', (e) => {\n // Fix all backdrop stacking after Bootstrap has finished\n setTimeout(() => {\n Dialog.fixAllBackdropStacking();\n }, 50);\n \n if (this.onShown) this.onShown(e);\n this.emit('shown', {\n dialog: this,\n relatedTarget: e.relatedTarget\n });\n\n // Focus first input if exists\n if (this.focus) {\n const firstInput = this.element.querySelector('input:not([type=\"hidden\"]), textarea, select');\n if (firstInput) {\n firstInput.focus();\n }\n }\n });\n\n // hide.bs.modal\n this.element.addEventListener('hide.bs.modal', (e) => {\n // Blur any focused element inside the modal to prevent accessibility warning\n const focusedElement = this.element.querySelector(':focus');\n if (focusedElement) {\n focusedElement.blur();\n }\n\n if (this.onHide) {\n const result = this.onHide(e);\n if (result === false) {\n e.preventDefault();\n return;\n }\n }\n this.emit('hide', { dialog: this });\n });\n\n // hidden.bs.modal\n this.element.addEventListener('hidden.bs.modal', (e) => {\n // Manage stacking\n const index = Dialog._openDialogs.indexOf(this);\n if (index > -1) {\n Dialog._openDialogs.splice(index, 1);\n }\n\n // If there are still modals open, ensure body has modal-open class\n // and properly manage backdrop stacking\n if (Dialog._openDialogs.length > 0) {\n document.body.classList.add('modal-open');\n \n setTimeout(() => { // Let Bootstrap finish its hide animation\n Dialog.fixAllBackdropStacking();\n }, 50);\n }\n\n // Restore focus to the element that had it before modal opened\n if (this.previousFocus && document.body.contains(this.previousFocus)) {\n this.previousFocus.focus();\n }\n\n if (this.onHidden) this.onHidden(e);\n this.emit('hidden', { dialog: this });\n });\n\n // hidePrevented.bs.modal\n this.element.addEventListener('hidePrevented.bs.modal', (e) => {\n if (this.onHidePrevented) this.onHidePrevented(e);\n this.emit('hidePrevented', { dialog: this });\n });\n }\n\n\n\n /**\n * Show the dialog\n * @param {HTMLElement} relatedTarget - Optional element that triggered the modal\n */\n show(relatedTarget = null) {\n // Capture the currently focused element for later restoration\n this.previousFocus = document.activeElement;\n window.lastDialog = this;\n if (this.modal) {\n this.modal.show(relatedTarget);\n }\n }\n\n /**\n * Hide the dialog\n */\n hide() {\n // Blur any focused element inside the modal before hiding\n const focusedElement = this.element?.querySelector(':focus');\n if (focusedElement) {\n focusedElement.blur();\n }\n\n if (this.modal) {\n this.modal.hide();\n }\n }\n\n /**\n * Toggle the dialog\n * @param {HTMLElement} relatedTarget - Optional element that triggered the modal\n */\n toggle(relatedTarget = null) {\n if (this.modal) {\n this.modal.toggle(relatedTarget);\n }\n }\n\n /**\n * Destroy the dialog and clean up resources\n */\n async destroy() {\n // Hide modal if it's showing\n if (this.modal) {\n // Remove focus from any element inside the modal\n const focusedElement = this.element?.querySelector(':focus');\n if (focusedElement) {\n focusedElement.blur();\n }\n\n // Dispose of Bootstrap modal instance\n this.modal.dispose();\n this.modal = null;\n }\n\n // Restore previous focus if available\n if (this.previousFocus && document.body.contains(this.previousFocus)) {\n this.previousFocus.focus();\n this.previousFocus = null;\n }\n\n // Clean up auto-sizing\n if (this.autoSize) {\n this.resetAutoSizing();\n }\n\n // Call parent destroy\n await super.destroy();\n }\n\n /**\n * Handle dynamic height changes\n */\n handleUpdate() {\n if (this.modal) {\n this.modal.handleUpdate();\n }\n }\n\n /**\n * Update dialog content\n * @param {string|View} content - New content (string or View instance)\n */\n async setContent(content) {\n // Handle View instance\n if (content instanceof View) {\n // Clean up old view if exists\n if (this.bodyView) {\n await this.bodyView.destroy();\n this.removeChild(this.bodyView);\n }\n\n this.bodyView = content;\n this.body = '';\n this.addChild(this.bodyView);\n\n const bodyEl = this.element?.querySelector('.modal-body');\n if (bodyEl) {\n bodyEl.innerHTML = '';\n // Pass container to render - it will handle mounting internally\n await this.bodyView.render(bodyEl);\n }\n } else {\n // String content\n this.body = content;\n const bodyEl = this.element?.querySelector('.modal-body');\n if (bodyEl) {\n bodyEl.innerHTML = content;\n }\n }\n\n // Update modal position if needed\n this.handleUpdate();\n }\n\n /**\n * Update dialog title\n */\n setTitle(title) {\n this.title = title;\n const titleEl = this.element?.querySelector('.modal-title');\n if (titleEl) {\n titleEl.textContent = title;\n }\n }\n\n /**\n * Set loading state\n */\n setLoading(loading = true, message = 'Loading...') {\n const bodyEl = this.element?.querySelector('.modal-body');\n if (bodyEl) {\n if (loading) {\n bodyEl.innerHTML = `\n <div class=\"text-center py-4\">\n <div class=\"spinner-border text-primary mb-3\" role=\"status\">\n <span class=\"visually-hidden\">Loading...</span>\n </div>\n <p>${message}</p>\n </div>\n `;\n } else if (this.bodyView) {\n bodyEl.replaceChildren(this.bodyView.element);\n }\n }\n }\n\n /**\n * Clean up\n */\n async onBeforeDestroy() {\n // Clean up child views\n if (this.bodyView) {\n await this.bodyView.destroy();\n }\n if (this.footerView) {\n await this.footerView.destroy();\n }\n\n await super.onBeforeDestroy();\n\n if (this.modal) {\n this.modal.dispose();\n this.modal = null;\n }\n }\n\n /**\n * Static method to show code in a dialog\n */\n static async showCode(options = {}) {\n const dialog = new Dialog({\n title: options.title || 'Source Code',\n size: options.size || 'lg',\n scrollable: true,\n body: Dialog.formatCode(options.code, options.language),\n buttons: [\n {\n text: 'Copy to Clipboard',\n class: 'btn-primary',\n icon: 'bi-clipboard',\n action: 'copy'\n },\n {\n text: 'Close',\n class: 'btn-secondary',\n dismiss: true\n }\n ]\n });\n\n // Handle copy action\n dialog.on('action:copy', async () => {\n if (navigator.clipboard) {\n try {\n await navigator.clipboard.writeText(options.code);\n dialog.showCopySuccess();\n } catch (err) {\n console.error('Failed to copy:', err);\n }\n }\n });\n\n // Mount to fullscreen element if it exists, otherwise body\n const fullscreenElement = document.querySelector('.table-fullscreen');\n const targetContainer = fullscreenElement || document.body;\n await dialog.render(true, targetContainer);\n\n // Apply syntax highlighting after mounting\n if (window.Prism && dialog.element) {\n window.Prism.highlightAllUnder(dialog.element);\n }\n\n // Show the dialog\n dialog.show();\n\n // Clean up when hidden\n dialog.on('hidden', () => {\n dialog.destroy();\n dialog.element.remove();\n });\n\n return dialog;\n }\n\n /**\n * Format code for display with syntax highlighting support\n */\n static formatCode(code, language = 'javascript') {\n let highlightedCode;\n\n // Check if Prism.js is available and has the language\n if (window.Prism && window.Prism.languages[language]) {\n // Use Prism to highlight the code\n highlightedCode = window.Prism.highlight(code, window.Prism.languages[language], language);\n } else {\n // Fallback: just escape HTML\n highlightedCode = code\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#039;');\n }\n\n // Add Prism classes for styling even if highlighting wasn't applied\n const prismClass = window.Prism ? `language-${language}` : '';\n\n // Modern VS Code-like dark theme styling\n const codeStyles = `\n max-height: 60vh;\n overflow-y: auto;\n background: #1e1e1e;\n color: #d4d4d4;\n padding: 1.25rem;\n border-radius: 0.5rem;\n margin: 0;\n font-family: 'Cascadia Code', 'Fira Code', 'JetBrains Mono', 'Consolas', 'Monaco', monospace;\n font-size: 0.9rem;\n line-height: 1.6;\n border: 1px solid #2d2d30;\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3);\n `.replace(/\\s+/g, ' ').trim();\n\n return `\n <style>\n /* Custom Prism theme overrides for Dialog */\n .dialog-code-block .token.comment { color: #6a9955; }\n .dialog-code-block .token.string { color: #ce9178; }\n .dialog-code-block .token.keyword { color: #569cd6; }\n .dialog-code-block .token.function { color: #dcdcaa; }\n .dialog-code-block .token.number { color: #b5cea8; }\n .dialog-code-block .token.operator { color: #d4d4d4; }\n .dialog-code-block .token.class-name { color: #4ec9b0; }\n .dialog-code-block .token.punctuation { color: #d4d4d4; }\n .dialog-code-block .token.boolean { color: #569cd6; }\n .dialog-code-block .token.property { color: #9cdcfe; }\n .dialog-code-block .token.tag { color: #569cd6; }\n .dialog-code-block .token.attr-name { color: #9cdcfe; }\n .dialog-code-block .token.attr-value { color: #ce9178; }\n .dialog-code-block ::selection { background: #264f78; }\n </style>\n <pre class=\"${prismClass} dialog-code-block\" style=\"${codeStyles}\">\n <code class=\"${prismClass}\" style=\"color: inherit; background: transparent; text-shadow: none;\">${highlightedCode}</code>\n </pre>\n `;\n }\n\n /**\n * Trigger Prism highlighting on already rendered code blocks\n * Call this after inserting code into the DOM if not using formatCode\n */\n static highlightCodeBlocks(container = document) {\n if (window.Prism && window.Prism.highlightAllUnder) {\n window.Prism.highlightAllUnder(container);\n }\n }\n\n /**\n * Show copy success feedback\n */\n showCopySuccess() {\n const btn = this.element.querySelector('[data-action=\"copy\"]');\n if (btn) {\n const originalHtml = btn.innerHTML;\n btn.innerHTML = '<i class=\"bi bi-check me-1\"></i>Copied!';\n btn.classList.remove('btn-primary');\n btn.classList.add('btn-success');\n btn.disabled = true;\n\n setTimeout(() => {\n btn.innerHTML = originalHtml;\n btn.classList.remove('btn-success');\n btn.classList.add('btn-primary');\n btn.disabled = false;\n }, 2000);\n }\n }\n\n\n\n\n /**\n * Show a dialog with promise-based button handling\n * - If a button has a handler, it will be called. Return semantics:\n * - true or undefined: resolve and close (with button.value || button.action || index)\n * - null or false: keep dialog open (do not resolve)\n * - any other value: resolve with that value and close\n * - If no handler, resolve with action/value/index and close\n * @param {Object} options - Dialog options\n * @returns {Promise} Resolves with value/action/index or null on dismiss\n */\n static async showDialog(options = {}) {\n // Handle legacy signature (message, title, options)\n if (typeof options === 'string') {\n const message = arguments[0];\n const title = arguments[1] || 'Alert';\n const opts = arguments[2] || {};\n options = {\n ...opts,\n body: message,\n title: title\n };\n }\n\n const {\n title = 'Dialog',\n content,\n body = content || '',\n size = 'md',\n centered = true,\n buttons = [\n { text: 'OK', class: 'btn-primary', value: true }\n ],\n rejectOnDismiss = false, // Default to return null on dismissal\n ...dialogOptions\n } = options;\n\n // Create the dialog (preserve original button action/dismiss attributes)\n const dialog = new Dialog({\n title,\n body: body,\n size,\n centered,\n buttons,\n ...dialogOptions\n });\n\n // Render and mount\n // Mount to fullscreen element if it exists, otherwise body\n const fullscreenElement = document.querySelector('.table-fullscreen');\n const targetContainer = fullscreenElement || document.body;\n await dialog.render(true, targetContainer);\n\n // Return promise that resolves based on button clicks\n return new Promise((resolve, reject) => {\n let resolved = false;\n\n // Handle button clicks\n const buttonElements = dialog.element.querySelectorAll('.modal-footer button');\n buttonElements.forEach((btnElement, index) => {\n const buttonConfig = buttons[index];\n if (!buttonConfig) return;\n\n btnElement.addEventListener('click', async (e) => {\n if (resolved) return;\n\n const defaultResolveValue = (\n buttonConfig.value !== undefined\n ? buttonConfig.value\n : (buttonConfig.action ?? index)\n );\n\n // If a handler is provided, call it and respect its return semantics\n if (typeof buttonConfig.handler === 'function') {\n try {\n const result = await buttonConfig.handler({\n dialog,\n button: buttonConfig,\n index,\n event: e\n });\n\n // null/false -> keep dialog open\n if (result === null || result === false) {\n return;\n }\n\n // Determine resolve value and close\n const valueToResolve =\n (result === true || result === undefined)\n ? defaultResolveValue\n : result;\n\n resolved = true;\n // Close the dialog (Bootstrap will close if dismiss attribute is present)\n if (!buttonConfig.dismiss) {\n dialog.hide();\n }\n resolve(valueToResolve);\n } catch (err) {\n console.error('Dialog button handler error:', err);\n // Keep dialog open on handler error\n return;\n }\n } else {\n // No handler: resolve with action/value/index and close\n resolved = true;\n if (!buttonConfig.dismiss) {\n dialog.hide();\n }\n resolve(defaultResolveValue);\n }\n });\n });\n\n // Handle backdrop click or ESC key\n dialog.on('hidden', () => {\n // If not already resolved by a button handler, resolve as dismiss\n if (!resolved) {\n resolved = true;\n if (rejectOnDismiss) {\n reject(new Error('Dialog dismissed'));\n } else {\n resolve(null);\n }\n }\n // Always cleanup after hide\n setTimeout(() => {\n dialog.destroy();\n dialog.element.remove();\n }, 100);\n });\n\n // Show the dialog\n dialog.show();\n });\n }\n\n /**\n * Static alert dialog helper\n * @param {Object|string} options - Alert options or message string\n * @returns {Promise} Resolves when OK is clicked\n */\n static async alert(options = {}) {\n // Handle string argument\n if (typeof options === 'string') {\n options = {\n message: options,\n title: 'Alert'\n };\n }\n\n const {\n message = '',\n title = 'Alert',\n type = 'info', // info, success, warning, danger\n ...dialogOptions\n } = options;\n\n // Add icon based on type\n let icon = '';\n let titleClass = '';\n switch(type) {\n case 'success':\n icon = '<i class=\"bi bi-check-circle-fill text-success me-2\"></i>';\n titleClass = 'text-success';\n break;\n case 'warning':\n icon = '<i class=\"bi bi-exclamation-triangle-fill text-warning me-2\"></i>';\n titleClass = 'text-warning';\n break;\n case 'danger':\n case 'error':\n icon = '<i class=\"bi bi-x-circle-fill text-danger me-2\"></i>';\n titleClass = 'text-danger';\n break;\n default:\n icon = '<i class=\"bi bi-info-circle-fill text-info me-2\"></i>';\n titleClass = 'text-info';\n }\n\n return Dialog.showDialog({\n title: `<span class=\"${titleClass}\">${icon}${title}</span>`,\n body: `<p>${message}</p>`,\n size: 'sm',\n centered: true,\n buttons: [\n { text: 'OK', class: 'btn-primary', value: true }\n ],\n ...dialogOptions\n });\n }\n\n /**\n * Static confirm dialog\n */\n static async confirm(message, title = 'Confirm', options = {}) {\n if (typeof message === 'object') {\n options = message;\n message = options.message;\n title = options.title || title;\n }\n const dialog = new Dialog({\n title,\n body: `<p>${message}</p>`,\n size: options.size || 'sm',\n centered: true,\n backdrop: 'static',\n buttons: [\n { text: options.cancelText || 'Cancel', class: 'btn-secondary', dismiss: true, action: 'cancel' },\n { text: options.confirmText || 'Confirm', class: options.confirmClass || 'btn-primary', action: 'confirm' }\n ],\n ...options\n });\n\n // Mount to fullscreen element if it exists, otherwise body\n const fullscreenElement = document.querySelector('.table-fullscreen');\n const targetContainer = fullscreenElement || document.body;\n await dialog.render(true, targetContainer);\n dialog.show();\n\n return new Promise((resolve) => {\n let result = false;\n\n dialog.on('action:confirm', () => {\n result = true;\n dialog.hide();\n });\n\n dialog.on('hidden', () => {\n dialog.destroy();\n dialog.element.remove();\n resolve(result);\n });\n });\n }\n\n /**\n * Static prompt dialog\n */\n static async prompt(message, title = 'Input', options = {}) {\n const inputId = `prompt-input-${Date.now()}`;\n const defaultValue = options.defaultValue || '';\n const inputType = options.inputType || 'text';\n const placeholder = options.placeholder || '';\n\n const dialog = new Dialog({\n title,\n body: `\n <p>${message}</p>\n <input type=\"${inputType}\"\n class=\"form-control\"\n id=\"${inputId}\"\n value=\"${defaultValue}\"\n placeholder=\"${placeholder}\">\n `,\n size: options.size || 'sm',\n centered: true,\n backdrop: 'static',\n buttons: [\n { text: 'Cancel', class: 'btn-secondary', dismiss: true },\n { text: 'OK', class: 'btn-primary', action: 'ok' }\n ],\n ...options\n });\n\n // Mount to fullscreen element if it exists, otherwise body\n const fullscreenElement = document.querySelector('.table-fullscreen');\n const targetContainer = fullscreenElement || document.body;\n await dialog.render(true, targetContainer);\n dialog.show();\n\n // Focus the input\n dialog.on('shown', () => {\n const input = dialog.element.querySelector(`#${inputId}`);\n if (input) {\n input.focus();\n input.select();\n }\n });\n\n return new Promise((resolve) => {\n let result = null;\n\n dialog.on('action:ok', () => {\n const input = dialog.element.querySelector(`#${inputId}`);\n result = input ? input.value : null;\n dialog.hide();\n });\n\n dialog.on('hidden', () => {\n dialog.destroy();\n dialog.element.remove();\n resolve(result);\n });\n });\n }\n\n /**\n * Get Bootstrap modal instance\n */\n getModal() {\n return this.modal;\n }\n\n /**\n * Check if modal is shown\n */\n isShown() {\n return this.element?.classList.contains('show') || false;\n }\n\n /**\n * Show form in a dialog for simple data collection (no model saving)\n * @param {object} options - Configuration options\n * @returns {Promise} Promise that resolves with form data or null if cancelled\n */\n static async showForm(options = {}) {\n const {\n title = 'Form',\n formConfig = {},\n size = 'md',\n centered = true,\n submitText = 'Submit',\n cancelText = 'Cancel',\n ...dialogOptions\n } = options;\n\n // Create the FormView (no model for simple form) - lazy loaded\n const FormView = (await import('@core/forms/FormView.js')).default;\n const formView = new FormView({\n fileHandling: options.fileHandling || 'base64',\n data: options.data,\n defaults: options.defaults,\n model: options.model,\n formConfig: {\n fields: formConfig.fields || options.fields,\n ...formConfig,\n submitButton: false,\n resetButton: false\n }\n });\n\n // Create the dialog with the FormView as body\n const dialog = new Dialog({\n title,\n body: formView,\n size,\n centered,\n buttons: [\n {\n text: cancelText,\n class: 'btn-secondary',\n action: 'cancel'\n },\n {\n text: submitText,\n class: 'btn-primary',\n action: 'submit'\n }\n ],\n ...dialogOptions\n });\n\n // Render and mount dialog\n const fullscreenElement = document.querySelector('.table-fullscreen');\n const targetContainer = fullscreenElement || document.body;\n await dialog.render(true, targetContainer);\n\n // Show the dialog\n dialog.show();\n\n return new Promise((resolve) => {\n let resolved = false;\n\n // Handle dialog actions\n dialog.on('action:submit', async () => {\n if (resolved) return;\n\n // Validate form\n if (!formView.validate()) {\n formView.focusFirstError();\n return;\n }\n\n if (options.autoSave && options.model) {\n dialog.setLoading(true);\n const result = await formView.saveModel()\n if (!result.success) {\n dialog.setLoading(false);\n dialog.render();\n dialog.getApp().toast.error(result.message);\n return;\n }\n resolved = true;\n dialog.hide();\n resolve(result);\n }\n\n // Get form data and resolve\n try {\n const formData = await formView.getFormData();\n resolved = true;\n dialog.hide();\n resolve(formData);\n } catch (error) {\n console.error('Error collecting form data:', error);\n formView.showError('Error collecting form data');\n }\n });\n\n dialog.on('action:cancel', () => {\n if (resolved) return;\n resolved = true;\n dialog.hide();\n resolve(null);\n });\n\n // Handle ESC key or backdrop click\n dialog.on('hidden', () => {\n if (!resolved) {\n resolved = true;\n resolve(null);\n }\n // Clean up\n setTimeout(() => {\n formView.destroy();\n dialog.destroy();\n }, 100);\n });\n });\n }\n\n /**\n * Show form in a dialog with automatic model saving\n * @param {object} options - Configuration options (requires model)\n * @returns {Promise} Promise that resolves with save result or null if cancelled\n */\n static async showModelForm(options = {}) {\n const {\n title = 'Edit',\n formConfig = {},\n size = 'md',\n centered = true,\n submitText = 'Save',\n cancelText = 'Cancel',\n model,\n fields,\n ...dialogOptions\n } = options;\n\n if (!model) {\n throw new Error('showModelForm requires a model');\n }\n\n // Create the FormView with model - lazy loaded\n const FormView = (await import('@core/forms/FormView.js')).default;\n const formView = new FormView({\n fileHandling: options.fileHandling || 'base64',\n model: model,\n data: options.data,\n defaults: options.defaults,\n formConfig: {\n // Support both formConfig.fields and direct fields parameter\n fields: fields || formConfig.fields || [],\n ...formConfig,\n submitButton: false,\n resetButton: false\n }\n });\n\n // Create the dialog with the FormView as body\n const dialog = new Dialog({\n title,\n body: formView,\n size,\n centered,\n buttons: [\n {\n text: cancelText,\n class: 'btn-secondary',\n action: 'cancel'\n },\n {\n text: submitText,\n class: 'btn-primary',\n action: 'submit'\n }\n ],\n ...dialogOptions\n });\n\n // Render and mount dialog\n const fullscreenElement = document.querySelector('.table-fullscreen');\n const targetContainer = fullscreenElement || document.body;\n await dialog.render(true, targetContainer);\n\n // Show the dialog\n dialog.show();\n\n return new Promise((resolve) => {\n let resolved = false;\n\n // Handle dialog actions\n dialog.on('action:submit', async () => {\n if (resolved) return;\n\n // Show loading state\n dialog.setLoading(true, 'Saving...');\n\n try {\n const result = await formView.handleSubmit();\n if (result.success) {\n resolved = true;\n dialog.hide();\n resolve(result);\n } else {\n // Restore form and show error\n dialog.setLoading(false);\n let errmsg = result.error;\n if (result.data && result.data.error) {\n errmsg = result.data.error;\n }\n dialog.getApp().toast.error(errmsg);\n // formView.showError(result.error || 'Save failed. Please try again.');\n }\n } catch (error) {\n console.error('Error saving form:', error);\n // Restore form and show error\n await dialog.setContent(formView);\n formView.showError(error.message || 'An error occurred while saving');\n }\n });\n\n dialog.on('action:cancel', () => {\n if (resolved) return;\n resolved = true;\n dialog.hide();\n resolve(null);\n });\n\n // Handle ESC key or backdrop click\n dialog.on('hidden', () => {\n if (!resolved) {\n resolved = true;\n resolve(null);\n }\n // Clean up\n setTimeout(() => {\n formView.destroy();\n dialog.destroy();\n }, 100);\n });\n });\n }\n\n /**\n * Show data in a dialog using DataView component\n * @param {object} options - Configuration options\n * @returns {Promise} Promise that resolves when dialog is closed\n */\n static async showData(options = {}) {\n const {\n title = 'Data View',\n data = {},\n model = null,\n fields = [],\n columns = 2,\n responsive = true,\n showEmptyValues = false,\n emptyValueText = '—',\n size = 'lg',\n centered = true,\n closeText = 'Close',\n ...dialogOptions\n } = options;\n\n\n // Create the DataView - lazy loaded\n const DataView = (await import('@core/views/data/DataView.js')).default;\n const dataView = new DataView({\n data,\n model,\n fields,\n columns,\n responsive,\n showEmptyValues,\n emptyValueText\n });\n\n // Create the dialog with the DataView as body\n const dialog = new Dialog({\n title,\n body: dataView,\n size,\n centered,\n buttons: [\n {\n text: closeText,\n class: 'btn-secondary',\n value: 'close'\n }\n ],\n ...dialogOptions\n });\n\n // Render and mount dialog\n const fullscreenElement = document.querySelector('.table-fullscreen');\n const targetContainer = fullscreenElement || document.body;\n await dialog.render(true, targetContainer);\n\n // Show the dialog and return promise\n dialog.show();\n\n return new Promise((resolve) => {\n let resolved = false;\n\n // Get close button\n const closeBtn = dialog.element.querySelector('.modal-footer button');\n\n // Handle close\n const handleClose = () => {\n if (resolved) return;\n resolved = true;\n dialog.hide();\n resolve(true);\n };\n\n // Attach event listener\n closeBtn?.addEventListener('click', handleClose);\n\n // Handle ESC key or backdrop click\n dialog.on('hidden', () => {\n if (!resolved) {\n resolved = true;\n resolve(true);\n }\n // Clean up\n setTimeout(() => {\n dataView.destroy();\n dialog.destroy();\n dialog.element.remove();\n }, 100);\n });\n\n // Forward DataView events\n dataView.on('field:click', (data) => {\n dialog.emit('dataview:field:click', data);\n });\n\n dataView.on('error', (data) => {\n dialog.emit('dataview:error', data);\n });\n });\n }\n}\n\nDialog.showConfirm = Dialog.confirm;\nDialog.showError = Dialog.alert;\n\nexport default Dialog;\n"],"names":["bodyClass","title","data"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./Rest-BNYqGlnP.js");class Dialog extends e.View{static _openDialogs=[];static _baseZIndex={backdrop:1050,modal:1055};static getFullscreenAwareZIndex(){return document.querySelector(".table-fullscreen")?{backdrop:10040,modal:10050}:this._baseZIndex}static _busyIndicator=null;static _busyCounter=0;static _busyTimeout=null;static fixAllBackdropStacking(){const e=document.querySelectorAll(".modal-backdrop"),t=Dialog._openDialogs;if(0===e.length||0===t.length)return;const o=[...t].sort((e,t)=>(e._dialogZIndex||0)-(t._dialogZIndex||0));e.forEach((e,t)=>{if(t<o.length){const i=o[t]._dialogZIndex-5;e.style.zIndex=i;const s=document.querySelector(".table-fullscreen")||document.body;e.parentNode!==s&&s.appendChild(e)}})}static updateAllBackdropStacking(){Dialog.fixAllBackdropStacking()}static showBusy(e={}){const{timeout:t=3e4,message:o="Loading..."}=e;if(this._busyCounter++,1===this._busyCounter){if(this._busyTimeout&&clearTimeout(this._busyTimeout),!this._busyIndicator){const e=this.getFullscreenAwareZIndex().modal+1e3;this._busyIndicator=document.createElement("div"),this._busyIndicator.className="mojo-busy-indicator",this._busyIndicator.innerHTML=`\n <div class="mojo-busy-spinner">\n <div class="spinner-border text-light" role="status">\n <span class="visually-hidden">Loading...</span>\n </div>\n <p class="mojo-busy-message mt-3 text-light">${o}</p>\n </div>\n <style>\n .mojo-busy-indicator {\n position: fixed; top: 0; left: 0; width: 100vw; height: 100vh;\n background-color: rgba(0, 0, 0, 0.5); z-index: ${e};\n display: flex; align-items: center; justify-content: center;\n opacity: 0; transition: opacity 0.15s linear;\n }\n .mojo-busy-indicator.show { opacity: 1; }\n .mojo-busy-spinner .spinner-border { width: 3rem; height: 3rem; }\n </style>\n `,document.body.appendChild(this._busyIndicator)}const e=this._busyIndicator.querySelector(".mojo-busy-message");e&&(e.textContent=o),setTimeout(()=>this._busyIndicator.classList.add("show"),10),this._busyTimeout=setTimeout(()=>{console.error("Busy indicator timed out."),this.hideBusy(!0),this.alert({title:"Operation Timed Out",message:"The operation took too long. Please check your connection and try again.",type:"danger"})},t)}}static hideBusy(e=!1){e?this._busyCounter=0:this._busyCounter--,this._busyCounter<=0&&(this._busyCounter=0,this._busyTimeout&&(clearTimeout(this._busyTimeout),this._busyTimeout=null),this._busyIndicator&&(this._busyIndicator.classList.remove("show"),setTimeout(()=>{this._busyIndicator&&0===this._busyCounter&&(this._busyIndicator.remove(),this._busyIndicator=null)},150)))}constructor(e={}){const t=e.id||`modal-${Date.now()}`;super({...e,id:t,tagName:"div",className:`modal ${!1!==e.fade?"fade":""} ${e.className||""}`,attributes:{tabindex:"-1","aria-hidden":"true","aria-labelledby":e.labelledBy||`${t}-label`,"aria-describedby":e.describedBy||null,...e.attributes}}),this.modalId=t,this.title=e.title||"",this.titleId=`${this.modalId}-label`,this.size=e.size||"",this.centered=void 0!==e.centered&&e.centered,this.scrollable=void 0!==e.scrollable&&e.scrollable,this.autoSize=e.autoSize||"auto"===e.size,this.backdrop=void 0===e.backdrop||e.backdrop,this.keyboard=void 0===e.keyboard||e.keyboard,this.focus=void 0===e.focus||e.focus,this.header=void 0===e.header||e.header,this.headerContent=e.headerContent||null,this.closeButton=void 0===e.closeButton||e.closeButton,this.contextMenu=e.contextMenu||null,this.body=e.body||e.content||"",this.bodyView=null,this.bodyClass=e.bodyClass||"",this.noBodyPadding=e.noBodyPadding||!1,this.minWidth=e.minWidth||300,this.minHeight=e.minHeight||200,this.maxWidthPercent=e.maxWidthPercent||.9,this.maxHeightPercent=e.maxHeightPercent||.8,this._processBodyContent(this.body),this.footer=e.footer||null,this.footerView=null,this.footerClass=e.footerClass||"",this._processFooterContent(this.footer),this.buttons=e.buttons||null,this.onShow=e.onShow||null,this.onShown=e.onShown||null,this.onHide=e.onHide||null,this.onHidden=e.onHidden||null,this.onHidePrevented=e.onHidePrevented||null,this.autoShow=void 0!==e.autoShow&&e.autoShow,this.modal=null,this.relatedTarget=e.relatedTarget||null}_processBodyContent(t){if(t&&t.render)this.bodyView=t,this.body="",this.addChild(this.bodyView);else if("function"==typeof t)try{const o=t();o instanceof e.View?(this.bodyView=o,this.body="",this.addChild(this.bodyView)):o instanceof Promise?(this.bodyPromise=o,this.body='<div class="text-center"><div class="spinner-border spinner-border-sm"></div></div>'):this.body=o}catch(o){console.error("Error processing body function:",o),this.body=t}else this.body=t}_processFooterContent(t){if(t instanceof e.View)this.footerView=t,this.footer=null,this.addChild(this.footerView);else if("function"==typeof t)try{const o=t();o instanceof e.View?(this.footerView=o,this.footer=null,this.addChild(this.footerView)):o instanceof Promise?(this.footerPromise=o,this.footer='<div class="text-center"><div class="spinner-border spinner-border-sm"></div></div>'):this.footer=o}catch(o){console.error("Error processing footer function:",o),this.footer=t}else this.footer=t}async getTemplate(){const e=["modal-dialog"];return this.size&&"auto"!==this.size&&(this.size.startsWith("fullscreen")||["sm","lg","xl"].includes(this.size))&&e.push(`modal-${this.size}`),this.centered&&e.push("modal-dialog-centered"),this.scrollable&&e.push("modal-dialog-scrollable"),`\n <div class="${e.join(" ")}">\n <div class="modal-content">\n ${await this.buildHeader()}\n ${await this.buildBody()}\n ${await this.buildFooter()}\n </div>\n </div>\n `}async buildHeader(){if(!this.header)return"";if(this.headerContent)return`<div class="modal-header">${this.headerContent}</div>`;let e="";return this.contextMenu&&this.contextMenu.items&&this.contextMenu.items.length>0?e=await this.buildContextMenu():this.closeButton&&(e='<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>'),`\n <div class="modal-header">\n ${this.title?`<h5 class="modal-title" id="${this.titleId}">${this.title}</h5>`:""}\n ${e}\n </div>\n `}async buildContextMenu(){const e=await this.filterContextMenuItems();if(0===e.length)return this.closeButton?'<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>':"";const t=this.contextMenu.icon||"bi-three-dots-vertical";return`\n <div class="dropdown">\n <button class="${this.contextMenu.buttonClass||"btn btn-link p-1 mojo-modal-context-menu-btn"}" type="button" data-bs-toggle="dropdown" aria-expanded="false">\n <i class="${t}"></i>\n </button>\n <ul class="dropdown-menu dropdown-menu-end">\n ${e.map(e=>{if("divider"===e.type)return'<li><hr class="dropdown-divider"></li>';const t=e.icon?`<i class="${e.icon} me-2"></i>`:"",o=e.label||"";if(e.href)return`<li><a class="dropdown-item" href="${e.href}"${e.target?` target="${e.target}"`:""}>${t}${o}</a></li>`;if(e.action){const i=Object.keys(e).filter(e=>e.startsWith("data-")).map(t=>`${t}="${e[t]}"`).join(" ");return`<li><a class="dropdown-item" data-action="${e.action}" ${i}>${t}${o}</a></li>`}return""}).join("")}\n </ul>\n </div>\n `}async filterContextMenuItems(){if(!this.contextMenu||!this.contextMenu.items)return[];const e=[];for(const i of this.contextMenu.items)if("divider"!==i.type){if(i.permissions)try{const e=this.getApp?.();let o=null;if(e&&(o=e.activeUser||e.getState?.("activeUser")),!o&&"undefined"!=typeof window&&window.getApp)try{const e=window.getApp();o=e?.activeUser}catch(t){}if(!o||!o.hasPermission)continue;if(!o.hasPermission(i.permissions))continue}catch(o){console.warn("Error checking permissions for context menu item:",o);continue}e.push(i)}else e.push(i);return e}async buildBody(){return this.bodyView?(this.bodyView.replaceById=!0,`<div class="${this.noBodyPadding?`modal-body p-0 ${this.bodyClass}`:`modal-body ${this.bodyClass}`}" data-view-container="body">\n \x3c!-- View will be mounted here --\x3e\n <div id="${this.bodyView.id}"></div>\n </div>`):this.body||""===this.body?`\n <div class="${this.noBodyPadding?`modal-body p-0 ${this.bodyClass}`:`modal-body ${this.bodyClass}`}">\n ${this.body}\n </div>\n `:""}async buildFooter(){if(this.footerView)return`<div class="modal-footer ${this.footerClass}" data-view-container="footer"></div>`;if(null!==this.footer&&"string"==typeof this.footer)return`<div class="modal-footer ${this.footerClass}">${this.footer}</div>`;if(this.buttons&&this.buttons.length>0){const e=this.buttons.map(e=>{const t=e.dismiss?'data-bs-dismiss="modal"':"",o=e.action?`data-action="${e.action}"`:"",i=e.id?`id="${e.id}"`:"",s=e.disabled?"disabled":"";return`\n <button type="${e.type||"button"}"\n class="btn ${e.class||"btn-secondary"}"\n ${i}\n ${t}\n ${o}\n ${s}>\n ${e.icon?`<i class="bi ${e.icon} me-1"></i>`:""}\n ${e.text||"Button"}\n </button>\n `}).join("");return`<div class="modal-footer ${this.footerClass}">${e}</div>`}return""}async mount(e=null){if(!this.mounted&&!this.destroyed){if(!this.element)throw new Error("Cannot mount dialog without element");return await this.onBeforeMount(),(document.querySelector(".table-fullscreen")||document.body).appendChild(this.element),this.bindEvents(),this.mounted=!0,await this.onAfterMount(),this.emit("mounted",{view:this}),this}}async onAfterRender(){await super.onAfterRender(),window.Prism&&this.element&&this.element.querySelectorAll("pre code").length>0&&window.Prism.highlightAllUnder(this.element),this.autoSize&&this.setupAutoSizing()}async onAfterMount(){await super.onAfterMount(),"undefined"!=typeof window&&window.bootstrap&&window.bootstrap.Modal&&("static"===this.backdrop&&this.element.setAttribute("data-bs-backdrop","static"),this.keyboard||this.element.setAttribute("data-bs-keyboard","false"),this.modal=new window.bootstrap.Modal(this.element,{backdrop:this.backdrop,keyboard:this.keyboard,focus:this.focus}),this.bindBootstrapEvents(),this.autoShow&&this.show(this.relatedTarget))}setupAutoSizing(){this.element&&(this.element.addEventListener("shown.bs.modal",()=>{this.applyAutoSizing()},{once:!0}),setTimeout(()=>{this.isShown()&&this.applyAutoSizing()},100))}applyAutoSizing(){if(this.element)try{const e=this.element.querySelector(".modal-dialog"),t=this.element.querySelector(".modal-content"),o=this.element.querySelector(".modal-body");if(!e||!t||!o)return void console.warn("Dialog auto-sizing: Required elements not found");if(this.bodyView&&!this.bodyView.element)return void setTimeout(()=>this.applyAutoSizing(),50);const i={dialogMaxWidth:e.style.maxWidth,dialogWidth:e.style.width,contentWidth:t.style.width,contentMaxHeight:t.style.maxHeight,bodyOverflow:o.style.overflowY};e.style.maxWidth="none",e.style.width="auto",t.style.width="auto",t.style.maxHeight="none",t.offsetHeight;const s=t.getBoundingClientRect(),n=40,a=Math.min(window.innerWidth*this.maxWidthPercent,window.innerWidth-n),l=Math.min(window.innerHeight*this.maxHeightPercent,window.innerHeight-n);let r=Math.max(this.minWidth,Math.ceil(s.width+20)),d=Math.max(this.minHeight,Math.ceil(s.height));r=Math.min(r,a);const c=s.height>l;e.style.maxWidth=`${r}px`,e.style.width=`${r}px`,c&&(t.style.maxHeight=`${l}px`,o.style.overflowY="auto",d=l),this.autoSizedWidth=r,this.autoSizedHeight=d,this._originalStyles=i}catch(e){console.error("Error in dialog auto-sizing:",e),this.element.querySelector(".modal-dialog").style.maxWidth=""}}resetAutoSizing(){if(this.autoSize&&this._originalStyles&&this.element)try{const e=this.element.querySelector(".modal-dialog"),t=this.element.querySelector(".modal-content"),o=this.element.querySelector(".modal-body");e&&t&&o&&(e.style.maxWidth=this._originalStyles.dialogMaxWidth||"",e.style.width=this._originalStyles.dialogWidth||"",t.style.width=this._originalStyles.contentWidth||"",t.style.maxHeight=this._originalStyles.contentMaxHeight||"",o.style.overflowY=this._originalStyles.bodyOverflow||"",delete this.autoSizedWidth,delete this.autoSizedHeight,delete this._originalStyles)}catch(e){console.error("Error resetting dialog auto-sizing:",e)}}bindBootstrapEvents(){this.element.addEventListener("show.bs.modal",e=>{const t=Dialog._openDialogs.length,o=Dialog.getFullscreenAwareZIndex().modal+20*t;this.element.style.zIndex=o,this._dialogZIndex=o,this._backdropZIndex=o-10,Dialog._openDialogs.push(this),this.onShow&&this.onShow(e),this.emit("show",{dialog:this,relatedTarget:e.relatedTarget})}),this.element.addEventListener("shown.bs.modal",e=>{if(setTimeout(()=>{Dialog.fixAllBackdropStacking()},50),this.onShown&&this.onShown(e),this.emit("shown",{dialog:this,relatedTarget:e.relatedTarget}),this.focus){const e=this.element.querySelector('input:not([type="hidden"]), textarea, select');e&&e.focus()}}),this.element.addEventListener("hide.bs.modal",e=>{const t=this.element.querySelector(":focus");t&&t.blur(),this.onHide&&!1===this.onHide(e)?e.preventDefault():this.emit("hide",{dialog:this})}),this.element.addEventListener("hidden.bs.modal",e=>{const t=Dialog._openDialogs.indexOf(this);t>-1&&Dialog._openDialogs.splice(t,1),Dialog._openDialogs.length>0&&(document.body.classList.add("modal-open"),setTimeout(()=>{Dialog.fixAllBackdropStacking()},50)),this.previousFocus&&document.body.contains(this.previousFocus)&&this.previousFocus.focus(),this.onHidden&&this.onHidden(e),this.emit("hidden",{dialog:this})}),this.element.addEventListener("hidePrevented.bs.modal",e=>{this.onHidePrevented&&this.onHidePrevented(e),this.emit("hidePrevented",{dialog:this})})}show(e=null){this.previousFocus=document.activeElement,window.lastDialog=this,this.modal&&this.modal.show(e)}hide(){const e=this.element?.querySelector(":focus");e&&e.blur(),this.modal&&this.modal.hide()}toggle(e=null){this.modal&&this.modal.toggle(e)}async destroy(){if(this.modal){const e=this.element?.querySelector(":focus");e&&e.blur(),this.modal.dispose(),this.modal=null}this.previousFocus&&document.body.contains(this.previousFocus)&&(this.previousFocus.focus(),this.previousFocus=null),this.autoSize&&this.resetAutoSizing(),await super.destroy()}handleUpdate(){this.modal&&this.modal.handleUpdate()}async setContent(t){if(t instanceof e.View){this.bodyView&&(await this.bodyView.destroy(),this.removeChild(this.bodyView)),this.bodyView=t,this.body="",this.addChild(this.bodyView);const e=this.element?.querySelector(".modal-body");e&&(e.innerHTML="",await this.bodyView.render(e))}else{this.body=t;const e=this.element?.querySelector(".modal-body");e&&(e.innerHTML=t)}this.handleUpdate()}setTitle(e){this.title=e;const t=this.element?.querySelector(".modal-title");t&&(t.textContent=e)}setLoading(e=!0,t="Loading..."){const o=this.element?.querySelector(".modal-body");o&&(e?o.innerHTML=`\n <div class="text-center py-4">\n <div class="spinner-border text-primary mb-3" role="status">\n <span class="visually-hidden">Loading...</span>\n </div>\n <p>${t}</p>\n </div>\n `:this.bodyView&&o.replaceChildren(this.bodyView.element))}async onBeforeDestroy(){this.bodyView&&await this.bodyView.destroy(),this.footerView&&await this.footerView.destroy(),await super.onBeforeDestroy(),this.modal&&(this.modal.dispose(),this.modal=null)}static async showCode(e={}){const t=new Dialog({title:e.title||"Source Code",size:e.size||"lg",scrollable:!0,body:Dialog.formatCode(e.code,e.language),buttons:[{text:"Copy to Clipboard",class:"btn-primary",icon:"bi-clipboard",action:"copy"},{text:"Close",class:"btn-secondary",dismiss:!0}]});t.on("action:copy",async()=>{if(navigator.clipboard)try{await navigator.clipboard.writeText(e.code),t.showCopySuccess()}catch(o){console.error("Failed to copy:",o)}});const o=document.querySelector(".table-fullscreen")||document.body;return await t.render(!0,o),window.Prism&&t.element&&window.Prism.highlightAllUnder(t.element),t.show(),t.on("hidden",()=>{t.destroy(),t.element.remove()}),t}static formatCode(e,t="javascript"){let o;o=window.Prism&&window.Prism.languages[t]?window.Prism.highlight(e,window.Prism.languages[t],t):e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;");const i=window.Prism?`language-${t}`:"";return`\n <style>\n /* Custom Prism theme overrides for Dialog */\n .dialog-code-block .token.comment { color: #6a9955; }\n .dialog-code-block .token.string { color: #ce9178; }\n .dialog-code-block .token.keyword { color: #569cd6; }\n .dialog-code-block .token.function { color: #dcdcaa; }\n .dialog-code-block .token.number { color: #b5cea8; }\n .dialog-code-block .token.operator { color: #d4d4d4; }\n .dialog-code-block .token.class-name { color: #4ec9b0; }\n .dialog-code-block .token.punctuation { color: #d4d4d4; }\n .dialog-code-block .token.boolean { color: #569cd6; }\n .dialog-code-block .token.property { color: #9cdcfe; }\n .dialog-code-block .token.tag { color: #569cd6; }\n .dialog-code-block .token.attr-name { color: #9cdcfe; }\n .dialog-code-block .token.attr-value { color: #ce9178; }\n .dialog-code-block ::selection { background: #264f78; }\n </style>\n <pre class="${i} dialog-code-block" style="${"\n max-height: 60vh;\n overflow-y: auto;\n background: #1e1e1e;\n color: #d4d4d4;\n padding: 1.25rem;\n border-radius: 0.5rem;\n margin: 0;\n font-family: 'Cascadia Code', 'Fira Code', 'JetBrains Mono', 'Consolas', 'Monaco', monospace;\n font-size: 0.9rem;\n line-height: 1.6;\n border: 1px solid #2d2d30;\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3);\n ".replace(/\s+/g," ").trim()}">\n <code class="${i}" style="color: inherit; background: transparent; text-shadow: none;">${o}</code>\n </pre>\n `}static highlightCodeBlocks(e=document){window.Prism&&window.Prism.highlightAllUnder&&window.Prism.highlightAllUnder(e)}showCopySuccess(){const e=this.element.querySelector('[data-action="copy"]');if(e){const t=e.innerHTML;e.innerHTML='<i class="bi bi-check me-1"></i>Copied!',e.classList.remove("btn-primary"),e.classList.add("btn-success"),e.disabled=!0,setTimeout(()=>{e.innerHTML=t,e.classList.remove("btn-success"),e.classList.add("btn-primary"),e.disabled=!1},2e3)}}static async showDialog(e={}){"string"==typeof e&&(e={...arguments[2]||{},body:arguments[0],title:arguments[1]||"Alert"});const{title:t="Dialog",content:o,body:i=o||"",size:s="md",centered:n=!0,buttons:a=[{text:"OK",class:"btn-primary",value:!0}],rejectOnDismiss:l=!1,...r}=e,d=new Dialog({title:t,body:i,size:s,centered:n,buttons:a,...r}),c=document.querySelector(".table-fullscreen")||document.body;return await d.render(!0,c),new Promise((e,t)=>{let o=!1;d.element.querySelectorAll(".modal-footer button").forEach((t,i)=>{const s=a[i];s&&t.addEventListener("click",async t=>{if(o)return;const n=void 0!==s.value?s.value:s.action??i;if("function"==typeof s.handler)try{const a=await s.handler({dialog:d,button:s,index:i,event:t});if(null===a||!1===a)return;const l=!0===a||void 0===a?n:a;o=!0,s.dismiss||d.hide(),e(l)}catch(a){return void console.error("Dialog button handler error:",a)}else o=!0,s.dismiss||d.hide(),e(n)})}),d.on("hidden",()=>{o||(o=!0,l?t(new Error("Dialog dismissed")):e(null)),setTimeout(()=>{d.destroy(),d.element.remove()},100)}),d.show()})}static async alert(e={}){"string"==typeof e&&(e={message:e,title:"Alert"});const{message:t="",title:o="Alert",type:i="info",...s}=e;let n="",a="";switch(i){case"success":n='<i class="bi bi-check-circle-fill text-success me-2"></i>',a="text-success";break;case"warning":n='<i class="bi bi-exclamation-triangle-fill text-warning me-2"></i>',a="text-warning";break;case"danger":case"error":n='<i class="bi bi-x-circle-fill text-danger me-2"></i>',a="text-danger";break;default:n='<i class="bi bi-info-circle-fill text-info me-2"></i>',a="text-info"}return Dialog.showDialog({title:`<span class="${a}">${n}${o}</span>`,body:`<p>${t}</p>`,size:"sm",centered:!0,buttons:[{text:"OK",class:"btn-primary",value:!0}],...s})}static async confirm(e,t="Confirm",o={}){"object"==typeof e&&(e=(o=e).message,t=o.title||t);const i=new Dialog({title:t,body:`<p>${e}</p>`,size:o.size||"sm",centered:!0,backdrop:"static",buttons:[{text:o.cancelText||"Cancel",class:"btn-secondary",dismiss:!0,action:"cancel"},{text:o.confirmText||"Confirm",class:o.confirmClass||"btn-primary",action:"confirm"}],...o}),s=document.querySelector(".table-fullscreen")||document.body;return await i.render(!0,s),i.show(),new Promise(e=>{let t=!1;i.on("action:confirm",()=>{t=!0,i.hide()}),i.on("hidden",()=>{i.destroy(),i.element.remove(),e(t)})})}static async prompt(e,t="Input",o={}){const i=`prompt-input-${Date.now()}`,s=o.defaultValue||"",n=o.inputType||"text",a=o.placeholder||"",l=new Dialog({title:t,body:`\n <p>${e}</p>\n <input type="${n}"\n class="form-control"\n id="${i}"\n value="${s}"\n placeholder="${a}">\n `,size:o.size||"sm",centered:!0,backdrop:"static",buttons:[{text:"Cancel",class:"btn-secondary",dismiss:!0},{text:"OK",class:"btn-primary",action:"ok"}],...o}),r=document.querySelector(".table-fullscreen")||document.body;return await l.render(!0,r),l.show(),l.on("shown",()=>{const e=l.element.querySelector(`#${i}`);e&&(e.focus(),e.select())}),new Promise(e=>{let t=null;l.on("action:ok",()=>{const e=l.element.querySelector(`#${i}`);t=e?e.value:null,l.hide()}),l.on("hidden",()=>{l.destroy(),l.element.remove(),e(t)})})}getModal(){return this.modal}isShown(){return this.element?.classList.contains("show")||!1}static async showForm(e={}){const{title:t="Form",formConfig:o={},size:i="md",centered:s=!0,submitText:n="Submit",cancelText:a="Cancel",...l}=e,r=new(0,(await Promise.resolve().then(()=>require("./FormView-nulck4nL.js")).then(e=>e.FormView$1)).default)({fileHandling:e.fileHandling||"base64",data:e.data,defaults:e.defaults,model:e.model,formConfig:{fields:o.fields||e.fields,...o,submitButton:!1,resetButton:!1}}),d=new Dialog({title:t,body:r,size:i,centered:s,buttons:[{text:a,class:"btn-secondary",action:"cancel"},{text:n,class:"btn-primary",action:"submit"}],...l}),c=document.querySelector(".table-fullscreen")||document.body;return await d.render(!0,c),d.show(),new Promise(t=>{let o=!1;d.on("action:submit",async()=>{if(!o)if(r.validate()){if(e.autoSave&&e.model){d.setLoading(!0);const e=await r.saveModel();if(!e.success)return d.setLoading(!1),d.render(),void d.getApp().toast.error(e.message);o=!0,d.hide(),t(e)}try{const e=await r.getFormData();o=!0,d.hide(),t(e)}catch(i){console.error("Error collecting form data:",i),r.showError("Error collecting form data")}}else r.focusFirstError()}),d.on("action:cancel",()=>{o||(o=!0,d.hide(),t(null))}),d.on("hidden",()=>{o||(o=!0,t(null)),setTimeout(()=>{r.destroy(),d.destroy()},100)})})}static async showModelForm(e={}){const{title:t="Edit",formConfig:o={},size:i="md",centered:s=!0,submitText:n="Save",cancelText:a="Cancel",model:l,fields:r,...d}=e;if(!l)throw new Error("showModelForm requires a model");const c=new(0,(await Promise.resolve().then(()=>require("./FormView-nulck4nL.js")).then(e=>e.FormView$1)).default)({fileHandling:e.fileHandling||"base64",model:l,data:e.data,defaults:e.defaults,formConfig:{fields:r||o.fields||[],...o,submitButton:!1,resetButton:!1}}),h=new Dialog({title:t,body:c,size:i,centered:s,buttons:[{text:a,class:"btn-secondary",action:"cancel"},{text:n,class:"btn-primary",action:"submit"}],...d}),u=document.querySelector(".table-fullscreen")||document.body;return await h.render(!0,u),h.show(),new Promise(e=>{let t=!1;h.on("action:submit",async()=>{if(!t){h.setLoading(!0,"Saving...");try{const o=await c.handleSubmit();if(o.success)t=!0,h.hide(),e(o);else{h.setLoading(!1);let e=o.error;o.data&&o.data.error&&(e=o.data.error),h.getApp().toast.error(e)}}catch(o){console.error("Error saving form:",o),await h.setContent(c),c.showError(o.message||"An error occurred while saving")}}}),h.on("action:cancel",()=>{t||(t=!0,h.hide(),e(null))}),h.on("hidden",()=>{t||(t=!0,e(null)),setTimeout(()=>{c.destroy(),h.destroy()},100)})})}static async showData(e={}){const{title:t="Data View",data:o={},model:i=null,fields:s=[],columns:n=2,responsive:a=!0,showEmptyValues:l=!1,emptyValueText:r="—",size:d="lg",centered:c=!0,closeText:h="Close",...u}=e,m=new(0,(await Promise.resolve().then(()=>require("./DataView-CdDY9ijM.js"))).default)({data:o,model:i,fields:s,columns:n,responsive:a,showEmptyValues:l,emptyValueText:r}),b=new Dialog({title:t,body:m,size:d,centered:c,buttons:[{text:h,class:"btn-secondary",value:"close"}],...u}),y=document.querySelector(".table-fullscreen")||document.body;return await b.render(!0,y),b.show(),new Promise(e=>{let t=!1;const o=b.element.querySelector(".modal-footer button");o?.addEventListener("click",()=>{t||(t=!0,b.hide(),e(!0))}),b.on("hidden",()=>{t||(t=!0,e(!0)),setTimeout(()=>{m.destroy(),b.destroy(),b.element.remove()},100)}),m.on("field:click",e=>{b.emit("dataview:field:click",e)}),m.on("error",e=>{b.emit("dataview:error",e)})})}}Dialog.showConfirm=Dialog.confirm,Dialog.showError=Dialog.alert,exports.default=Dialog;
2
- //# sourceMappingURL=Dialog-DmIPK_Bi.js.map