@memberjunction/ng-dashboards 5.11.0 → 5.13.0

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 (229) hide show
  1. package/dist/AI/components/agents/agent-configuration.component.d.ts +34 -2
  2. package/dist/AI/components/agents/agent-configuration.component.d.ts.map +1 -1
  3. package/dist/AI/components/agents/agent-configuration.component.js +586 -223
  4. package/dist/AI/components/agents/agent-configuration.component.js.map +1 -1
  5. package/dist/AI/components/agents/agent-editor.component.js +2 -2
  6. package/dist/AI/components/agents/agent-filter-panel.component.d.ts +8 -0
  7. package/dist/AI/components/agents/agent-filter-panel.component.d.ts.map +1 -1
  8. package/dist/AI/components/agents/agent-filter-panel.component.js +85 -52
  9. package/dist/AI/components/agents/agent-filter-panel.component.js.map +1 -1
  10. package/dist/AI/components/charts/performance-heatmap.component.d.ts +1 -0
  11. package/dist/AI/components/charts/performance-heatmap.component.d.ts.map +1 -1
  12. package/dist/AI/components/charts/performance-heatmap.component.js +27 -5
  13. package/dist/AI/components/charts/performance-heatmap.component.js.map +1 -1
  14. package/dist/AI/components/charts/time-series-chart.component.d.ts +5 -0
  15. package/dist/AI/components/charts/time-series-chart.component.d.ts.map +1 -1
  16. package/dist/AI/components/charts/time-series-chart.component.js +23 -8
  17. package/dist/AI/components/charts/time-series-chart.component.js.map +1 -1
  18. package/dist/AI/components/execution-monitoring.component.js +2 -2
  19. package/dist/AI/components/execution-monitoring.component.js.map +1 -1
  20. package/dist/AI/components/models/model-management.component.js +2 -2
  21. package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js +2 -2
  22. package/dist/AI/components/prompts/prompt-filter-panel.component.js +2 -2
  23. package/dist/AI/components/prompts/prompt-management.component.js +3 -3
  24. package/dist/AI/components/prompts/prompt-management.component.js.map +1 -1
  25. package/dist/AI/components/prompts/prompt-version-control.component.js +2 -2
  26. package/dist/AI/components/requests/agent-requests-resource.component.d.ts +83 -0
  27. package/dist/AI/components/requests/agent-requests-resource.component.d.ts.map +1 -0
  28. package/dist/AI/components/requests/agent-requests-resource.component.js +547 -0
  29. package/dist/AI/components/requests/agent-requests-resource.component.js.map +1 -0
  30. package/dist/AI/components/system/system-config-filter-panel.component.js +2 -2
  31. package/dist/AI/components/system/system-configuration.component.js +2 -2
  32. package/dist/AI/components/widgets/kpi-card.component.js +7 -7
  33. package/dist/AI/components/widgets/kpi-card.component.js.map +1 -1
  34. package/dist/AI/components/widgets/live-execution-widget.component.d.ts.map +1 -1
  35. package/dist/AI/components/widgets/live-execution-widget.component.js +6 -6
  36. package/dist/AI/components/widgets/live-execution-widget.component.js.map +1 -1
  37. package/dist/AI/index.d.ts +1 -0
  38. package/dist/AI/index.d.ts.map +1 -1
  39. package/dist/AI/index.js +2 -0
  40. package/dist/AI/index.js.map +1 -1
  41. package/dist/APIKeys/api-applications-panel.component.js +3 -3
  42. package/dist/APIKeys/api-applications-panel.component.js.map +1 -1
  43. package/dist/APIKeys/api-key-create-dialog.component.js +3 -3
  44. package/dist/APIKeys/api-key-create-dialog.component.js.map +1 -1
  45. package/dist/APIKeys/api-key-edit-panel.component.js +1 -1
  46. package/dist/APIKeys/api-key-edit-panel.component.js.map +1 -1
  47. package/dist/APIKeys/api-key-list.component.js +3 -3
  48. package/dist/APIKeys/api-key-list.component.js.map +1 -1
  49. package/dist/APIKeys/api-keys-resource.component.js +1 -1
  50. package/dist/APIKeys/api-keys-resource.component.js.map +1 -1
  51. package/dist/APIKeys/api-scopes-panel.component.js +2 -2
  52. package/dist/APIKeys/api-usage-panel.component.js +2 -2
  53. package/dist/Actions/components/actions-overview.component.js +2 -2
  54. package/dist/Actions/components/execution-monitoring.component.js +2 -2
  55. package/dist/Actions/components/explorer/action-breadcrumb.component.js +2 -2
  56. package/dist/Actions/components/explorer/action-card.component.js +2 -2
  57. package/dist/Actions/components/explorer/action-explorer.component.js +2 -2
  58. package/dist/Actions/components/explorer/action-list-item.component.js +2 -2
  59. package/dist/Actions/components/explorer/action-toolbar.component.js +2 -2
  60. package/dist/Actions/components/explorer/action-tree-panel.component.js +2 -2
  61. package/dist/Actions/components/explorer/new-action-panel.component.js +2 -2
  62. package/dist/Actions/components/explorer/new-action-panel.component.js.map +1 -1
  63. package/dist/Actions/components/explorer/new-category-panel.component.js +2 -2
  64. package/dist/Actions/components/explorer/new-category-panel.component.js.map +1 -1
  65. package/dist/Communication/communication-dashboard.component.js +2 -2
  66. package/dist/Communication/communication-logs-resource.component.d.ts.map +1 -1
  67. package/dist/Communication/communication-logs-resource.component.js +3 -3
  68. package/dist/Communication/communication-logs-resource.component.js.map +1 -1
  69. package/dist/Communication/communication-monitor-resource.component.d.ts.map +1 -1
  70. package/dist/Communication/communication-monitor-resource.component.js +5 -5
  71. package/dist/Communication/communication-monitor-resource.component.js.map +1 -1
  72. package/dist/Communication/communication-providers-resource.component.d.ts.map +1 -1
  73. package/dist/Communication/communication-providers-resource.component.js +3 -3
  74. package/dist/Communication/communication-providers-resource.component.js.map +1 -1
  75. package/dist/Communication/communication-runs-resource.component.d.ts.map +1 -1
  76. package/dist/Communication/communication-runs-resource.component.js +3 -3
  77. package/dist/Communication/communication-runs-resource.component.js.map +1 -1
  78. package/dist/Communication/communication-templates-resource.component.js +2 -2
  79. package/dist/Communication/communication-templates-resource.component.js.map +1 -1
  80. package/dist/ComponentStudio/component-studio-dashboard.component.js +2 -2
  81. package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.js +2 -2
  82. package/dist/ComponentStudio/components/artifact-load-dialog.component.js +2 -2
  83. package/dist/ComponentStudio/components/artifact-selection-dialog.component.js +2 -2
  84. package/dist/ComponentStudio/components/browser/component-browser.component.js +2 -2
  85. package/dist/ComponentStudio/components/editors/code-editor-panel.component.js +2 -2
  86. package/dist/ComponentStudio/components/editors/code-editor-panel.component.js.map +1 -1
  87. package/dist/ComponentStudio/components/editors/data-requirements-editor.component.js +2 -2
  88. package/dist/ComponentStudio/components/editors/data-requirements-editor.component.js.map +1 -1
  89. package/dist/ComponentStudio/components/editors/requirements-editor.component.js +2 -2
  90. package/dist/ComponentStudio/components/editors/requirements-editor.component.js.map +1 -1
  91. package/dist/ComponentStudio/components/editors/spec-editor.component.js +2 -2
  92. package/dist/ComponentStudio/components/editors/spec-editor.component.js.map +1 -1
  93. package/dist/ComponentStudio/components/new-component-dialog/new-component-dialog.component.js +2 -2
  94. package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.js +2 -2
  95. package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.js.map +1 -1
  96. package/dist/ComponentStudio/components/text-import-dialog.component.js +2 -2
  97. package/dist/ComponentStudio/components/text-import-dialog.component.js.map +1 -1
  98. package/dist/ComponentStudio/components/workspace/component-preview.component.js +2 -2
  99. package/dist/ComponentStudio/components/workspace/editor-tabs.component.js +2 -2
  100. package/dist/ComponentStudio/components/workspace/editor-tabs.component.js.map +1 -1
  101. package/dist/Credentials/components/credentials-audit-resource.component.js +9 -9
  102. package/dist/Credentials/components/credentials-audit-resource.component.js.map +1 -1
  103. package/dist/Credentials/components/credentials-categories-resource.component.d.ts.map +1 -1
  104. package/dist/Credentials/components/credentials-categories-resource.component.js +11 -3
  105. package/dist/Credentials/components/credentials-categories-resource.component.js.map +1 -1
  106. package/dist/Credentials/components/credentials-list-resource.component.js +2 -2
  107. package/dist/Credentials/components/credentials-overview-resource.component.d.ts.map +1 -1
  108. package/dist/Credentials/components/credentials-overview-resource.component.js +12 -11
  109. package/dist/Credentials/components/credentials-overview-resource.component.js.map +1 -1
  110. package/dist/Credentials/components/credentials-types-resource.component.js +9 -9
  111. package/dist/Credentials/components/credentials-types-resource.component.js.map +1 -1
  112. package/dist/Credentials/credentials-dashboard.component.js +2 -2
  113. package/dist/DashboardBrowser/dashboard-browser-resource.component.js +2 -2
  114. package/dist/DashboardBrowser/dashboard-share-dialog.component.js +2 -2
  115. package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.js +2 -2
  116. package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.js +2 -2
  117. package/dist/DataExplorer/components/view-selector/view-selector.component.js +2 -2
  118. package/dist/DataExplorer/data-explorer-dashboard.component.js +4 -4
  119. package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
  120. package/dist/Home/home-dashboard.component.js +2 -2
  121. package/dist/Integration/components/activity/activity.component.d.ts +1 -1
  122. package/dist/Integration/components/activity/activity.component.d.ts.map +1 -1
  123. package/dist/Integration/components/activity/activity.component.js +5 -5
  124. package/dist/Integration/components/activity/activity.component.js.map +1 -1
  125. package/dist/Integration/components/connections/connections.component.d.ts +31 -2
  126. package/dist/Integration/components/connections/connections.component.d.ts.map +1 -1
  127. package/dist/Integration/components/connections/connections.component.js +753 -412
  128. package/dist/Integration/components/connections/connections.component.js.map +1 -1
  129. package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js +3 -3
  130. package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js.map +1 -1
  131. package/dist/Integration/components/overview/overview.component.d.ts +0 -1
  132. package/dist/Integration/components/overview/overview.component.d.ts.map +1 -1
  133. package/dist/Integration/components/overview/overview.component.js +3 -6
  134. package/dist/Integration/components/overview/overview.component.js.map +1 -1
  135. package/dist/Integration/components/pipelines/pipelines.component.js +3 -3
  136. package/dist/Integration/components/pipelines/pipelines.component.js.map +1 -1
  137. package/dist/Integration/components/schedules/schedules.component.d.ts +20 -0
  138. package/dist/Integration/components/schedules/schedules.component.d.ts.map +1 -1
  139. package/dist/Integration/components/schedules/schedules.component.js +97 -5
  140. package/dist/Integration/components/schedules/schedules.component.js.map +1 -1
  141. package/dist/Integration/components/visual-editor/visual-editor.component.js +2 -2
  142. package/dist/Integration/components/widgets/integration-card.component.d.ts.map +1 -1
  143. package/dist/Integration/components/widgets/integration-card.component.js +5 -1
  144. package/dist/Integration/components/widgets/integration-card.component.js.map +1 -1
  145. package/dist/Integration/components/widgets/run-history-panel.component.js +2 -2
  146. package/dist/Integration/components/widgets/run-history-panel.component.js.map +1 -1
  147. package/dist/Integration/integration.module.d.ts +2 -1
  148. package/dist/Integration/integration.module.d.ts.map +1 -1
  149. package/dist/Integration/integration.module.js +7 -3
  150. package/dist/Integration/integration.module.js.map +1 -1
  151. package/dist/Integration/services/integration-data.service.d.ts +27 -2
  152. package/dist/Integration/services/integration-data.service.d.ts.map +1 -1
  153. package/dist/Integration/services/integration-data.service.js +107 -4
  154. package/dist/Integration/services/integration-data.service.js.map +1 -1
  155. package/dist/Lists/components/lists-browse-resource.component.d.ts.map +1 -1
  156. package/dist/Lists/components/lists-browse-resource.component.js +25 -24
  157. package/dist/Lists/components/lists-browse-resource.component.js.map +1 -1
  158. package/dist/Lists/components/lists-categories-resource.component.js +2 -2
  159. package/dist/Lists/components/lists-categories-resource.component.js.map +1 -1
  160. package/dist/Lists/components/lists-my-lists-resource.component.d.ts.map +1 -1
  161. package/dist/Lists/components/lists-my-lists-resource.component.js +26 -25
  162. package/dist/Lists/components/lists-my-lists-resource.component.js.map +1 -1
  163. package/dist/Lists/components/lists-operations-resource.component.js +2 -2
  164. package/dist/Lists/components/lists-operations-resource.component.js.map +1 -1
  165. package/dist/Lists/components/venn-diagram/venn-diagram.component.js +3 -3
  166. package/dist/Lists/components/venn-diagram/venn-diagram.component.js.map +1 -1
  167. package/dist/MCP/components/mcp-connection-dialog.component.js +2 -2
  168. package/dist/MCP/components/mcp-log-detail-panel.component.js +2 -2
  169. package/dist/MCP/components/mcp-log-detail-panel.component.js.map +1 -1
  170. package/dist/MCP/components/mcp-server-dialog.component.js +2 -2
  171. package/dist/MCP/components/mcp-test-tool-dialog.component.js +2 -2
  172. package/dist/MCP/components/mcp-test-tool-dialog.component.js.map +1 -1
  173. package/dist/MCP/mcp-dashboard.component.js +2 -2
  174. package/dist/MCP/mcp-filter-panel.component.js +2 -2
  175. package/dist/QueryBrowser/query-browser-resource.component.js +7 -7
  176. package/dist/QueryBrowser/query-browser-resource.component.js.map +1 -1
  177. package/dist/Scheduling/components/index.d.ts +0 -1
  178. package/dist/Scheduling/components/index.d.ts.map +1 -1
  179. package/dist/Scheduling/components/index.js +0 -1
  180. package/dist/Scheduling/components/index.js.map +1 -1
  181. package/dist/Scheduling/components/scheduling-activity.component.js +2 -2
  182. package/dist/Scheduling/components/scheduling-jobs.component.d.ts +6 -9
  183. package/dist/Scheduling/components/scheduling-jobs.component.d.ts.map +1 -1
  184. package/dist/Scheduling/components/scheduling-jobs.component.js +118 -110
  185. package/dist/Scheduling/components/scheduling-jobs.component.js.map +1 -1
  186. package/dist/Scheduling/components/scheduling-overview.component.js +3 -3
  187. package/dist/Scheduling/components/scheduling-overview.component.js.map +1 -1
  188. package/dist/Scheduling/scheduling-dashboard.component.js +2 -2
  189. package/dist/SystemDiagnostics/system-diagnostics.component.js +4 -4
  190. package/dist/SystemDiagnostics/system-diagnostics.component.js.map +1 -1
  191. package/dist/Testing/components/testing-analytics.component.js +2 -2
  192. package/dist/Testing/components/testing-analytics.component.js.map +1 -1
  193. package/dist/Testing/components/testing-dashboard-tab.component.js +4 -4
  194. package/dist/Testing/components/testing-dashboard-tab.component.js.map +1 -1
  195. package/dist/Testing/components/testing-explorer.component.js +2 -2
  196. package/dist/Testing/components/testing-explorer.component.js.map +1 -1
  197. package/dist/Testing/components/testing-review.component.d.ts.map +1 -1
  198. package/dist/Testing/components/testing-review.component.js +5 -5
  199. package/dist/Testing/components/testing-review.component.js.map +1 -1
  200. package/dist/Testing/components/testing-runs.component.js +2 -2
  201. package/dist/Testing/components/testing-runs.component.js.map +1 -1
  202. package/dist/Testing/components/widgets/oracle-breakdown-table.component.js +2 -2
  203. package/dist/Testing/components/widgets/oracle-breakdown-table.component.js.map +1 -1
  204. package/dist/Testing/components/widgets/suite-tree.component.js +4 -4
  205. package/dist/Testing/components/widgets/suite-tree.component.js.map +1 -1
  206. package/dist/Testing/components/widgets/test-run-detail-panel.component.js +2 -2
  207. package/dist/Testing/components/widgets/test-run-detail-panel.component.js.map +1 -1
  208. package/dist/Testing/testing-dashboard.component.js +2 -2
  209. package/dist/VersionHistory/components/diff-resource.component.js +2 -2
  210. package/dist/VersionHistory/components/graph-resource.component.js +2 -2
  211. package/dist/VersionHistory/components/labels-resource.component.js +3 -3
  212. package/dist/VersionHistory/components/labels-resource.component.js.map +1 -1
  213. package/dist/VersionHistory/components/restore-resource.component.js +3 -3
  214. package/dist/VersionHistory/components/restore-resource.component.js.map +1 -1
  215. package/dist/__tests__/integration-data-service.test.js +1 -0
  216. package/dist/__tests__/integration-data-service.test.js.map +1 -1
  217. package/dist/module.d.ts +52 -49
  218. package/dist/module.d.ts.map +1 -1
  219. package/dist/module.js +25 -6
  220. package/dist/module.js.map +1 -1
  221. package/dist/public-api.d.ts +1 -1
  222. package/dist/public-api.d.ts.map +1 -1
  223. package/dist/public-api.js +1 -1
  224. package/dist/public-api.js.map +1 -1
  225. package/package.json +42 -40
  226. package/dist/Scheduling/components/job-slideout.component.d.ts +0 -45
  227. package/dist/Scheduling/components/job-slideout.component.d.ts.map +0 -1
  228. package/dist/Scheduling/components/job-slideout.component.js +0 -459
  229. package/dist/Scheduling/components/job-slideout.component.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"requirements-editor.component.js","sourceRoot":"","sources":["../../../../src/ComponentStudio/components/editors/requirements-editor.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';\nimport { Subscription } from 'rxjs';\nimport { ComponentStudioStateService } from '../../services/component-studio-state.service';\nimport { ComponentSpec } from '@memberjunction/interactive-component-types';\n\ntype RequirementsField = 'functionalRequirements' | 'technicalDesign';\ntype EditorMode = 'preview' | 'edit';\n\n@Component({\n standalone: false,\n selector: 'mj-requirements-editor',\n template: `\n <div class=\"requirements-editor\">\n <div class=\"editor-header\">\n <span class=\"header-title\">\n <i class=\"fa-solid\" [ngClass]=\"FieldIcon\"></i>\n {{ Title }}\n </span>\n <div class=\"header-right\">\n @if (IsEditing) {\n <div class=\"action-buttons\">\n <button kendoButton [themeColor]=\"'primary'\" (click)=\"ApplyChanges()\" class=\"action-btn\">\n <i class=\"fa-solid fa-check\"></i> Apply\n </button>\n <button kendoButton [themeColor]=\"'base'\" (click)=\"CancelChanges()\" class=\"action-btn\">\n Cancel\n </button>\n </div>\n }\n <div class=\"mode-toggle\">\n <button class=\"mode-btn\" [class.active]=\"ViewMode === 'preview'\" (click)=\"SetViewMode('preview')\">\n <i class=\"fa-solid fa-eye\"></i> Preview\n </button>\n <button class=\"mode-btn\" [class.active]=\"ViewMode === 'edit'\" (click)=\"SetViewMode('edit')\">\n <i class=\"fa-solid fa-pencil\"></i> Edit\n </button>\n </div>\n </div>\n </div>\n\n <div class=\"editor-body\">\n @if (State.SelectedComponent) {\n @if (ViewMode === 'preview') {\n <div class=\"preview-container\">\n @if (EditableContent) {\n <mj-markdown [data]=\"EditableContent\" [enableCodeCopy]=\"true\"></mj-markdown>\n } @else {\n <div class=\"empty-preview\">\n <i class=\"fa-solid fa-file-lines\"></i>\n <p>No {{ Title | lowercase }} defined yet.</p>\n <button class=\"edit-link\" (click)=\"SetViewMode('edit')\">\n <i class=\"fa-solid fa-pencil\"></i> Start writing\n </button>\n </div>\n }\n </div>\n } @else {\n <div class=\"code-editor-container\">\n <mj-code-editor\n [(ngModel)]=\"EditableContent\"\n [language]=\"'markdown'\"\n [indentWithTab]=\"true\"\n [placeholder]=\"'Enter ' + Title + ' in markdown format...'\"\n (ngModelChange)=\"OnContentChanged()\">\n </mj-code-editor>\n </div>\n }\n } @else {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-file-lines\"></i>\n <p>Select a component to view its {{ Title | lowercase }}.</p>\n </div>\n }\n </div>\n </div>\n `,\n styles: [`\n .requirements-editor {\n display: flex;\n flex-direction: column;\n height: 100%;\n }\n\n .editor-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 8px 12px;\n border-bottom: 1px solid var(--mat-sys-outline-variant);\n background: var(--mat-sys-surface);\n flex-shrink: 0;\n gap: 8px;\n }\n\n .header-title {\n font-weight: 600;\n font-size: 13px;\n color: var(--mat-sys-on-surface);\n white-space: nowrap;\n }\n\n .header-title i {\n margin-right: 6px;\n color: var(--mat-sys-primary);\n }\n\n .header-right {\n display: flex;\n align-items: center;\n gap: 8px;\n }\n\n .action-buttons {\n display: flex;\n gap: 6px;\n }\n\n .action-btn {\n font-size: 12px;\n }\n\n .mode-toggle {\n display: inline-flex;\n border: 1px solid var(--mat-sys-outline);\n border-radius: 8px;\n overflow: hidden;\n }\n\n .mode-btn {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 10px;\n border: none;\n background: transparent;\n color: var(--mat-sys-on-surface-variant);\n font-size: 11px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n font-family: inherit;\n }\n\n .mode-btn:not(:last-child) {\n border-right: 1px solid var(--mat-sys-outline);\n }\n\n .mode-btn:hover {\n background: var(--mat-sys-surface-container);\n }\n\n .mode-btn.active {\n background: var(--mat-sys-primary);\n color: var(--mat-sys-on-primary, #fff);\n }\n\n .mode-btn i {\n font-size: 10px;\n }\n\n .editor-body {\n flex: 1;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n }\n\n .preview-container {\n flex: 1;\n overflow: auto;\n padding: 16px 20px;\n }\n\n .code-editor-container {\n flex: 1;\n overflow: hidden;\n }\n\n .code-editor-container mj-code-editor {\n display: block;\n height: 100%;\n }\n\n .empty-preview {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 20px;\n color: var(--mat-sys-on-surface-variant);\n }\n\n .empty-preview i {\n font-size: 32px;\n margin-bottom: 12px;\n opacity: 0.4;\n }\n\n .empty-preview p {\n margin: 0 0 12px;\n font-size: 13px;\n }\n\n .edit-link {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 6px 14px;\n border: 1px solid var(--mat-sys-outline);\n border-radius: 8px;\n background: transparent;\n color: var(--mat-sys-primary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n font-family: inherit;\n }\n\n .edit-link:hover {\n background: var(--mat-sys-primary-container, #e0e7ff);\n }\n\n .empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 20px;\n color: var(--mat-sys-on-surface-variant);\n flex: 1;\n }\n\n .empty-state i {\n font-size: 32px;\n margin-bottom: 12px;\n opacity: 0.4;\n }\n\n .empty-state p {\n margin: 0;\n font-size: 13px;\n text-align: center;\n }\n `]\n})\nexport class RequirementsEditorComponent implements OnInit, OnDestroy {\n @Input() Field: RequirementsField = 'functionalRequirements';\n @Input() Title: string = 'Functional Requirements';\n\n EditableContent: string = '';\n IsEditing: boolean = false;\n ViewMode: EditorMode = 'preview';\n\n private stateChangedSub: Subscription | null = null;\n\n constructor(\n public State: ComponentStudioStateService,\n private cdr: ChangeDetectorRef\n ) {}\n\n get FieldIcon(): string {\n return this.Field === 'functionalRequirements' ? 'fa-clipboard-list' : 'fa-drafting-compass';\n }\n\n ngOnInit(): void {\n this.loadContent();\n this.stateChangedSub = this.State.StateChanged.subscribe(() => {\n if (!this.IsEditing) {\n this.loadContent();\n }\n this.cdr.detectChanges();\n });\n }\n\n ngOnDestroy(): void {\n if (this.stateChangedSub) {\n this.stateChangedSub.unsubscribe();\n this.stateChangedSub = null;\n }\n }\n\n SetViewMode(mode: EditorMode): void {\n this.ViewMode = mode;\n this.cdr.detectChanges();\n }\n\n OnContentChanged(): void {\n this.IsEditing = true;\n }\n\n ApplyChanges(): void {\n try {\n const spec: ComponentSpec = JSON.parse(this.State.EditableSpec);\n spec[this.Field] = this.EditableContent;\n this.State.UpdateSpec(spec);\n this.IsEditing = false;\n this.ViewMode = 'preview';\n } catch (error) {\n console.error('Error applying requirements changes:', error);\n }\n }\n\n CancelChanges(): void {\n this.loadContent();\n this.IsEditing = false;\n this.ViewMode = 'preview';\n this.cdr.detectChanges();\n }\n\n private loadContent(): void {\n try {\n const spec = JSON.parse(this.State.EditableSpec);\n this.EditableContent = spec[this.Field] || '';\n } catch {\n this.EditableContent = '';\n }\n }\n}\n"]}
1
+ {"version":3,"file":"requirements-editor.component.js","sourceRoot":"","sources":["../../../../src/ComponentStudio/components/editors/requirements-editor.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';\nimport { Subscription } from 'rxjs';\nimport { ComponentStudioStateService } from '../../services/component-studio-state.service';\nimport { ComponentSpec } from '@memberjunction/interactive-component-types';\n\ntype RequirementsField = 'functionalRequirements' | 'technicalDesign';\ntype EditorMode = 'preview' | 'edit';\n\n@Component({\n standalone: false,\n selector: 'mj-requirements-editor',\n template: `\n <div class=\"requirements-editor\">\n <div class=\"editor-header\">\n <span class=\"header-title\">\n <i class=\"fa-solid\" [ngClass]=\"FieldIcon\"></i>\n {{ Title }}\n </span>\n <div class=\"header-right\">\n @if (IsEditing) {\n <div class=\"action-buttons\">\n <button kendoButton [themeColor]=\"'primary'\" (click)=\"ApplyChanges()\" class=\"action-btn\">\n <i class=\"fa-solid fa-check\"></i> Apply\n </button>\n <button kendoButton [themeColor]=\"'base'\" (click)=\"CancelChanges()\" class=\"action-btn\">\n Cancel\n </button>\n </div>\n }\n <div class=\"mode-toggle\">\n <button class=\"mode-btn\" [class.active]=\"ViewMode === 'preview'\" (click)=\"SetViewMode('preview')\">\n <i class=\"fa-solid fa-eye\"></i> Preview\n </button>\n <button class=\"mode-btn\" [class.active]=\"ViewMode === 'edit'\" (click)=\"SetViewMode('edit')\">\n <i class=\"fa-solid fa-pencil\"></i> Edit\n </button>\n </div>\n </div>\n </div>\n\n <div class=\"editor-body\">\n @if (State.SelectedComponent) {\n @if (ViewMode === 'preview') {\n <div class=\"preview-container\">\n @if (EditableContent) {\n <mj-markdown [data]=\"EditableContent\" [enableCodeCopy]=\"true\"></mj-markdown>\n } @else {\n <div class=\"empty-preview\">\n <i class=\"fa-solid fa-file-lines\"></i>\n <p>No {{ Title | lowercase }} defined yet.</p>\n <button class=\"edit-link\" (click)=\"SetViewMode('edit')\">\n <i class=\"fa-solid fa-pencil\"></i> Start writing\n </button>\n </div>\n }\n </div>\n } @else {\n <div class=\"code-editor-container\">\n <mj-code-editor\n [(ngModel)]=\"EditableContent\"\n [language]=\"'markdown'\"\n [indentWithTab]=\"true\"\n [placeholder]=\"'Enter ' + Title + ' in markdown format...'\"\n (ngModelChange)=\"OnContentChanged()\">\n </mj-code-editor>\n </div>\n }\n } @else {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-file-lines\"></i>\n <p>Select a component to view its {{ Title | lowercase }}.</p>\n </div>\n }\n </div>\n </div>\n `,\n styles: [`\n .requirements-editor {\n display: flex;\n flex-direction: column;\n height: 100%;\n }\n\n .editor-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 8px 12px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n flex-shrink: 0;\n gap: 8px;\n }\n\n .header-title {\n font-weight: 600;\n font-size: 13px;\n color: var(--mj-text-primary);\n white-space: nowrap;\n }\n\n .header-title i {\n margin-right: 6px;\n color: var(--mj-brand-primary);\n }\n\n .header-right {\n display: flex;\n align-items: center;\n gap: 8px;\n }\n\n .action-buttons {\n display: flex;\n gap: 6px;\n }\n\n .action-btn {\n font-size: 12px;\n }\n\n .mode-toggle {\n display: inline-flex;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n }\n\n .mode-btn {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 10px;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 11px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n font-family: inherit;\n }\n\n .mode-btn:not(:last-child) {\n border-right: 1px solid var(--mj-border-default);\n }\n\n .mode-btn:hover {\n background: var(--mj-bg-surface-sunken);\n }\n\n .mode-btn.active {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n }\n\n .mode-btn i {\n font-size: 10px;\n }\n\n .editor-body {\n flex: 1;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n }\n\n .preview-container {\n flex: 1;\n overflow: auto;\n padding: 16px 20px;\n }\n\n .code-editor-container {\n flex: 1;\n overflow: hidden;\n }\n\n .code-editor-container mj-code-editor {\n display: block;\n height: 100%;\n }\n\n .empty-preview {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 20px;\n color: var(--mj-text-secondary);\n }\n\n .empty-preview i {\n font-size: 32px;\n margin-bottom: 12px;\n opacity: 0.4;\n }\n\n .empty-preview p {\n margin: 0 0 12px;\n font-size: 13px;\n }\n\n .edit-link {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 6px 14px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: transparent;\n color: var(--mj-brand-primary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n font-family: inherit;\n }\n\n .edit-link:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n }\n\n .empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 20px;\n color: var(--mj-text-secondary);\n flex: 1;\n }\n\n .empty-state i {\n font-size: 32px;\n margin-bottom: 12px;\n opacity: 0.4;\n }\n\n .empty-state p {\n margin: 0;\n font-size: 13px;\n text-align: center;\n }\n `]\n})\nexport class RequirementsEditorComponent implements OnInit, OnDestroy {\n @Input() Field: RequirementsField = 'functionalRequirements';\n @Input() Title: string = 'Functional Requirements';\n\n EditableContent: string = '';\n IsEditing: boolean = false;\n ViewMode: EditorMode = 'preview';\n\n private stateChangedSub: Subscription | null = null;\n\n constructor(\n public State: ComponentStudioStateService,\n private cdr: ChangeDetectorRef\n ) {}\n\n get FieldIcon(): string {\n return this.Field === 'functionalRequirements' ? 'fa-clipboard-list' : 'fa-drafting-compass';\n }\n\n ngOnInit(): void {\n this.loadContent();\n this.stateChangedSub = this.State.StateChanged.subscribe(() => {\n if (!this.IsEditing) {\n this.loadContent();\n }\n this.cdr.detectChanges();\n });\n }\n\n ngOnDestroy(): void {\n if (this.stateChangedSub) {\n this.stateChangedSub.unsubscribe();\n this.stateChangedSub = null;\n }\n }\n\n SetViewMode(mode: EditorMode): void {\n this.ViewMode = mode;\n this.cdr.detectChanges();\n }\n\n OnContentChanged(): void {\n this.IsEditing = true;\n }\n\n ApplyChanges(): void {\n try {\n const spec: ComponentSpec = JSON.parse(this.State.EditableSpec);\n spec[this.Field] = this.EditableContent;\n this.State.UpdateSpec(spec);\n this.IsEditing = false;\n this.ViewMode = 'preview';\n } catch (error) {\n console.error('Error applying requirements changes:', error);\n }\n }\n\n CancelChanges(): void {\n this.loadContent();\n this.IsEditing = false;\n this.ViewMode = 'preview';\n this.cdr.detectChanges();\n }\n\n private loadContent(): void {\n try {\n const spec = JSON.parse(this.State.EditableSpec);\n this.EditableContent = spec[this.Field] || '';\n } catch {\n this.EditableContent = '';\n }\n }\n}\n"]}
@@ -223,7 +223,7 @@ export class SpecEditorComponent {
223
223
  i0.ɵɵconditional(ctx.State.IsEditingSpec ? 9 : -1);
224
224
  i0.ɵɵadvance(2);
225
225
  i0.ɵɵconditional(ctx.Mode === "form" ? 11 : 12);
226
- } }, dependencies: [i2.NgSelectOption, i2.ɵNgSelectMultipleOption, i2.DefaultValueAccessor, i2.SelectControlValueAccessor, i2.NgControlStatus, i2.NgModel, i3.CodeEditorComponent, i4.ButtonComponent], styles: [".spec-editor[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n }\n\n .editor-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 8px 12px;\n border-bottom: 1px solid var(--mat-sys-outline-variant);\n background: var(--mat-sys-surface);\n flex-shrink: 0;\n }\n\n .mode-toggle[_ngcontent-%COMP%] {\n display: inline-flex;\n border: 1px solid var(--mat-sys-outline);\n border-radius: 8px;\n overflow: hidden;\n }\n\n .mode-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 12px;\n border: none;\n background: transparent;\n color: var(--mat-sys-on-surface-variant);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n font-family: inherit;\n }\n\n .mode-btn[_ngcontent-%COMP%]:not(:last-child) {\n border-right: 1px solid var(--mat-sys-outline);\n }\n\n .mode-btn[_ngcontent-%COMP%]:hover {\n background: var(--mat-sys-surface-container);\n }\n\n .mode-btn.active[_ngcontent-%COMP%] {\n background: var(--mat-sys-primary);\n color: var(--mat-sys-on-primary, #fff);\n }\n\n .mode-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n }\n\n .action-buttons[_ngcontent-%COMP%] {\n display: flex;\n gap: 6px;\n }\n\n .action-btn[_ngcontent-%COMP%] {\n font-size: 12px;\n }\n\n .editor-body[_ngcontent-%COMP%] {\n flex: 1;\n overflow: auto;\n }\n\n .form-mode[_ngcontent-%COMP%] {\n padding: 16px;\n display: flex;\n flex-direction: column;\n gap: 14px;\n }\n\n .form-field[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 4px;\n flex: 1;\n }\n\n .form-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n color: var(--mat-sys-on-surface-variant);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n }\n\n .form-input[_ngcontent-%COMP%] {\n padding: 8px 12px;\n border: 1px solid var(--mat-sys-outline);\n border-radius: 6px;\n background: var(--mat-sys-surface);\n color: var(--mat-sys-on-surface);\n font-size: 13px;\n font-family: inherit;\n outline: none;\n transition: border-color 0.15s ease;\n }\n\n .form-input[_ngcontent-%COMP%]:focus {\n border-color: var(--mat-sys-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mat-sys-primary) 15%, transparent);\n }\n\n .form-textarea[_ngcontent-%COMP%] {\n padding: 8px 12px;\n border: 1px solid var(--mat-sys-outline);\n border-radius: 6px;\n background: var(--mat-sys-surface);\n color: var(--mat-sys-on-surface);\n font-size: 13px;\n font-family: inherit;\n resize: vertical;\n min-height: 60px;\n outline: none;\n transition: border-color 0.15s ease;\n }\n\n .form-textarea[_ngcontent-%COMP%]:focus {\n border-color: var(--mat-sys-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mat-sys-primary) 15%, transparent);\n }\n\n .form-select[_ngcontent-%COMP%] {\n padding: 8px 12px;\n border: 1px solid var(--mat-sys-outline);\n border-radius: 6px;\n background: var(--mat-sys-surface);\n color: var(--mat-sys-on-surface);\n font-size: 13px;\n font-family: inherit;\n outline: none;\n cursor: pointer;\n transition: border-color 0.15s ease;\n }\n\n .form-select[_ngcontent-%COMP%]:focus {\n border-color: var(--mat-sys-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mat-sys-primary) 15%, transparent);\n }\n\n .form-row[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 12px;\n }\n\n .json-mode[_ngcontent-%COMP%] {\n height: 100%;\n }\n\n .json-mode[_ngcontent-%COMP%] mj-code-editor[_ngcontent-%COMP%] {\n display: block;\n height: 100%;\n }"] });
226
+ } }, dependencies: [i2.NgSelectOption, i2.ɵNgSelectMultipleOption, i2.DefaultValueAccessor, i2.SelectControlValueAccessor, i2.NgControlStatus, i2.NgModel, i3.CodeEditorComponent, i4.ButtonComponent], styles: [".spec-editor[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n }\n\n .editor-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 8px 12px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n flex-shrink: 0;\n }\n\n .mode-toggle[_ngcontent-%COMP%] {\n display: inline-flex;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n }\n\n .mode-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 12px;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n font-family: inherit;\n }\n\n .mode-btn[_ngcontent-%COMP%]:not(:last-child) {\n border-right: 1px solid var(--mj-border-default);\n }\n\n .mode-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n }\n\n .mode-btn.active[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n }\n\n .mode-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n }\n\n .action-buttons[_ngcontent-%COMP%] {\n display: flex;\n gap: 6px;\n }\n\n .action-btn[_ngcontent-%COMP%] {\n font-size: 12px;\n }\n\n .editor-body[_ngcontent-%COMP%] {\n flex: 1;\n overflow: auto;\n }\n\n .form-mode[_ngcontent-%COMP%] {\n padding: 16px;\n display: flex;\n flex-direction: column;\n gap: 14px;\n }\n\n .form-field[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 4px;\n flex: 1;\n }\n\n .form-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n }\n\n .form-input[_ngcontent-%COMP%] {\n padding: 8px 12px;\n border: 1px solid var(--mj-border-strong);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n font-family: inherit;\n outline: none;\n transition: border-color 0.15s ease;\n }\n\n .form-input[_ngcontent-%COMP%]:focus {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n }\n\n .form-textarea[_ngcontent-%COMP%] {\n padding: 8px 12px;\n border: 1px solid var(--mj-border-strong);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n font-family: inherit;\n resize: vertical;\n min-height: 60px;\n outline: none;\n transition: border-color 0.15s ease;\n }\n\n .form-textarea[_ngcontent-%COMP%]:focus {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n }\n\n .form-select[_ngcontent-%COMP%] {\n padding: 8px 12px;\n border: 1px solid var(--mj-border-strong);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n font-family: inherit;\n outline: none;\n cursor: pointer;\n transition: border-color 0.15s ease;\n }\n\n .form-select[_ngcontent-%COMP%]:focus {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n }\n\n .form-row[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 12px;\n }\n\n .json-mode[_ngcontent-%COMP%] {\n height: 100%;\n }\n\n .json-mode[_ngcontent-%COMP%] mj-code-editor[_ngcontent-%COMP%] {\n display: block;\n height: 100%;\n }"] });
227
227
  }
228
228
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SpecEditorComponent, [{
229
229
  type: Component,
@@ -301,7 +301,7 @@ export class SpecEditorComponent {
301
301
  }
302
302
  </div>
303
303
  </div>
304
- `, styles: ["\n .spec-editor {\n display: flex;\n flex-direction: column;\n height: 100%;\n }\n\n .editor-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 8px 12px;\n border-bottom: 1px solid var(--mat-sys-outline-variant);\n background: var(--mat-sys-surface);\n flex-shrink: 0;\n }\n\n .mode-toggle {\n display: inline-flex;\n border: 1px solid var(--mat-sys-outline);\n border-radius: 8px;\n overflow: hidden;\n }\n\n .mode-btn {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 12px;\n border: none;\n background: transparent;\n color: var(--mat-sys-on-surface-variant);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n font-family: inherit;\n }\n\n .mode-btn:not(:last-child) {\n border-right: 1px solid var(--mat-sys-outline);\n }\n\n .mode-btn:hover {\n background: var(--mat-sys-surface-container);\n }\n\n .mode-btn.active {\n background: var(--mat-sys-primary);\n color: var(--mat-sys-on-primary, #fff);\n }\n\n .mode-btn i {\n font-size: 11px;\n }\n\n .action-buttons {\n display: flex;\n gap: 6px;\n }\n\n .action-btn {\n font-size: 12px;\n }\n\n .editor-body {\n flex: 1;\n overflow: auto;\n }\n\n .form-mode {\n padding: 16px;\n display: flex;\n flex-direction: column;\n gap: 14px;\n }\n\n .form-field {\n display: flex;\n flex-direction: column;\n gap: 4px;\n flex: 1;\n }\n\n .form-label {\n font-size: 11px;\n font-weight: 600;\n color: var(--mat-sys-on-surface-variant);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n }\n\n .form-input {\n padding: 8px 12px;\n border: 1px solid var(--mat-sys-outline);\n border-radius: 6px;\n background: var(--mat-sys-surface);\n color: var(--mat-sys-on-surface);\n font-size: 13px;\n font-family: inherit;\n outline: none;\n transition: border-color 0.15s ease;\n }\n\n .form-input:focus {\n border-color: var(--mat-sys-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mat-sys-primary) 15%, transparent);\n }\n\n .form-textarea {\n padding: 8px 12px;\n border: 1px solid var(--mat-sys-outline);\n border-radius: 6px;\n background: var(--mat-sys-surface);\n color: var(--mat-sys-on-surface);\n font-size: 13px;\n font-family: inherit;\n resize: vertical;\n min-height: 60px;\n outline: none;\n transition: border-color 0.15s ease;\n }\n\n .form-textarea:focus {\n border-color: var(--mat-sys-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mat-sys-primary) 15%, transparent);\n }\n\n .form-select {\n padding: 8px 12px;\n border: 1px solid var(--mat-sys-outline);\n border-radius: 6px;\n background: var(--mat-sys-surface);\n color: var(--mat-sys-on-surface);\n font-size: 13px;\n font-family: inherit;\n outline: none;\n cursor: pointer;\n transition: border-color 0.15s ease;\n }\n\n .form-select:focus {\n border-color: var(--mat-sys-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mat-sys-primary) 15%, transparent);\n }\n\n .form-row {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 12px;\n }\n\n .json-mode {\n height: 100%;\n }\n\n .json-mode mj-code-editor {\n display: block;\n height: 100%;\n }\n "] }]
304
+ `, styles: ["\n .spec-editor {\n display: flex;\n flex-direction: column;\n height: 100%;\n }\n\n .editor-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 8px 12px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n flex-shrink: 0;\n }\n\n .mode-toggle {\n display: inline-flex;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n }\n\n .mode-btn {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 12px;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n font-family: inherit;\n }\n\n .mode-btn:not(:last-child) {\n border-right: 1px solid var(--mj-border-default);\n }\n\n .mode-btn:hover {\n background: var(--mj-bg-surface-sunken);\n }\n\n .mode-btn.active {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n }\n\n .mode-btn i {\n font-size: 11px;\n }\n\n .action-buttons {\n display: flex;\n gap: 6px;\n }\n\n .action-btn {\n font-size: 12px;\n }\n\n .editor-body {\n flex: 1;\n overflow: auto;\n }\n\n .form-mode {\n padding: 16px;\n display: flex;\n flex-direction: column;\n gap: 14px;\n }\n\n .form-field {\n display: flex;\n flex-direction: column;\n gap: 4px;\n flex: 1;\n }\n\n .form-label {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n }\n\n .form-input {\n padding: 8px 12px;\n border: 1px solid var(--mj-border-strong);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n font-family: inherit;\n outline: none;\n transition: border-color 0.15s ease;\n }\n\n .form-input:focus {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n }\n\n .form-textarea {\n padding: 8px 12px;\n border: 1px solid var(--mj-border-strong);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n font-family: inherit;\n resize: vertical;\n min-height: 60px;\n outline: none;\n transition: border-color 0.15s ease;\n }\n\n .form-textarea:focus {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n }\n\n .form-select {\n padding: 8px 12px;\n border: 1px solid var(--mj-border-strong);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n font-family: inherit;\n outline: none;\n cursor: pointer;\n transition: border-color 0.15s ease;\n }\n\n .form-select:focus {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n }\n\n .form-row {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 12px;\n }\n\n .json-mode {\n height: 100%;\n }\n\n .json-mode mj-code-editor {\n display: block;\n height: 100%;\n }\n "] }]
305
305
  }], () => [{ type: i1.ComponentStudioStateService }, { type: i0.ChangeDetectorRef }], null); })();
306
306
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(SpecEditorComponent, { className: "SpecEditorComponent", filePath: "src/ComponentStudio/components/editors/spec-editor.component.ts", lineNumber: 260 }); })();
307
307
  //# sourceMappingURL=spec-editor.component.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"spec-editor.component.js","sourceRoot":"","sources":["../../../../src/ComponentStudio/components/editors/spec-editor.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';\nimport { Subscription } from 'rxjs';\nimport { ComponentStudioStateService } from '../../services/component-studio-state.service';\n\ntype SpecEditorMode = 'form' | 'json';\n\ninterface SpecFormModel {\n name: string;\n title: string;\n description: string;\n type: string;\n location: string;\n exampleUsage: string;\n}\n\nconst COMPONENT_TYPES = [\n 'Report', 'Dashboard', 'Form', 'Chart', 'Table', 'Widget', 'Navigation', 'Search', 'Utility'\n];\n\n@Component({\n standalone: false,\n selector: 'mj-spec-editor',\n template: `\n <div class=\"spec-editor\">\n <div class=\"editor-header\">\n <div class=\"mode-toggle\">\n <button class=\"mode-btn\" [class.active]=\"Mode === 'form'\" (click)=\"SetMode('form')\">\n <i class=\"fa-solid fa-wpforms\"></i> Form\n </button>\n <button class=\"mode-btn\" [class.active]=\"Mode === 'json'\" (click)=\"SetMode('json')\">\n <i class=\"fa-solid fa-code\"></i> JSON\n </button>\n </div>\n @if (State.IsEditingSpec) {\n <div class=\"action-buttons\">\n <button kendoButton [themeColor]=\"'primary'\" (click)=\"ApplyChanges()\" class=\"action-btn\">\n <i class=\"fa-solid fa-check\"></i> Apply\n </button>\n <button kendoButton [themeColor]=\"'base'\" (click)=\"CancelChanges()\" class=\"action-btn\">\n Cancel\n </button>\n </div>\n }\n </div>\n\n <div class=\"editor-body\">\n @if (Mode === 'form') {\n <div class=\"form-mode\">\n <div class=\"form-row\">\n <div class=\"form-field\">\n <label class=\"form-label\">Name</label>\n <input class=\"form-input\" [(ngModel)]=\"FormModel.name\" (ngModelChange)=\"OnFormChanged()\" />\n </div>\n <div class=\"form-field\">\n <label class=\"form-label\">Type</label>\n <select class=\"form-select\" [(ngModel)]=\"FormModel.type\" (ngModelChange)=\"OnFormChanged()\">\n @for (t of ComponentTypes; track t) {\n <option [value]=\"t\">{{ t }}</option>\n }\n </select>\n </div>\n </div>\n <div class=\"form-field\">\n <label class=\"form-label\">Title</label>\n <input class=\"form-input\" [(ngModel)]=\"FormModel.title\" (ngModelChange)=\"OnFormChanged()\" />\n </div>\n <div class=\"form-field\">\n <label class=\"form-label\">Description</label>\n <textarea class=\"form-textarea\" [(ngModel)]=\"FormModel.description\" (ngModelChange)=\"OnFormChanged()\" rows=\"3\"></textarea>\n </div>\n <div class=\"form-row\">\n <div class=\"form-field\">\n <label class=\"form-label\">Location</label>\n <select class=\"form-select\" [(ngModel)]=\"FormModel.location\" (ngModelChange)=\"OnFormChanged()\">\n <option value=\"embedded\">embedded</option>\n <option value=\"standalone\">standalone</option>\n </select>\n </div>\n <div class=\"form-field\">\n <label class=\"form-label\">Example Usage</label>\n <input class=\"form-input\" [(ngModel)]=\"FormModel.exampleUsage\" (ngModelChange)=\"OnFormChanged()\" placeholder=\"Optional\" />\n </div>\n </div>\n </div>\n } @else {\n <div class=\"json-mode\">\n <mj-code-editor\n [(ngModel)]=\"State.EditableSpec\"\n [language]=\"'json'\"\n [indentWithTab]=\"true\"\n (ngModelChange)=\"OnJsonChanged()\">\n </mj-code-editor>\n </div>\n }\n </div>\n </div>\n `,\n styles: [`\n .spec-editor {\n display: flex;\n flex-direction: column;\n height: 100%;\n }\n\n .editor-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 8px 12px;\n border-bottom: 1px solid var(--mat-sys-outline-variant);\n background: var(--mat-sys-surface);\n flex-shrink: 0;\n }\n\n .mode-toggle {\n display: inline-flex;\n border: 1px solid var(--mat-sys-outline);\n border-radius: 8px;\n overflow: hidden;\n }\n\n .mode-btn {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 12px;\n border: none;\n background: transparent;\n color: var(--mat-sys-on-surface-variant);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n font-family: inherit;\n }\n\n .mode-btn:not(:last-child) {\n border-right: 1px solid var(--mat-sys-outline);\n }\n\n .mode-btn:hover {\n background: var(--mat-sys-surface-container);\n }\n\n .mode-btn.active {\n background: var(--mat-sys-primary);\n color: var(--mat-sys-on-primary, #fff);\n }\n\n .mode-btn i {\n font-size: 11px;\n }\n\n .action-buttons {\n display: flex;\n gap: 6px;\n }\n\n .action-btn {\n font-size: 12px;\n }\n\n .editor-body {\n flex: 1;\n overflow: auto;\n }\n\n .form-mode {\n padding: 16px;\n display: flex;\n flex-direction: column;\n gap: 14px;\n }\n\n .form-field {\n display: flex;\n flex-direction: column;\n gap: 4px;\n flex: 1;\n }\n\n .form-label {\n font-size: 11px;\n font-weight: 600;\n color: var(--mat-sys-on-surface-variant);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n }\n\n .form-input {\n padding: 8px 12px;\n border: 1px solid var(--mat-sys-outline);\n border-radius: 6px;\n background: var(--mat-sys-surface);\n color: var(--mat-sys-on-surface);\n font-size: 13px;\n font-family: inherit;\n outline: none;\n transition: border-color 0.15s ease;\n }\n\n .form-input:focus {\n border-color: var(--mat-sys-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mat-sys-primary) 15%, transparent);\n }\n\n .form-textarea {\n padding: 8px 12px;\n border: 1px solid var(--mat-sys-outline);\n border-radius: 6px;\n background: var(--mat-sys-surface);\n color: var(--mat-sys-on-surface);\n font-size: 13px;\n font-family: inherit;\n resize: vertical;\n min-height: 60px;\n outline: none;\n transition: border-color 0.15s ease;\n }\n\n .form-textarea:focus {\n border-color: var(--mat-sys-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mat-sys-primary) 15%, transparent);\n }\n\n .form-select {\n padding: 8px 12px;\n border: 1px solid var(--mat-sys-outline);\n border-radius: 6px;\n background: var(--mat-sys-surface);\n color: var(--mat-sys-on-surface);\n font-size: 13px;\n font-family: inherit;\n outline: none;\n cursor: pointer;\n transition: border-color 0.15s ease;\n }\n\n .form-select:focus {\n border-color: var(--mat-sys-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mat-sys-primary) 15%, transparent);\n }\n\n .form-row {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 12px;\n }\n\n .json-mode {\n height: 100%;\n }\n\n .json-mode mj-code-editor {\n display: block;\n height: 100%;\n }\n `]\n})\nexport class SpecEditorComponent implements OnInit, OnDestroy {\n Mode: SpecEditorMode = 'form';\n FormModel: SpecFormModel = { name: '', title: '', description: '', type: '', location: '', exampleUsage: '' };\n ComponentTypes: string[] = COMPONENT_TYPES;\n\n private stateChangedSub: Subscription | null = null;\n\n constructor(\n public State: ComponentStudioStateService,\n private cdr: ChangeDetectorRef\n ) {}\n\n ngOnInit(): void {\n this.syncSpecToForm();\n this.stateChangedSub = this.State.StateChanged.subscribe(() => {\n if (this.Mode === 'form' && !this.State.IsEditingSpec) {\n this.syncSpecToForm();\n }\n this.cdr.detectChanges();\n });\n }\n\n ngOnDestroy(): void {\n if (this.stateChangedSub) {\n this.stateChangedSub.unsubscribe();\n this.stateChangedSub = null;\n }\n }\n\n SetMode(mode: SpecEditorMode): void {\n if (mode === 'form') {\n this.syncSpecToForm();\n } else {\n this.syncFormToSpec();\n }\n this.Mode = mode;\n }\n\n OnFormChanged(): void {\n this.syncFormToSpec();\n this.State.IsEditingSpec = true;\n }\n\n OnJsonChanged(): void {\n this.State.IsEditingSpec = true;\n }\n\n ApplyChanges(): void {\n if (this.Mode === 'form') {\n this.syncFormToSpec();\n }\n this.State.ApplySpecChanges();\n }\n\n CancelChanges(): void {\n this.State.InitializeEditors();\n this.syncSpecToForm();\n this.cdr.detectChanges();\n }\n\n private syncSpecToForm(): void {\n try {\n const spec = JSON.parse(this.State.EditableSpec);\n this.FormModel = {\n name: spec.name || '',\n title: spec.title || '',\n description: spec.description || '',\n type: spec.type || '',\n location: spec.location || '',\n exampleUsage: spec.exampleUsage || ''\n };\n } catch {\n // If JSON is invalid, keep current form values\n }\n }\n\n private syncFormToSpec(): void {\n try {\n const spec = JSON.parse(this.State.EditableSpec);\n spec.name = this.FormModel.name;\n spec.title = this.FormModel.title;\n spec.description = this.FormModel.description;\n spec.type = this.FormModel.type;\n spec.location = this.FormModel.location;\n spec.exampleUsage = this.FormModel.exampleUsage;\n this.State.EditableSpec = JSON.stringify(spec, null, 2);\n } catch {\n // If JSON is invalid, skip sync\n }\n }\n}\n"]}
1
+ {"version":3,"file":"spec-editor.component.js","sourceRoot":"","sources":["../../../../src/ComponentStudio/components/editors/spec-editor.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';\nimport { Subscription } from 'rxjs';\nimport { ComponentStudioStateService } from '../../services/component-studio-state.service';\n\ntype SpecEditorMode = 'form' | 'json';\n\ninterface SpecFormModel {\n name: string;\n title: string;\n description: string;\n type: string;\n location: string;\n exampleUsage: string;\n}\n\nconst COMPONENT_TYPES = [\n 'Report', 'Dashboard', 'Form', 'Chart', 'Table', 'Widget', 'Navigation', 'Search', 'Utility'\n];\n\n@Component({\n standalone: false,\n selector: 'mj-spec-editor',\n template: `\n <div class=\"spec-editor\">\n <div class=\"editor-header\">\n <div class=\"mode-toggle\">\n <button class=\"mode-btn\" [class.active]=\"Mode === 'form'\" (click)=\"SetMode('form')\">\n <i class=\"fa-solid fa-wpforms\"></i> Form\n </button>\n <button class=\"mode-btn\" [class.active]=\"Mode === 'json'\" (click)=\"SetMode('json')\">\n <i class=\"fa-solid fa-code\"></i> JSON\n </button>\n </div>\n @if (State.IsEditingSpec) {\n <div class=\"action-buttons\">\n <button kendoButton [themeColor]=\"'primary'\" (click)=\"ApplyChanges()\" class=\"action-btn\">\n <i class=\"fa-solid fa-check\"></i> Apply\n </button>\n <button kendoButton [themeColor]=\"'base'\" (click)=\"CancelChanges()\" class=\"action-btn\">\n Cancel\n </button>\n </div>\n }\n </div>\n\n <div class=\"editor-body\">\n @if (Mode === 'form') {\n <div class=\"form-mode\">\n <div class=\"form-row\">\n <div class=\"form-field\">\n <label class=\"form-label\">Name</label>\n <input class=\"form-input\" [(ngModel)]=\"FormModel.name\" (ngModelChange)=\"OnFormChanged()\" />\n </div>\n <div class=\"form-field\">\n <label class=\"form-label\">Type</label>\n <select class=\"form-select\" [(ngModel)]=\"FormModel.type\" (ngModelChange)=\"OnFormChanged()\">\n @for (t of ComponentTypes; track t) {\n <option [value]=\"t\">{{ t }}</option>\n }\n </select>\n </div>\n </div>\n <div class=\"form-field\">\n <label class=\"form-label\">Title</label>\n <input class=\"form-input\" [(ngModel)]=\"FormModel.title\" (ngModelChange)=\"OnFormChanged()\" />\n </div>\n <div class=\"form-field\">\n <label class=\"form-label\">Description</label>\n <textarea class=\"form-textarea\" [(ngModel)]=\"FormModel.description\" (ngModelChange)=\"OnFormChanged()\" rows=\"3\"></textarea>\n </div>\n <div class=\"form-row\">\n <div class=\"form-field\">\n <label class=\"form-label\">Location</label>\n <select class=\"form-select\" [(ngModel)]=\"FormModel.location\" (ngModelChange)=\"OnFormChanged()\">\n <option value=\"embedded\">embedded</option>\n <option value=\"standalone\">standalone</option>\n </select>\n </div>\n <div class=\"form-field\">\n <label class=\"form-label\">Example Usage</label>\n <input class=\"form-input\" [(ngModel)]=\"FormModel.exampleUsage\" (ngModelChange)=\"OnFormChanged()\" placeholder=\"Optional\" />\n </div>\n </div>\n </div>\n } @else {\n <div class=\"json-mode\">\n <mj-code-editor\n [(ngModel)]=\"State.EditableSpec\"\n [language]=\"'json'\"\n [indentWithTab]=\"true\"\n (ngModelChange)=\"OnJsonChanged()\">\n </mj-code-editor>\n </div>\n }\n </div>\n </div>\n `,\n styles: [`\n .spec-editor {\n display: flex;\n flex-direction: column;\n height: 100%;\n }\n\n .editor-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 8px 12px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n flex-shrink: 0;\n }\n\n .mode-toggle {\n display: inline-flex;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n }\n\n .mode-btn {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 12px;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n font-family: inherit;\n }\n\n .mode-btn:not(:last-child) {\n border-right: 1px solid var(--mj-border-default);\n }\n\n .mode-btn:hover {\n background: var(--mj-bg-surface-sunken);\n }\n\n .mode-btn.active {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n }\n\n .mode-btn i {\n font-size: 11px;\n }\n\n .action-buttons {\n display: flex;\n gap: 6px;\n }\n\n .action-btn {\n font-size: 12px;\n }\n\n .editor-body {\n flex: 1;\n overflow: auto;\n }\n\n .form-mode {\n padding: 16px;\n display: flex;\n flex-direction: column;\n gap: 14px;\n }\n\n .form-field {\n display: flex;\n flex-direction: column;\n gap: 4px;\n flex: 1;\n }\n\n .form-label {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n }\n\n .form-input {\n padding: 8px 12px;\n border: 1px solid var(--mj-border-strong);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n font-family: inherit;\n outline: none;\n transition: border-color 0.15s ease;\n }\n\n .form-input:focus {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n }\n\n .form-textarea {\n padding: 8px 12px;\n border: 1px solid var(--mj-border-strong);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n font-family: inherit;\n resize: vertical;\n min-height: 60px;\n outline: none;\n transition: border-color 0.15s ease;\n }\n\n .form-textarea:focus {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n }\n\n .form-select {\n padding: 8px 12px;\n border: 1px solid var(--mj-border-strong);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n font-family: inherit;\n outline: none;\n cursor: pointer;\n transition: border-color 0.15s ease;\n }\n\n .form-select:focus {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n }\n\n .form-row {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 12px;\n }\n\n .json-mode {\n height: 100%;\n }\n\n .json-mode mj-code-editor {\n display: block;\n height: 100%;\n }\n `]\n})\nexport class SpecEditorComponent implements OnInit, OnDestroy {\n Mode: SpecEditorMode = 'form';\n FormModel: SpecFormModel = { name: '', title: '', description: '', type: '', location: '', exampleUsage: '' };\n ComponentTypes: string[] = COMPONENT_TYPES;\n\n private stateChangedSub: Subscription | null = null;\n\n constructor(\n public State: ComponentStudioStateService,\n private cdr: ChangeDetectorRef\n ) {}\n\n ngOnInit(): void {\n this.syncSpecToForm();\n this.stateChangedSub = this.State.StateChanged.subscribe(() => {\n if (this.Mode === 'form' && !this.State.IsEditingSpec) {\n this.syncSpecToForm();\n }\n this.cdr.detectChanges();\n });\n }\n\n ngOnDestroy(): void {\n if (this.stateChangedSub) {\n this.stateChangedSub.unsubscribe();\n this.stateChangedSub = null;\n }\n }\n\n SetMode(mode: SpecEditorMode): void {\n if (mode === 'form') {\n this.syncSpecToForm();\n } else {\n this.syncFormToSpec();\n }\n this.Mode = mode;\n }\n\n OnFormChanged(): void {\n this.syncFormToSpec();\n this.State.IsEditingSpec = true;\n }\n\n OnJsonChanged(): void {\n this.State.IsEditingSpec = true;\n }\n\n ApplyChanges(): void {\n if (this.Mode === 'form') {\n this.syncFormToSpec();\n }\n this.State.ApplySpecChanges();\n }\n\n CancelChanges(): void {\n this.State.InitializeEditors();\n this.syncSpecToForm();\n this.cdr.detectChanges();\n }\n\n private syncSpecToForm(): void {\n try {\n const spec = JSON.parse(this.State.EditableSpec);\n this.FormModel = {\n name: spec.name || '',\n title: spec.title || '',\n description: spec.description || '',\n type: spec.type || '',\n location: spec.location || '',\n exampleUsage: spec.exampleUsage || ''\n };\n } catch {\n // If JSON is invalid, keep current form values\n }\n }\n\n private syncFormToSpec(): void {\n try {\n const spec = JSON.parse(this.State.EditableSpec);\n spec.name = this.FormModel.name;\n spec.title = this.FormModel.title;\n spec.description = this.FormModel.description;\n spec.type = this.FormModel.type;\n spec.location = this.FormModel.location;\n spec.exampleUsage = this.FormModel.exampleUsage;\n this.State.EditableSpec = JSON.stringify(spec, null, 2);\n } catch {\n // If JSON is invalid, skip sync\n }\n }\n}\n"]}
@@ -145,11 +145,11 @@ export class NewComponentDialogComponent {
145
145
  i0.ɵɵconditionalCreate(0, NewComponentDialogComponent_Conditional_0_Template, 35, 6, "kendo-dialog", 0);
146
146
  } if (rf & 2) {
147
147
  i0.ɵɵconditional(ctx.Visible ? 0 : -1);
148
- } }, dependencies: [i1.ɵNgNoValidate, i1.DefaultValueAccessor, i1.NgControlStatus, i1.NgControlStatusGroup, i1.FormGroupDirective, i1.FormControlName, i2.DialogComponent, i2.DialogActionsComponent, i3.ButtonComponent], styles: ["\n\n.dialog-form[_ngcontent-%COMP%] {\n padding: 16px 8px;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n\n\n.form-field[_ngcontent-%COMP%] {\n margin-bottom: 16px;\n}\n\n\n\n.form-label[_ngcontent-%COMP%] {\n display: block;\n font-size: 12px;\n font-weight: 600;\n color: var(--mat-sys-on-surface-variant, #49454f);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 6px;\n}\n\n.form-label[_ngcontent-%COMP%] .required[_ngcontent-%COMP%] {\n color: var(--mat-sys-error, #b3261e);\n margin-left: 2px;\n}\n\n\n\n.form-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 10px 12px;\n font-size: 14px;\n font-family: inherit;\n color: var(--mat-sys-on-surface, #1d1b20);\n background: var(--mat-sys-surface-container-lowest, #ffffff);\n border: 1px solid var(--mat-sys-outline-variant, #cac4d0);\n border-radius: 6px;\n outline: none;\n transition: border-color 0.2s ease, box-shadow 0.2s ease;\n box-sizing: border-box;\n}\n\n.form-input[_ngcontent-%COMP%]:focus {\n border-color: var(--mat-sys-primary, #6750a4);\n box-shadow: 0 0 0 2px rgba(103, 80, 164, 0.15);\n}\n\n.form-input[_ngcontent-%COMP%]::placeholder {\n color: var(--mat-sys-on-surface-variant, #49454f);\n opacity: 0.6;\n}\n\n\n\n.form-textarea[_ngcontent-%COMP%] {\n width: 100%;\n padding: 10px 12px;\n font-size: 14px;\n font-family: inherit;\n color: var(--mat-sys-on-surface, #1d1b20);\n background: var(--mat-sys-surface-container-lowest, #ffffff);\n border: 1px solid var(--mat-sys-outline-variant, #cac4d0);\n border-radius: 6px;\n outline: none;\n transition: border-color 0.2s ease, box-shadow 0.2s ease;\n box-sizing: border-box;\n resize: vertical;\n min-height: 72px;\n}\n\n.form-textarea[_ngcontent-%COMP%]:focus {\n border-color: var(--mat-sys-primary, #6750a4);\n box-shadow: 0 0 0 2px rgba(103, 80, 164, 0.15);\n}\n\n.form-textarea[_ngcontent-%COMP%]::placeholder {\n color: var(--mat-sys-on-surface-variant, #49454f);\n opacity: 0.6;\n}\n\n\n\n.form-hint[_ngcontent-%COMP%] {\n display: block;\n font-size: 11px;\n color: var(--mat-sys-on-surface-variant, #49454f);\n margin-top: 4px;\n opacity: 0.7;\n}\n\n\n\n.type-options[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 10px;\n}\n\n\n\n.type-card[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 14px 10px 12px;\n border: 1.5px solid var(--mat-sys-outline-variant, #cac4d0);\n border-radius: 10px;\n background: var(--mat-sys-surface-container-lowest, #ffffff);\n cursor: pointer;\n transition: border-color 0.2s ease, background 0.2s ease, box-shadow 0.2s ease;\n text-align: center;\n user-select: none;\n}\n\n.type-card[_ngcontent-%COMP%]:hover {\n border-color: var(--mat-sys-primary, #6750a4);\n background: var(--mat-sys-surface-container-low, #f7f2fa);\n}\n\n.type-card.selected[_ngcontent-%COMP%] {\n border-color: var(--mat-sys-primary, #6750a4);\n background: var(--mat-sys-primary-container, #eaddff);\n box-shadow: 0 0 0 2px rgba(103, 80, 164, 0.2);\n}\n\n\n\n.type-card-icon[_ngcontent-%COMP%] {\n font-size: 22px;\n color: var(--mat-sys-on-surface-variant, #49454f);\n margin-bottom: 6px;\n transition: color 0.2s ease;\n}\n\n.type-card.selected[_ngcontent-%COMP%] .type-card-icon[_ngcontent-%COMP%] {\n color: var(--mat-sys-on-primary-container, #21005d);\n}\n\n\n\n.type-card-label[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n color: var(--mat-sys-on-surface, #1d1b20);\n margin-bottom: 2px;\n}\n\n.type-card.selected[_ngcontent-%COMP%] .type-card-label[_ngcontent-%COMP%] {\n color: var(--mat-sys-on-primary-container, #21005d);\n}\n\n\n\n.type-card-description[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mat-sys-on-surface-variant, #49454f);\n line-height: 1.3;\n}\n\n.type-card.selected[_ngcontent-%COMP%] .type-card-description[_ngcontent-%COMP%] {\n color: var(--mat-sys-on-primary-container, #21005d);\n opacity: 0.8;\n}"] });
148
+ } }, dependencies: [i1.ɵNgNoValidate, i1.DefaultValueAccessor, i1.NgControlStatus, i1.NgControlStatusGroup, i1.FormGroupDirective, i1.FormControlName, i2.DialogComponent, i2.DialogActionsComponent, i3.ButtonComponent], styles: ["\n\n.dialog-form[_ngcontent-%COMP%] {\n padding: 16px 8px;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n\n\n.form-field[_ngcontent-%COMP%] {\n margin-bottom: 16px;\n}\n\n\n\n.form-label[_ngcontent-%COMP%] {\n display: block;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 6px;\n}\n\n.form-label[_ngcontent-%COMP%] .required[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n margin-left: 2px;\n}\n\n\n\n.form-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 10px 12px;\n font-size: 14px;\n font-family: inherit;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: 6px;\n outline: none;\n transition: border-color 0.2s ease, box-shadow 0.2s ease;\n box-sizing: border-box;\n}\n\n.form-input[_ngcontent-%COMP%]:focus {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.form-input[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-secondary);\n opacity: 0.6;\n}\n\n\n\n.form-textarea[_ngcontent-%COMP%] {\n width: 100%;\n padding: 10px 12px;\n font-size: 14px;\n font-family: inherit;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: 6px;\n outline: none;\n transition: border-color 0.2s ease, box-shadow 0.2s ease;\n box-sizing: border-box;\n resize: vertical;\n min-height: 72px;\n}\n\n.form-textarea[_ngcontent-%COMP%]:focus {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.form-textarea[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-secondary);\n opacity: 0.6;\n}\n\n\n\n.form-hint[_ngcontent-%COMP%] {\n display: block;\n font-size: 11px;\n color: var(--mj-text-secondary);\n margin-top: 4px;\n opacity: 0.7;\n}\n\n\n\n.type-options[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 10px;\n}\n\n\n\n.type-card[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 14px 10px 12px;\n border: 1.5px solid var(--mj-border-default);\n border-radius: 10px;\n background: var(--mj-bg-surface);\n cursor: pointer;\n transition: border-color 0.2s ease, background 0.2s ease, box-shadow 0.2s ease;\n text-align: center;\n user-select: none;\n}\n\n.type-card[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface-sunken);\n}\n\n.type-card.selected[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n}\n\n\n\n.type-card-icon[_ngcontent-%COMP%] {\n font-size: 22px;\n color: var(--mj-text-secondary);\n margin-bottom: 6px;\n transition: color 0.2s ease;\n}\n\n.type-card.selected[_ngcontent-%COMP%] .type-card-icon[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n\n\n.type-card-label[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin-bottom: 2px;\n}\n\n.type-card.selected[_ngcontent-%COMP%] .type-card-label[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n\n\n.type-card-description[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-secondary);\n line-height: 1.3;\n}\n\n.type-card.selected[_ngcontent-%COMP%] .type-card-description[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n opacity: 0.8;\n}"] });
149
149
  }
150
150
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(NewComponentDialogComponent, [{
151
151
  type: Component,
152
- args: [{ standalone: false, selector: 'mj-new-component-dialog', template: "@if (Visible) {\n <kendo-dialog [title]=\"'Create New Component'\" (close)=\"OnCancel()\" [width]=\"520\" [minWidth]=\"400\">\n <form [formGroup]=\"form\">\n <div class=\"dialog-form\">\n <!-- Name field (required) -->\n <div class=\"form-field\">\n <label class=\"form-label\" for=\"component-name\">Name <span class=\"required\">*</span></label>\n <input\n id=\"component-name\"\n class=\"form-input\"\n type=\"text\"\n formControlName=\"name\"\n (input)=\"OnNameChange()\"\n placeholder=\"e.g. Sales Overview Dashboard\"\n autocomplete=\"off\">\n <span class=\"form-hint\">A unique name for your component</span>\n </div>\n\n <!-- Type selection (card grid) -->\n <div class=\"form-field\">\n <label class=\"form-label\">Type</label>\n <div class=\"type-options\">\n @for (option of TypeOptions; track option.value) {\n <div\n class=\"type-card\"\n [class.selected]=\"SelectedType === option.value\"\n (click)=\"OnSelectType(option.value)\">\n <div class=\"type-card-icon\">\n <i [class]=\"option.icon\"></i>\n </div>\n <div class=\"type-card-label\">{{ option.label }}</div>\n <div class=\"type-card-description\">{{ option.description }}</div>\n </div>\n }\n </div>\n </div>\n\n <!-- Title field (auto-filled from name) -->\n <div class=\"form-field\">\n <label class=\"form-label\" for=\"component-title\">Title</label>\n <input\n id=\"component-title\"\n class=\"form-input\"\n type=\"text\"\n formControlName=\"title\"\n placeholder=\"Display title (auto-filled from name)\"\n autocomplete=\"off\">\n <span class=\"form-hint\">The display title shown in the component header</span>\n </div>\n\n <!-- Description (optional textarea) -->\n <div class=\"form-field\">\n <label class=\"form-label\" for=\"component-description\">Description</label>\n <textarea\n id=\"component-description\"\n class=\"form-textarea\"\n formControlName=\"description\"\n placeholder=\"Describe what this component does...\"\n rows=\"3\"></textarea>\n <span class=\"form-hint\">Optional description of the component's purpose</span>\n </div>\n </div>\n </form>\n\n <kendo-dialog-actions>\n <button kendoButton (click)=\"OnCreate()\" [themeColor]=\"'primary'\" [disabled]=\"!form.valid\">\n <span class=\"fa-solid fa-plus\"></span> Create\n </button>\n <button kendoButton (click)=\"OnCancel()\">Cancel</button>\n </kendo-dialog-actions>\n </kendo-dialog>\n}\n", styles: ["/* Dialog form container */\n.dialog-form {\n padding: 16px 8px;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n/* Form field wrapper */\n.form-field {\n margin-bottom: 16px;\n}\n\n/* Form label */\n.form-label {\n display: block;\n font-size: 12px;\n font-weight: 600;\n color: var(--mat-sys-on-surface-variant, #49454f);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 6px;\n}\n\n.form-label .required {\n color: var(--mat-sys-error, #b3261e);\n margin-left: 2px;\n}\n\n/* Text inputs */\n.form-input {\n width: 100%;\n padding: 10px 12px;\n font-size: 14px;\n font-family: inherit;\n color: var(--mat-sys-on-surface, #1d1b20);\n background: var(--mat-sys-surface-container-lowest, #ffffff);\n border: 1px solid var(--mat-sys-outline-variant, #cac4d0);\n border-radius: 6px;\n outline: none;\n transition: border-color 0.2s ease, box-shadow 0.2s ease;\n box-sizing: border-box;\n}\n\n.form-input:focus {\n border-color: var(--mat-sys-primary, #6750a4);\n box-shadow: 0 0 0 2px rgba(103, 80, 164, 0.15);\n}\n\n.form-input::placeholder {\n color: var(--mat-sys-on-surface-variant, #49454f);\n opacity: 0.6;\n}\n\n/* Textarea */\n.form-textarea {\n width: 100%;\n padding: 10px 12px;\n font-size: 14px;\n font-family: inherit;\n color: var(--mat-sys-on-surface, #1d1b20);\n background: var(--mat-sys-surface-container-lowest, #ffffff);\n border: 1px solid var(--mat-sys-outline-variant, #cac4d0);\n border-radius: 6px;\n outline: none;\n transition: border-color 0.2s ease, box-shadow 0.2s ease;\n box-sizing: border-box;\n resize: vertical;\n min-height: 72px;\n}\n\n.form-textarea:focus {\n border-color: var(--mat-sys-primary, #6750a4);\n box-shadow: 0 0 0 2px rgba(103, 80, 164, 0.15);\n}\n\n.form-textarea::placeholder {\n color: var(--mat-sys-on-surface-variant, #49454f);\n opacity: 0.6;\n}\n\n/* Helper text */\n.form-hint {\n display: block;\n font-size: 11px;\n color: var(--mat-sys-on-surface-variant, #49454f);\n margin-top: 4px;\n opacity: 0.7;\n}\n\n/* Type selection grid */\n.type-options {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 10px;\n}\n\n/* Type card */\n.type-card {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 14px 10px 12px;\n border: 1.5px solid var(--mat-sys-outline-variant, #cac4d0);\n border-radius: 10px;\n background: var(--mat-sys-surface-container-lowest, #ffffff);\n cursor: pointer;\n transition: border-color 0.2s ease, background 0.2s ease, box-shadow 0.2s ease;\n text-align: center;\n user-select: none;\n}\n\n.type-card:hover {\n border-color: var(--mat-sys-primary, #6750a4);\n background: var(--mat-sys-surface-container-low, #f7f2fa);\n}\n\n.type-card.selected {\n border-color: var(--mat-sys-primary, #6750a4);\n background: var(--mat-sys-primary-container, #eaddff);\n box-shadow: 0 0 0 2px rgba(103, 80, 164, 0.2);\n}\n\n/* Type card icon */\n.type-card-icon {\n font-size: 22px;\n color: var(--mat-sys-on-surface-variant, #49454f);\n margin-bottom: 6px;\n transition: color 0.2s ease;\n}\n\n.type-card.selected .type-card-icon {\n color: var(--mat-sys-on-primary-container, #21005d);\n}\n\n/* Type card label */\n.type-card-label {\n font-size: 13px;\n font-weight: 600;\n color: var(--mat-sys-on-surface, #1d1b20);\n margin-bottom: 2px;\n}\n\n.type-card.selected .type-card-label {\n color: var(--mat-sys-on-primary-container, #21005d);\n}\n\n/* Type card description */\n.type-card-description {\n font-size: 11px;\n color: var(--mat-sys-on-surface-variant, #49454f);\n line-height: 1.3;\n}\n\n.type-card.selected .type-card-description {\n color: var(--mat-sys-on-primary-container, #21005d);\n opacity: 0.8;\n}\n"] }]
152
+ args: [{ standalone: false, selector: 'mj-new-component-dialog', template: "@if (Visible) {\n <kendo-dialog [title]=\"'Create New Component'\" (close)=\"OnCancel()\" [width]=\"520\" [minWidth]=\"400\">\n <form [formGroup]=\"form\">\n <div class=\"dialog-form\">\n <!-- Name field (required) -->\n <div class=\"form-field\">\n <label class=\"form-label\" for=\"component-name\">Name <span class=\"required\">*</span></label>\n <input\n id=\"component-name\"\n class=\"form-input\"\n type=\"text\"\n formControlName=\"name\"\n (input)=\"OnNameChange()\"\n placeholder=\"e.g. Sales Overview Dashboard\"\n autocomplete=\"off\">\n <span class=\"form-hint\">A unique name for your component</span>\n </div>\n\n <!-- Type selection (card grid) -->\n <div class=\"form-field\">\n <label class=\"form-label\">Type</label>\n <div class=\"type-options\">\n @for (option of TypeOptions; track option.value) {\n <div\n class=\"type-card\"\n [class.selected]=\"SelectedType === option.value\"\n (click)=\"OnSelectType(option.value)\">\n <div class=\"type-card-icon\">\n <i [class]=\"option.icon\"></i>\n </div>\n <div class=\"type-card-label\">{{ option.label }}</div>\n <div class=\"type-card-description\">{{ option.description }}</div>\n </div>\n }\n </div>\n </div>\n\n <!-- Title field (auto-filled from name) -->\n <div class=\"form-field\">\n <label class=\"form-label\" for=\"component-title\">Title</label>\n <input\n id=\"component-title\"\n class=\"form-input\"\n type=\"text\"\n formControlName=\"title\"\n placeholder=\"Display title (auto-filled from name)\"\n autocomplete=\"off\">\n <span class=\"form-hint\">The display title shown in the component header</span>\n </div>\n\n <!-- Description (optional textarea) -->\n <div class=\"form-field\">\n <label class=\"form-label\" for=\"component-description\">Description</label>\n <textarea\n id=\"component-description\"\n class=\"form-textarea\"\n formControlName=\"description\"\n placeholder=\"Describe what this component does...\"\n rows=\"3\"></textarea>\n <span class=\"form-hint\">Optional description of the component's purpose</span>\n </div>\n </div>\n </form>\n\n <kendo-dialog-actions>\n <button kendoButton (click)=\"OnCreate()\" [themeColor]=\"'primary'\" [disabled]=\"!form.valid\">\n <span class=\"fa-solid fa-plus\"></span> Create\n </button>\n <button kendoButton (click)=\"OnCancel()\">Cancel</button>\n </kendo-dialog-actions>\n </kendo-dialog>\n}\n", styles: ["/* Dialog form container */\n.dialog-form {\n padding: 16px 8px;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n/* Form field wrapper */\n.form-field {\n margin-bottom: 16px;\n}\n\n/* Form label */\n.form-label {\n display: block;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 6px;\n}\n\n.form-label .required {\n color: var(--mj-status-error);\n margin-left: 2px;\n}\n\n/* Text inputs */\n.form-input {\n width: 100%;\n padding: 10px 12px;\n font-size: 14px;\n font-family: inherit;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: 6px;\n outline: none;\n transition: border-color 0.2s ease, box-shadow 0.2s ease;\n box-sizing: border-box;\n}\n\n.form-input:focus {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.form-input::placeholder {\n color: var(--mj-text-secondary);\n opacity: 0.6;\n}\n\n/* Textarea */\n.form-textarea {\n width: 100%;\n padding: 10px 12px;\n font-size: 14px;\n font-family: inherit;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: 6px;\n outline: none;\n transition: border-color 0.2s ease, box-shadow 0.2s ease;\n box-sizing: border-box;\n resize: vertical;\n min-height: 72px;\n}\n\n.form-textarea:focus {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.form-textarea::placeholder {\n color: var(--mj-text-secondary);\n opacity: 0.6;\n}\n\n/* Helper text */\n.form-hint {\n display: block;\n font-size: 11px;\n color: var(--mj-text-secondary);\n margin-top: 4px;\n opacity: 0.7;\n}\n\n/* Type selection grid */\n.type-options {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 10px;\n}\n\n/* Type card */\n.type-card {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 14px 10px 12px;\n border: 1.5px solid var(--mj-border-default);\n border-radius: 10px;\n background: var(--mj-bg-surface);\n cursor: pointer;\n transition: border-color 0.2s ease, background 0.2s ease, box-shadow 0.2s ease;\n text-align: center;\n user-select: none;\n}\n\n.type-card:hover {\n border-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface-sunken);\n}\n\n.type-card.selected {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n}\n\n/* Type card icon */\n.type-card-icon {\n font-size: 22px;\n color: var(--mj-text-secondary);\n margin-bottom: 6px;\n transition: color 0.2s ease;\n}\n\n.type-card.selected .type-card-icon {\n color: var(--mj-brand-primary);\n}\n\n/* Type card label */\n.type-card-label {\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin-bottom: 2px;\n}\n\n.type-card.selected .type-card-label {\n color: var(--mj-brand-primary);\n}\n\n/* Type card description */\n.type-card-description {\n font-size: 11px;\n color: var(--mj-text-secondary);\n line-height: 1.3;\n}\n\n.type-card.selected .type-card-description {\n color: var(--mj-brand-primary);\n opacity: 0.8;\n}\n"] }]
153
153
  }], () => [{ type: i1.FormBuilder }], { Visible: [{
154
154
  type: Input
155
155
  }], Close: [{
@@ -118,7 +118,7 @@ export class SaveVersionDialogComponent {
118
118
  i0.ɵɵconditionalCreate(0, SaveVersionDialogComponent_Conditional_0_Template, 16, 7, "kendo-dialog", 0);
119
119
  } if (rf & 2) {
120
120
  i0.ɵɵconditional(ctx.Visible ? 0 : -1);
121
- } }, dependencies: [i1.DefaultValueAccessor, i1.RadioControlValueAccessor, i1.NgControlStatus, i1.NgModel, i2.TextBoxDirective, i3.DialogComponent, i3.DialogActionsComponent, i4.ButtonComponent], styles: [".dialog-body[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 16px;\n padding: 4px 0;\n }\n\n .version-context[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n }\n\n .version-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 3px 10px;\n border-radius: 12px;\n font-size: 12px;\n font-weight: 600;\n background: var(--mat-sys-primary-container, #e0e7ff);\n color: var(--mat-sys-on-primary-container, #1e1b4b);\n }\n\n .new-badge[_ngcontent-%COMP%] {\n background: var(--mat-sys-tertiary-container, #f3e8ff);\n color: var(--mat-sys-on-tertiary-container, #4a1d96);\n }\n\n .form-field[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n }\n\n .field-label[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 500;\n color: var(--mat-sys-on-surface, #1f2937);\n }\n\n .comment-input[_ngcontent-%COMP%] {\n width: 100%;\n }\n\n .save-mode[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n }\n\n .radio-option[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 10px 12px;\n border: 1px solid var(--mat-sys-outline-variant, #d1d5db);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.15s ease;\n }\n\n .radio-option[_ngcontent-%COMP%]:hover {\n background: var(--mat-sys-surface-container, #f3f4f6);\n }\n\n .radio-option.selected[_ngcontent-%COMP%] {\n border-color: var(--mat-sys-primary, #6366f1);\n background: var(--mat-sys-primary-container, #e0e7ff);\n }\n\n .radio-option[_ngcontent-%COMP%] input[type=\"radio\"][_ngcontent-%COMP%] {\n margin-top: 2px;\n accent-color: var(--mat-sys-primary, #6366f1);\n }\n\n .radio-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n }\n\n .radio-label[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 500;\n color: var(--mat-sys-on-surface, #1f2937);\n }\n\n .radio-desc[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mat-sys-on-surface-variant, #6b7280);\n }"] });
121
+ } }, dependencies: [i1.DefaultValueAccessor, i1.RadioControlValueAccessor, i1.NgControlStatus, i1.NgModel, i2.TextBoxDirective, i3.DialogComponent, i3.DialogActionsComponent, i4.ButtonComponent], styles: [".dialog-body[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 16px;\n padding: 4px 0;\n }\n\n .version-context[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n }\n\n .version-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 3px 10px;\n border-radius: 12px;\n font-size: 12px;\n font-weight: 600;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n }\n\n .new-badge[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n }\n\n .form-field[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n }\n\n .field-label[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-primary);\n }\n\n .comment-input[_ngcontent-%COMP%] {\n width: 100%;\n }\n\n .save-mode[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n }\n\n .radio-option[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 10px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.15s ease;\n }\n\n .radio-option[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n }\n\n .radio-option.selected[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n }\n\n .radio-option[_ngcontent-%COMP%] input[type=\"radio\"][_ngcontent-%COMP%] {\n margin-top: 2px;\n accent-color: var(--mj-brand-primary);\n }\n\n .radio-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n }\n\n .radio-label[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-primary);\n }\n\n .radio-desc[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-secondary);\n }"] });
122
122
  }
123
123
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SaveVersionDialogComponent, [{
124
124
  type: Component,
@@ -178,7 +178,7 @@ export class SaveVersionDialogComponent {
178
178
  </kendo-dialog-actions>
179
179
  </kendo-dialog>
180
180
  }
181
- `, styles: ["\n .dialog-body {\n display: flex;\n flex-direction: column;\n gap: 16px;\n padding: 4px 0;\n }\n\n .version-context {\n display: flex;\n align-items: center;\n }\n\n .version-badge {\n display: inline-flex;\n align-items: center;\n padding: 3px 10px;\n border-radius: 12px;\n font-size: 12px;\n font-weight: 600;\n background: var(--mat-sys-primary-container, #e0e7ff);\n color: var(--mat-sys-on-primary-container, #1e1b4b);\n }\n\n .new-badge {\n background: var(--mat-sys-tertiary-container, #f3e8ff);\n color: var(--mat-sys-on-tertiary-container, #4a1d96);\n }\n\n .form-field {\n display: flex;\n flex-direction: column;\n gap: 6px;\n }\n\n .field-label {\n font-size: 13px;\n font-weight: 500;\n color: var(--mat-sys-on-surface, #1f2937);\n }\n\n .comment-input {\n width: 100%;\n }\n\n .save-mode {\n display: flex;\n flex-direction: column;\n gap: 8px;\n }\n\n .radio-option {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 10px 12px;\n border: 1px solid var(--mat-sys-outline-variant, #d1d5db);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.15s ease;\n }\n\n .radio-option:hover {\n background: var(--mat-sys-surface-container, #f3f4f6);\n }\n\n .radio-option.selected {\n border-color: var(--mat-sys-primary, #6366f1);\n background: var(--mat-sys-primary-container, #e0e7ff);\n }\n\n .radio-option input[type=\"radio\"] {\n margin-top: 2px;\n accent-color: var(--mat-sys-primary, #6366f1);\n }\n\n .radio-content {\n display: flex;\n flex-direction: column;\n gap: 2px;\n }\n\n .radio-label {\n font-size: 13px;\n font-weight: 500;\n color: var(--mat-sys-on-surface, #1f2937);\n }\n\n .radio-desc {\n font-size: 11px;\n color: var(--mat-sys-on-surface-variant, #6b7280);\n }\n "] }]
181
+ `, styles: ["\n .dialog-body {\n display: flex;\n flex-direction: column;\n gap: 16px;\n padding: 4px 0;\n }\n\n .version-context {\n display: flex;\n align-items: center;\n }\n\n .version-badge {\n display: inline-flex;\n align-items: center;\n padding: 3px 10px;\n border-radius: 12px;\n font-size: 12px;\n font-weight: 600;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n }\n\n .new-badge {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n }\n\n .form-field {\n display: flex;\n flex-direction: column;\n gap: 6px;\n }\n\n .field-label {\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-primary);\n }\n\n .comment-input {\n width: 100%;\n }\n\n .save-mode {\n display: flex;\n flex-direction: column;\n gap: 8px;\n }\n\n .radio-option {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 10px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.15s ease;\n }\n\n .radio-option:hover {\n background: var(--mj-bg-surface-sunken);\n }\n\n .radio-option.selected {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n }\n\n .radio-option input[type=\"radio\"] {\n margin-top: 2px;\n accent-color: var(--mj-brand-primary);\n }\n\n .radio-content {\n display: flex;\n flex-direction: column;\n gap: 2px;\n }\n\n .radio-label {\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-primary);\n }\n\n .radio-desc {\n font-size: 11px;\n color: var(--mj-text-secondary);\n }\n "] }]
182
182
  }], null, { Visible: [{
183
183
  type: Input
184
184
  }], CurrentVersion: [{
@@ -1 +1 @@
1
- {"version":3,"file":"save-version-dialog.component.js","sourceRoot":"","sources":["../../../../src/ComponentStudio/components/save-version-dialog/save-version-dialog.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;;;;;;;IAoBzD,+BAA4B;IAAA,YAA8B;IAAA,iBAAO;;;IAArC,cAA8B;IAA9B,0DAA8B;;;IAE1D,+BAAsC;IAAA,6BAAa;IAAA,iBAAO;;;;IAiBxD,AADF,AADF,8BAAuB,gBACyC,gBACS;IAArB,yTAAkB;IAAlE,iBAAqE;IAEnE,AADF,+BAA2B,eACC;IAAA,mCAAmB;IAAA,iBAAO;IACpD,gCAAyB;IAAA,YAAiC;IAE9D,AADE,AAD4D,iBAAO,EAC7D,EACA;IAEN,AADF,iCAAiE,gBACS;IAArB,yTAAkB;IAArE,iBAAwE;IAEtE,AADF,gCAA2B,gBACC;IAAA,uCAAsB;IAAA,iBAAO;IACvD,iCAAyB;IAAA,aAAgC;IAG/D,AADE,AADE,AAD2D,iBAAO,EAC5D,EACA,EACJ;;;IAdwB,cAAiC;IAAjC,iDAAiC;IACX,cAAkB;IAAlB,2CAAkB;IAGvC,eAAiC;IAAjC,6DAAiC;IAGlC,cAAoC;IAApC,oDAAoC;IACX,cAAkB;IAAlB,2CAAkB;IAG1C,eAAgC;IAAhC,4DAAgC;;;;IArCrE,uCAGuB;IAArB,oMAAS,iBAAU,KAAC;IAGlB,AADF,8BAAyB,aACM;IAGzB,AAFF,2GAA0B,qFAEjB;IAGX,iBAAM;IAGJ,AADF,8BAAwB,eAC0B;IAAA,uBAAO;IAAA,iBAAQ;IAC/D,gCAK0B;IAFxB,gTAAqB;IAGzB,AANE,iBAK0B,EACtB;IAEN,2GAA0B;IAkB5B,iBAAM;IAGJ,AADF,6CAAsB,kBAC4C;IAAnB,+LAAS,eAAQ,KAAC;IAC7D,yBAAgC;IAAC,uBACnC;IAAA,iBAAS;IACT,mCAA+D;IAArB,+LAAS,iBAAU,KAAC;IAC5D,yBACF;IAEJ,AADE,AADE,iBAAS,EACY,EACV;;;IAlDb,AADA,sCAAwB,cACX;IAKT,eAIC;IAJD,mDAIC;IAQC,eAAqB;IAArB,8CAAqB;IAKzB,cAiBC;IAjBD,oDAiBC;IAImB,eAAwB;IAAxB,sCAAwB;IAGxB,eAAqB;IAArB,mCAAqB;;AAqGnD,MAAM,OAAO,0BAA0B;IAC5B,OAAO,GAAG,KAAK,CAAC;IAChB,cAAc,GAAG,CAAC,CAAC;IAClB,IAAI,GAAG,IAAI,YAAY,EAAqB,CAAC;IAC7C,MAAM,GAAG,IAAI,YAAY,EAAQ,CAAC;IAE5C,OAAO,GAAG,EAAE,CAAC;IACb,IAAI,GAAqB,KAAK,CAAC;IAE/B,MAAM;QACJ,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;YACb,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,IAAI,EAAE,IAAI,CAAC,IAAI;SAChB,CAAC,CAAC;QACH,IAAI,CAAC,SAAS,EAAE,CAAC;IACnB,CAAC;IAED,QAAQ;QACN,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QACnB,IAAI,CAAC,SAAS,EAAE,CAAC;IACnB,CAAC;IAEO,SAAS;QACf,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;QAClB,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC;IACpB,CAAC;oHAzBU,0BAA0B;6DAA1B,0BAA0B;YAtJnC,sGAAe;;YAAf,sCAsDC;;;iFAgGQ,0BAA0B;cA1JtC,SAAS;6BACI,KAAK,YACP,wBAAwB,YACxB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDT;;kBAgGA,KAAK;;kBACL,KAAK;;kBACL,MAAM;;kBACN,MAAM;;kFAJI,0BAA0B","sourcesContent":["import { Component, Input, Output, EventEmitter } from '@angular/core';\n\nexport interface SaveVersionResult {\n Comment: string;\n Mode: 'new' | 'update';\n}\n\n@Component({\n standalone: false,\n selector: 'mj-save-version-dialog',\n template: `\n @if (Visible) {\n <kendo-dialog\n [title]=\"'Save Version'\"\n [width]=\"420\"\n (close)=\"OnCancel()\">\n\n <div class=\"dialog-body\">\n <div class=\"version-context\">\n @if (CurrentVersion > 0) {\n <span class=\"version-badge\">Current: v{{ CurrentVersion }}</span>\n } @else {\n <span class=\"version-badge new-badge\">First version</span>\n }\n </div>\n\n <div class=\"form-field\">\n <label class=\"field-label\" for=\"versionComment\">Comment</label>\n <input\n kendoTextBox\n id=\"versionComment\"\n [(ngModel)]=\"Comment\"\n placeholder=\"Describe what changed...\"\n class=\"comment-input\" />\n </div>\n\n @if (CurrentVersion > 0) {\n <div class=\"save-mode\">\n <label class=\"radio-option\" [class.selected]=\"Mode === 'new'\">\n <input type=\"radio\" name=\"saveMode\" value=\"new\" [(ngModel)]=\"Mode\" />\n <div class=\"radio-content\">\n <span class=\"radio-label\">Save as new version</span>\n <span class=\"radio-desc\">Creates v{{ CurrentVersion + 1 }}</span>\n </div>\n </label>\n <label class=\"radio-option\" [class.selected]=\"Mode === 'update'\">\n <input type=\"radio\" name=\"saveMode\" value=\"update\" [(ngModel)]=\"Mode\" />\n <div class=\"radio-content\">\n <span class=\"radio-label\">Update current version</span>\n <span class=\"radio-desc\">Overwrites v{{ CurrentVersion }}</span>\n </div>\n </label>\n </div>\n }\n </div>\n\n <kendo-dialog-actions>\n <button kendoButton [themeColor]=\"'primary'\" (click)=\"OnSave()\">\n <i class=\"fa-solid fa-save\"></i> Save\n </button>\n <button kendoButton [themeColor]=\"'base'\" (click)=\"OnCancel()\">\n Cancel\n </button>\n </kendo-dialog-actions>\n </kendo-dialog>\n }\n `,\n styles: [`\n .dialog-body {\n display: flex;\n flex-direction: column;\n gap: 16px;\n padding: 4px 0;\n }\n\n .version-context {\n display: flex;\n align-items: center;\n }\n\n .version-badge {\n display: inline-flex;\n align-items: center;\n padding: 3px 10px;\n border-radius: 12px;\n font-size: 12px;\n font-weight: 600;\n background: var(--mat-sys-primary-container, #e0e7ff);\n color: var(--mat-sys-on-primary-container, #1e1b4b);\n }\n\n .new-badge {\n background: var(--mat-sys-tertiary-container, #f3e8ff);\n color: var(--mat-sys-on-tertiary-container, #4a1d96);\n }\n\n .form-field {\n display: flex;\n flex-direction: column;\n gap: 6px;\n }\n\n .field-label {\n font-size: 13px;\n font-weight: 500;\n color: var(--mat-sys-on-surface, #1f2937);\n }\n\n .comment-input {\n width: 100%;\n }\n\n .save-mode {\n display: flex;\n flex-direction: column;\n gap: 8px;\n }\n\n .radio-option {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 10px 12px;\n border: 1px solid var(--mat-sys-outline-variant, #d1d5db);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.15s ease;\n }\n\n .radio-option:hover {\n background: var(--mat-sys-surface-container, #f3f4f6);\n }\n\n .radio-option.selected {\n border-color: var(--mat-sys-primary, #6366f1);\n background: var(--mat-sys-primary-container, #e0e7ff);\n }\n\n .radio-option input[type=\"radio\"] {\n margin-top: 2px;\n accent-color: var(--mat-sys-primary, #6366f1);\n }\n\n .radio-content {\n display: flex;\n flex-direction: column;\n gap: 2px;\n }\n\n .radio-label {\n font-size: 13px;\n font-weight: 500;\n color: var(--mat-sys-on-surface, #1f2937);\n }\n\n .radio-desc {\n font-size: 11px;\n color: var(--mat-sys-on-surface-variant, #6b7280);\n }\n `]\n})\nexport class SaveVersionDialogComponent {\n @Input() Visible = false;\n @Input() CurrentVersion = 0;\n @Output() Save = new EventEmitter<SaveVersionResult>();\n @Output() Cancel = new EventEmitter<void>();\n\n Comment = '';\n Mode: 'new' | 'update' = 'new';\n\n OnSave(): void {\n this.Save.emit({\n Comment: this.Comment,\n Mode: this.Mode\n });\n this.ResetForm();\n }\n\n OnCancel(): void {\n this.Cancel.emit();\n this.ResetForm();\n }\n\n private ResetForm(): void {\n this.Comment = '';\n this.Mode = 'new';\n }\n}\n"]}
1
+ {"version":3,"file":"save-version-dialog.component.js","sourceRoot":"","sources":["../../../../src/ComponentStudio/components/save-version-dialog/save-version-dialog.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;;;;;;;IAoBzD,+BAA4B;IAAA,YAA8B;IAAA,iBAAO;;;IAArC,cAA8B;IAA9B,0DAA8B;;;IAE1D,+BAAsC;IAAA,6BAAa;IAAA,iBAAO;;;;IAiBxD,AADF,AADF,8BAAuB,gBACyC,gBACS;IAArB,yTAAkB;IAAlE,iBAAqE;IAEnE,AADF,+BAA2B,eACC;IAAA,mCAAmB;IAAA,iBAAO;IACpD,gCAAyB;IAAA,YAAiC;IAE9D,AADE,AAD4D,iBAAO,EAC7D,EACA;IAEN,AADF,iCAAiE,gBACS;IAArB,yTAAkB;IAArE,iBAAwE;IAEtE,AADF,gCAA2B,gBACC;IAAA,uCAAsB;IAAA,iBAAO;IACvD,iCAAyB;IAAA,aAAgC;IAG/D,AADE,AADE,AAD2D,iBAAO,EAC5D,EACA,EACJ;;;IAdwB,cAAiC;IAAjC,iDAAiC;IACX,cAAkB;IAAlB,2CAAkB;IAGvC,eAAiC;IAAjC,6DAAiC;IAGlC,cAAoC;IAApC,oDAAoC;IACX,cAAkB;IAAlB,2CAAkB;IAG1C,eAAgC;IAAhC,4DAAgC;;;;IArCrE,uCAGuB;IAArB,oMAAS,iBAAU,KAAC;IAGlB,AADF,8BAAyB,aACM;IAGzB,AAFF,2GAA0B,qFAEjB;IAGX,iBAAM;IAGJ,AADF,8BAAwB,eAC0B;IAAA,uBAAO;IAAA,iBAAQ;IAC/D,gCAK0B;IAFxB,gTAAqB;IAGzB,AANE,iBAK0B,EACtB;IAEN,2GAA0B;IAkB5B,iBAAM;IAGJ,AADF,6CAAsB,kBAC4C;IAAnB,+LAAS,eAAQ,KAAC;IAC7D,yBAAgC;IAAC,uBACnC;IAAA,iBAAS;IACT,mCAA+D;IAArB,+LAAS,iBAAU,KAAC;IAC5D,yBACF;IAEJ,AADE,AADE,iBAAS,EACY,EACV;;;IAlDb,AADA,sCAAwB,cACX;IAKT,eAIC;IAJD,mDAIC;IAQC,eAAqB;IAArB,8CAAqB;IAKzB,cAiBC;IAjBD,oDAiBC;IAImB,eAAwB;IAAxB,sCAAwB;IAGxB,eAAqB;IAArB,mCAAqB;;AAqGnD,MAAM,OAAO,0BAA0B;IAC5B,OAAO,GAAG,KAAK,CAAC;IAChB,cAAc,GAAG,CAAC,CAAC;IAClB,IAAI,GAAG,IAAI,YAAY,EAAqB,CAAC;IAC7C,MAAM,GAAG,IAAI,YAAY,EAAQ,CAAC;IAE5C,OAAO,GAAG,EAAE,CAAC;IACb,IAAI,GAAqB,KAAK,CAAC;IAE/B,MAAM;QACJ,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;YACb,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,IAAI,EAAE,IAAI,CAAC,IAAI;SAChB,CAAC,CAAC;QACH,IAAI,CAAC,SAAS,EAAE,CAAC;IACnB,CAAC;IAED,QAAQ;QACN,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QACnB,IAAI,CAAC,SAAS,EAAE,CAAC;IACnB,CAAC;IAEO,SAAS;QACf,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;QAClB,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC;IACpB,CAAC;oHAzBU,0BAA0B;6DAA1B,0BAA0B;YAtJnC,sGAAe;;YAAf,sCAsDC;;;iFAgGQ,0BAA0B;cA1JtC,SAAS;6BACI,KAAK,YACP,wBAAwB,YACxB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDT;;kBAgGA,KAAK;;kBACL,KAAK;;kBACL,MAAM;;kBACN,MAAM;;kFAJI,0BAA0B","sourcesContent":["import { Component, Input, Output, EventEmitter } from '@angular/core';\n\nexport interface SaveVersionResult {\n Comment: string;\n Mode: 'new' | 'update';\n}\n\n@Component({\n standalone: false,\n selector: 'mj-save-version-dialog',\n template: `\n @if (Visible) {\n <kendo-dialog\n [title]=\"'Save Version'\"\n [width]=\"420\"\n (close)=\"OnCancel()\">\n\n <div class=\"dialog-body\">\n <div class=\"version-context\">\n @if (CurrentVersion > 0) {\n <span class=\"version-badge\">Current: v{{ CurrentVersion }}</span>\n } @else {\n <span class=\"version-badge new-badge\">First version</span>\n }\n </div>\n\n <div class=\"form-field\">\n <label class=\"field-label\" for=\"versionComment\">Comment</label>\n <input\n kendoTextBox\n id=\"versionComment\"\n [(ngModel)]=\"Comment\"\n placeholder=\"Describe what changed...\"\n class=\"comment-input\" />\n </div>\n\n @if (CurrentVersion > 0) {\n <div class=\"save-mode\">\n <label class=\"radio-option\" [class.selected]=\"Mode === 'new'\">\n <input type=\"radio\" name=\"saveMode\" value=\"new\" [(ngModel)]=\"Mode\" />\n <div class=\"radio-content\">\n <span class=\"radio-label\">Save as new version</span>\n <span class=\"radio-desc\">Creates v{{ CurrentVersion + 1 }}</span>\n </div>\n </label>\n <label class=\"radio-option\" [class.selected]=\"Mode === 'update'\">\n <input type=\"radio\" name=\"saveMode\" value=\"update\" [(ngModel)]=\"Mode\" />\n <div class=\"radio-content\">\n <span class=\"radio-label\">Update current version</span>\n <span class=\"radio-desc\">Overwrites v{{ CurrentVersion }}</span>\n </div>\n </label>\n </div>\n }\n </div>\n\n <kendo-dialog-actions>\n <button kendoButton [themeColor]=\"'primary'\" (click)=\"OnSave()\">\n <i class=\"fa-solid fa-save\"></i> Save\n </button>\n <button kendoButton [themeColor]=\"'base'\" (click)=\"OnCancel()\">\n Cancel\n </button>\n </kendo-dialog-actions>\n </kendo-dialog>\n }\n `,\n styles: [`\n .dialog-body {\n display: flex;\n flex-direction: column;\n gap: 16px;\n padding: 4px 0;\n }\n\n .version-context {\n display: flex;\n align-items: center;\n }\n\n .version-badge {\n display: inline-flex;\n align-items: center;\n padding: 3px 10px;\n border-radius: 12px;\n font-size: 12px;\n font-weight: 600;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n }\n\n .new-badge {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n }\n\n .form-field {\n display: flex;\n flex-direction: column;\n gap: 6px;\n }\n\n .field-label {\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-primary);\n }\n\n .comment-input {\n width: 100%;\n }\n\n .save-mode {\n display: flex;\n flex-direction: column;\n gap: 8px;\n }\n\n .radio-option {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 10px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.15s ease;\n }\n\n .radio-option:hover {\n background: var(--mj-bg-surface-sunken);\n }\n\n .radio-option.selected {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n }\n\n .radio-option input[type=\"radio\"] {\n margin-top: 2px;\n accent-color: var(--mj-brand-primary);\n }\n\n .radio-content {\n display: flex;\n flex-direction: column;\n gap: 2px;\n }\n\n .radio-label {\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-primary);\n }\n\n .radio-desc {\n font-size: 11px;\n color: var(--mj-text-secondary);\n }\n `]\n})\nexport class SaveVersionDialogComponent {\n @Input() Visible = false;\n @Input() CurrentVersion = 0;\n @Output() Save = new EventEmitter<SaveVersionResult>();\n @Output() Cancel = new EventEmitter<void>();\n\n Comment = '';\n Mode: 'new' | 'update' = 'new';\n\n OnSave(): void {\n this.Save.emit({\n Comment: this.Comment,\n Mode: this.Mode\n });\n this.ResetForm();\n }\n\n OnCancel(): void {\n this.Cancel.emit();\n this.ResetForm();\n }\n\n private ResetForm(): void {\n this.Comment = '';\n this.Mode = 'new';\n }\n}\n"]}
@@ -72,7 +72,7 @@ export class TextImportDialogComponent {
72
72
  i0.ɵɵproperty("themeColor", "base");
73
73
  i0.ɵɵadvance(2);
74
74
  i0.ɵɵproperty("themeColor", "primary")("disabled", !ctx.componentJson);
75
- } }, dependencies: [i1.NgControlStatus, i1.NgModel, i2.CodeEditorComponent, i3.ButtonComponent], styles: [".text-import-dialog-content[_ngcontent-%COMP%] {\n padding: 20px;\n display: flex;\n flex-direction: column;\n height: 100%;\n }\n \n .dialog-header[_ngcontent-%COMP%] {\n margin-bottom: 15px;\n }\n \n .dialog-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 10px 0;\n color: #333;\n }\n \n .dialog-header[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n color: #666;\n font-size: 14px;\n }\n \n .editor-container[_ngcontent-%COMP%] {\n flex: 1;\n border: 1px solid #ddd;\n border-radius: 4px;\n overflow: hidden;\n margin-bottom: 15px;\n }\n \n .error-message[_ngcontent-%COMP%] {\n background-color: #fff5f5;\n border: 1px solid #feb2b2;\n color: #c53030;\n padding: 10px;\n border-radius: 4px;\n margin-bottom: 15px;\n font-size: 14px;\n }\n \n .error-message[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-right: 8px;\n }\n \n .dialog-actions[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-end;\n gap: 10px;\n padding-top: 15px;\n border-top: 1px solid #e0e0e0;\n }"] });
75
+ } }, dependencies: [i1.NgControlStatus, i1.NgModel, i2.CodeEditorComponent, i3.ButtonComponent], styles: [".text-import-dialog-content[_ngcontent-%COMP%] {\n padding: 20px;\n display: flex;\n flex-direction: column;\n height: 100%;\n }\n\n .dialog-header[_ngcontent-%COMP%] {\n margin-bottom: 15px;\n }\n\n .dialog-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 10px 0;\n color: var(--mj-text-primary);\n }\n\n .dialog-header[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n color: var(--mj-text-secondary);\n font-size: 14px;\n }\n\n .editor-container[_ngcontent-%COMP%] {\n flex: 1;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n overflow: hidden;\n margin-bottom: 15px;\n }\n\n .error-message[_ngcontent-%COMP%] {\n background-color: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n border: 1px solid var(--mj-status-error);\n color: var(--mj-status-error);\n padding: 10px;\n border-radius: 4px;\n margin-bottom: 15px;\n font-size: 14px;\n }\n\n .error-message[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-right: 8px;\n }\n\n .dialog-actions[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-end;\n gap: 10px;\n padding-top: 15px;\n border-top: 1px solid var(--mj-border-default);\n }"] });
76
76
  }
77
77
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(TextImportDialogComponent, [{
78
78
  type: Component,
@@ -111,7 +111,7 @@ export class TextImportDialogComponent {
111
111
  </button>
112
112
  </div>
113
113
  </div>
114
- `, styles: ["\n .text-import-dialog-content {\n padding: 20px;\n display: flex;\n flex-direction: column;\n height: 100%;\n }\n \n .dialog-header {\n margin-bottom: 15px;\n }\n \n .dialog-header h3 {\n margin: 0 0 10px 0;\n color: #333;\n }\n \n .dialog-header p {\n margin: 0;\n color: #666;\n font-size: 14px;\n }\n \n .editor-container {\n flex: 1;\n border: 1px solid #ddd;\n border-radius: 4px;\n overflow: hidden;\n margin-bottom: 15px;\n }\n \n .error-message {\n background-color: #fff5f5;\n border: 1px solid #feb2b2;\n color: #c53030;\n padding: 10px;\n border-radius: 4px;\n margin-bottom: 15px;\n font-size: 14px;\n }\n \n .error-message i {\n margin-right: 8px;\n }\n \n .dialog-actions {\n display: flex;\n justify-content: flex-end;\n gap: 10px;\n padding-top: 15px;\n border-top: 1px solid #e0e0e0;\n }\n "] }]
114
+ `, styles: ["\n .text-import-dialog-content {\n padding: 20px;\n display: flex;\n flex-direction: column;\n height: 100%;\n }\n\n .dialog-header {\n margin-bottom: 15px;\n }\n\n .dialog-header h3 {\n margin: 0 0 10px 0;\n color: var(--mj-text-primary);\n }\n\n .dialog-header p {\n margin: 0;\n color: var(--mj-text-secondary);\n font-size: 14px;\n }\n\n .editor-container {\n flex: 1;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n overflow: hidden;\n margin-bottom: 15px;\n }\n\n .error-message {\n background-color: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n border: 1px solid var(--mj-status-error);\n color: var(--mj-status-error);\n padding: 10px;\n border-radius: 4px;\n margin-bottom: 15px;\n font-size: 14px;\n }\n\n .error-message i {\n margin-right: 8px;\n }\n\n .dialog-actions {\n display: flex;\n justify-content: flex-end;\n gap: 10px;\n padding-top: 15px;\n border-top: 1px solid var(--mj-border-default);\n }\n "] }]
115
115
  }], null, { importSpec: [{
116
116
  type: Output
117
117
  }], cancelDialog: [{
@@ -1 +1 @@
1
- {"version":3,"file":"text-import-dialog.component.js","sourceRoot":"","sources":["../../../src/ComponentStudio/components/text-import-dialog.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;;;;;;IA0BxD,8BAA2B;IACzB,uBAAgD;IAChD,YACF;IAAA,iBAAM;;;IADJ,eACF;IADE,oDACF;;AAmER,MAAM,OAAO,yBAAyB;IAC1B,UAAU,GAAG,IAAI,YAAY,EAAiB,CAAC;IAC/C,YAAY,GAAG,IAAI,YAAY,EAAQ,CAAC;IAE3C,aAAa,GAAG,EAAE,CAAC;IACnB,YAAY,GAAG,EAAE,CAAC;IAElB,MAAM;QACX,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;QAEvB,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,EAAE,CAAC;YAC/B,IAAI,CAAC,YAAY,GAAG,wCAAwC,CAAC;YAC7D,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAkB,CAAC;YAE7D,2BAA2B;YAC3B,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;gBAC7B,IAAI,CAAC,YAAY,GAAG,gEAAgE,CAAC;gBACrF,OAAO;YACT,CAAC;YAED,uBAAuB;YACvB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,YAAY,GAAG,gDAAgD,CAAC;QACvE,CAAC;IACH,CAAC;IAEM,MAAM;QACX,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;IAC3B,CAAC;mHAjCU,yBAAyB;6DAAzB,yBAAyB;YAvF9B,AADF,AADF,8BAAwC,aACX,SACrB;YAAA,0CAA0B;YAAA,iBAAK;YACnC,yBAAG;YAAA,sEAAsD;YAC3D,AAD2D,iBAAI,EACzD;YAGJ,AADF,8BAA8B,wBAQH;YANvB,sOAA2B;YAQ/B,AADE,iBAAiB,EACb;YAEN,2FAAoB;YAQlB,AADF,8BAA4B,iBACmC;YAAzC,uGAAS,YAAQ,IAAC;YACpC,yBACF;YAAA,iBAAS;YACT,kCAA4F;YAAxE,uGAAS,YAAQ,IAAC;YACpC,wBAAuC;YAAC,yBAC1C;YAEJ,AADE,AADE,iBAAS,EACL,EACF;;YAzBA,eAA2B;YAA3B,iDAA2B;YAK3B,AADA,AADA,AADA,AADA,iCAAmB,mBACD,uBACI,mBACJ,kEAC+C;YAKrE,cAKC;YALD,2CAKC;YAGwC,eAAqB;YAArB,mCAAqB;YAGrB,eAAwB;YAAC,AAAzB,sCAAwB,gCAA4B;;;iFA4DtF,yBAAyB;cA7FrC,SAAS;6BACI,KAAK,YACP,wBAAwB,YACxB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCT;;kBAwDA,MAAM;;kBACN,MAAM;;kFAFI,yBAAyB","sourcesContent":["import { Component, EventEmitter, Output } from '@angular/core';\nimport { ComponentSpec } from '@memberjunction/interactive-component-types';\n\n@Component({\n standalone: false,\n selector: 'app-text-import-dialog',\n template: `\n <div class=\"text-import-dialog-content\">\n <div class=\"dialog-header\">\n <h3>Import Component from Text</h3>\n <p>Paste or type your component specification JSON below:</p>\n </div>\n \n <div class=\"editor-container\">\n <mj-code-editor\n [(ngModel)]=\"componentJson\"\n [language]=\"'json'\"\n [autoFocus]=\"true\"\n [indentWithTab]=\"true\"\n [readonly]=\"false\"\n [placeholder]=\"'Paste your component specification JSON here...'\"\n style=\"height: 400px;\">\n </mj-code-editor>\n </div>\n \n @if (errorMessage) {\n <div class=\"error-message\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n {{ errorMessage }}\n </div>\n }\n \n <div class=\"dialog-actions\">\n <button kendoButton (click)=\"cancel()\" [themeColor]=\"'base'\">\n Cancel\n </button>\n <button kendoButton (click)=\"import()\" [themeColor]=\"'primary'\" [disabled]=\"!componentJson\">\n <i class=\"fa-solid fa-file-import\"></i> Import\n </button>\n </div>\n </div>\n `,\n styles: [`\n .text-import-dialog-content {\n padding: 20px;\n display: flex;\n flex-direction: column;\n height: 100%;\n }\n \n .dialog-header {\n margin-bottom: 15px;\n }\n \n .dialog-header h3 {\n margin: 0 0 10px 0;\n color: #333;\n }\n \n .dialog-header p {\n margin: 0;\n color: #666;\n font-size: 14px;\n }\n \n .editor-container {\n flex: 1;\n border: 1px solid #ddd;\n border-radius: 4px;\n overflow: hidden;\n margin-bottom: 15px;\n }\n \n .error-message {\n background-color: #fff5f5;\n border: 1px solid #feb2b2;\n color: #c53030;\n padding: 10px;\n border-radius: 4px;\n margin-bottom: 15px;\n font-size: 14px;\n }\n \n .error-message i {\n margin-right: 8px;\n }\n \n .dialog-actions {\n display: flex;\n justify-content: flex-end;\n gap: 10px;\n padding-top: 15px;\n border-top: 1px solid #e0e0e0;\n }\n `]\n})\nexport class TextImportDialogComponent {\n @Output() importSpec = new EventEmitter<ComponentSpec>();\n @Output() cancelDialog = new EventEmitter<void>();\n \n public componentJson = '';\n public errorMessage = '';\n \n public import(): void {\n this.errorMessage = '';\n \n if (!this.componentJson.trim()) {\n this.errorMessage = 'Please enter a component specification';\n return;\n }\n \n try {\n const spec = JSON.parse(this.componentJson) as ComponentSpec;\n \n // Validate required fields\n if (!spec.name || !spec.code) {\n this.errorMessage = 'Invalid specification: missing required fields (name and code)';\n return;\n }\n \n // Emit the parsed spec\n this.importSpec.emit(spec);\n } catch (error) {\n this.errorMessage = 'Invalid JSON format. Please check your syntax.';\n }\n }\n \n public cancel(): void {\n this.cancelDialog.emit();\n }\n}"]}
1
+ {"version":3,"file":"text-import-dialog.component.js","sourceRoot":"","sources":["../../../src/ComponentStudio/components/text-import-dialog.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;;;;;;IA0BxD,8BAA2B;IACzB,uBAAgD;IAChD,YACF;IAAA,iBAAM;;;IADJ,eACF;IADE,oDACF;;AAmER,MAAM,OAAO,yBAAyB;IAC1B,UAAU,GAAG,IAAI,YAAY,EAAiB,CAAC;IAC/C,YAAY,GAAG,IAAI,YAAY,EAAQ,CAAC;IAE3C,aAAa,GAAG,EAAE,CAAC;IACnB,YAAY,GAAG,EAAE,CAAC;IAElB,MAAM;QACX,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;QAEvB,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,EAAE,CAAC;YAC/B,IAAI,CAAC,YAAY,GAAG,wCAAwC,CAAC;YAC7D,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAkB,CAAC;YAE7D,2BAA2B;YAC3B,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;gBAC7B,IAAI,CAAC,YAAY,GAAG,gEAAgE,CAAC;gBACrF,OAAO;YACT,CAAC;YAED,uBAAuB;YACvB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,YAAY,GAAG,gDAAgD,CAAC;QACvE,CAAC;IACH,CAAC;IAEM,MAAM;QACX,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;IAC3B,CAAC;mHAjCU,yBAAyB;6DAAzB,yBAAyB;YAvF9B,AADF,AADF,8BAAwC,aACX,SACrB;YAAA,0CAA0B;YAAA,iBAAK;YACnC,yBAAG;YAAA,sEAAsD;YAC3D,AAD2D,iBAAI,EACzD;YAGJ,AADF,8BAA8B,wBAQH;YANvB,sOAA2B;YAQ/B,AADE,iBAAiB,EACb;YAEN,2FAAoB;YAQlB,AADF,8BAA4B,iBACmC;YAAzC,uGAAS,YAAQ,IAAC;YACpC,yBACF;YAAA,iBAAS;YACT,kCAA4F;YAAxE,uGAAS,YAAQ,IAAC;YACpC,wBAAuC;YAAC,yBAC1C;YAEJ,AADE,AADE,iBAAS,EACL,EACF;;YAzBA,eAA2B;YAA3B,iDAA2B;YAK3B,AADA,AADA,AADA,AADA,iCAAmB,mBACD,uBACI,mBACJ,kEAC+C;YAKrE,cAKC;YALD,2CAKC;YAGwC,eAAqB;YAArB,mCAAqB;YAGrB,eAAwB;YAAC,AAAzB,sCAAwB,gCAA4B;;;iFA4DtF,yBAAyB;cA7FrC,SAAS;6BACI,KAAK,YACP,wBAAwB,YACxB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCT;;kBAwDA,MAAM;;kBACN,MAAM;;kFAFI,yBAAyB","sourcesContent":["import { Component, EventEmitter, Output } from '@angular/core';\nimport { ComponentSpec } from '@memberjunction/interactive-component-types';\n\n@Component({\n standalone: false,\n selector: 'app-text-import-dialog',\n template: `\n <div class=\"text-import-dialog-content\">\n <div class=\"dialog-header\">\n <h3>Import Component from Text</h3>\n <p>Paste or type your component specification JSON below:</p>\n </div>\n \n <div class=\"editor-container\">\n <mj-code-editor\n [(ngModel)]=\"componentJson\"\n [language]=\"'json'\"\n [autoFocus]=\"true\"\n [indentWithTab]=\"true\"\n [readonly]=\"false\"\n [placeholder]=\"'Paste your component specification JSON here...'\"\n style=\"height: 400px;\">\n </mj-code-editor>\n </div>\n \n @if (errorMessage) {\n <div class=\"error-message\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n {{ errorMessage }}\n </div>\n }\n \n <div class=\"dialog-actions\">\n <button kendoButton (click)=\"cancel()\" [themeColor]=\"'base'\">\n Cancel\n </button>\n <button kendoButton (click)=\"import()\" [themeColor]=\"'primary'\" [disabled]=\"!componentJson\">\n <i class=\"fa-solid fa-file-import\"></i> Import\n </button>\n </div>\n </div>\n `,\n styles: [`\n .text-import-dialog-content {\n padding: 20px;\n display: flex;\n flex-direction: column;\n height: 100%;\n }\n\n .dialog-header {\n margin-bottom: 15px;\n }\n\n .dialog-header h3 {\n margin: 0 0 10px 0;\n color: var(--mj-text-primary);\n }\n\n .dialog-header p {\n margin: 0;\n color: var(--mj-text-secondary);\n font-size: 14px;\n }\n\n .editor-container {\n flex: 1;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n overflow: hidden;\n margin-bottom: 15px;\n }\n\n .error-message {\n background-color: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n border: 1px solid var(--mj-status-error);\n color: var(--mj-status-error);\n padding: 10px;\n border-radius: 4px;\n margin-bottom: 15px;\n font-size: 14px;\n }\n\n .error-message i {\n margin-right: 8px;\n }\n\n .dialog-actions {\n display: flex;\n justify-content: flex-end;\n gap: 10px;\n padding-top: 15px;\n border-top: 1px solid var(--mj-border-default);\n }\n `]\n})\nexport class TextImportDialogComponent {\n @Output() importSpec = new EventEmitter<ComponentSpec>();\n @Output() cancelDialog = new EventEmitter<void>();\n \n public componentJson = '';\n public errorMessage = '';\n \n public import(): void {\n this.errorMessage = '';\n \n if (!this.componentJson.trim()) {\n this.errorMessage = 'Please enter a component specification';\n return;\n }\n \n try {\n const spec = JSON.parse(this.componentJson) as ComponentSpec;\n \n // Validate required fields\n if (!spec.name || !spec.code) {\n this.errorMessage = 'Invalid specification: missing required fields (name and code)';\n return;\n }\n \n // Emit the parsed spec\n this.importSpec.emit(spec);\n } catch (error) {\n this.errorMessage = 'Invalid JSON format. Please check your syntax.';\n }\n }\n \n public cancel(): void {\n this.cancelDialog.emit();\n }\n}"]}
@@ -328,11 +328,11 @@ export class ComponentPreviewComponent {
328
328
  i0.ɵɵconditional(ctx.State.IsRunning && ctx.State.SelectedComponent ? 8 : -1);
329
329
  i0.ɵɵadvance(2);
330
330
  i0.ɵɵconditional(!ctx.State.SelectedComponent ? 10 : !ctx.State.IsRunning ? 11 : ctx.LocalComponentSpec ? 12 : -1);
331
- } }, dependencies: [i2.NgClass, i3.MJReactComponent], styles: ["[_nghost-%COMP%] {\n display: block;\n width: 100%;\n height: 100%;\n}\n\n.component-preview[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--mat-sys-surface-container-low);\n overflow: hidden;\n}\n\n\n\n\n\n\n.preview-toolbar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 6px 12px;\n background: var(--mat-sys-surface);\n border-bottom: 1px solid var(--mat-sys-outline);\n min-height: 42px;\n gap: 12px;\n flex-shrink: 0;\n}\n\n.preview-toolbar[_ngcontent-%COMP%] .toolbar-left[_ngcontent-%COMP%], \n.preview-toolbar[_ngcontent-%COMP%] .toolbar-center[_ngcontent-%COMP%], \n.preview-toolbar[_ngcontent-%COMP%] .toolbar-right[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.preview-toolbar[_ngcontent-%COMP%] .toolbar-left[_ngcontent-%COMP%] {\n flex: 0 0 auto;\n}\n\n.preview-toolbar[_ngcontent-%COMP%] .toolbar-center[_ngcontent-%COMP%] {\n flex: 1 1 auto;\n justify-content: center;\n}\n\n.preview-toolbar[_ngcontent-%COMP%] .toolbar-right[_ngcontent-%COMP%] {\n flex: 0 0 auto;\n}\n\n.toolbar-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 10px;\n border: 1px solid var(--mat-sys-outline);\n border-radius: 5px;\n background: var(--mat-sys-surface);\n color: var(--mat-sys-on-surface);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n white-space: nowrap;\n}\n\n.toolbar-btn[_ngcontent-%COMP%]:hover {\n background: var(--mat-sys-surface-variant);\n border-color: #9ca3af;\n}\n\n.toolbar-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n}\n\n.run-btn[_ngcontent-%COMP%] {\n color: #059669;\n border-color: #a7f3d0;\n background: #ecfdf5;\n}\n\n.run-btn[_ngcontent-%COMP%]:hover {\n background: #d1fae5;\n border-color: #6ee7b7;\n}\n\n.stop-btn[_ngcontent-%COMP%] {\n color: #dc2626;\n border-color: #fca5a5;\n background: #fef2f2;\n}\n\n.stop-btn[_ngcontent-%COMP%]:hover {\n background: #fee2e2;\n border-color: #f87171;\n}\n\n.ai-fix-btn[_ngcontent-%COMP%] {\n color: #7c3aed;\n border-color: #c4b5fd;\n background: #f5f3ff;\n}\n\n.ai-fix-btn[_ngcontent-%COMP%]:hover {\n background: #ede9fe;\n border-color: #a78bfa;\n}\n\n.running-indicator[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: var(--mat-sys-on-surface-variant);\n font-weight: 500;\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.running-indicator[_ngcontent-%COMP%] .running-dot[_ngcontent-%COMP%] {\n font-size: 7px;\n color: #22c55e;\n animation: _ngcontent-%COMP%_pulse-dot 1.5s ease-in-out infinite;\n}\n\n@keyframes _ngcontent-%COMP%_pulse-dot {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.3; }\n}\n\n\n\n\n\n\n.viewport-selector[_ngcontent-%COMP%] {\n display: inline-flex;\n border: 1px solid var(--mat-sys-outline);\n border-radius: var(--mat-sys-corner-extra-small);\n overflow: hidden;\n background: var(--mat-sys-surface-container-lowest);\n}\n\n.viewport-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 34px;\n height: 28px;\n border: none;\n background: transparent;\n color: var(--mat-sys-on-surface-variant);\n cursor: pointer;\n font-size: 13px;\n transition: all 0.15s ease;\n}\n\n.viewport-btn[_ngcontent-%COMP%]:not(:last-child) {\n border-right: 1px solid var(--mat-sys-outline);\n}\n\n.viewport-btn[_ngcontent-%COMP%]:hover {\n background: var(--mat-sys-surface-container-high);\n color: var(--mat-sys-on-surface);\n}\n\n.viewport-btn.active[_ngcontent-%COMP%] {\n background: var(--mat-sys-primary);\n color: #ffffff;\n}\n\n.viewport-btn.active[_ngcontent-%COMP%]:hover {\n background: var(--mat-sys-primary);\n}\n\n\n\n\n\n\n.preview-area[_ngcontent-%COMP%] {\n flex: 1;\n overflow: auto;\n position: relative;\n display: flex;\n justify-content: center;\n}\n\n.preview-container[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n margin: 0 auto;\n transition: max-width 0.3s ease;\n overflow: auto;\n background: var(--mat-sys-surface);\n}\n\n.preview-container.mobile[_ngcontent-%COMP%], \n.preview-container.tablet[_ngcontent-%COMP%] {\n border-left: 1px solid var(--mat-sys-outline);\n border-right: 1px solid var(--mat-sys-outline);\n box-shadow: var(--mat-sys-elevation-1);\n}\n\n.preview-container.desktop[_ngcontent-%COMP%] {\n max-width: 100% !important;\n}\n\n\n\n\n\n\n.empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n text-align: center;\n padding: 40px 24px;\n color: var(--mat-sys-on-surface-variant);\n}\n\n.empty-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-bottom: 16px;\n color: var(--mat-sys-outline);\n}\n\n.empty-state[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: 18px;\n font-weight: 600;\n color: var(--mat-sys-on-surface-variant);\n}\n\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n color: var(--mat-sys-on-surface-variant);\n max-width: 320px;\n line-height: 1.5;\n}\n\n.run-state[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n color: var(--mat-sys-on-surface);\n}\n\n.run-component-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n margin-top: 20px;\n padding: 10px 24px;\n border: none;\n border-radius: var(--mat-sys-corner-small);\n background: var(--mat-sys-primary);\n color: #ffffff;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.run-component-btn[_ngcontent-%COMP%]:hover {\n background: var(--mat-sys-primary);\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(99, 102, 241, 0.3);\n}\n\n.run-component-btn[_ngcontent-%COMP%]:active {\n transform: translateY(0);\n}\n\n.run-component-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 13px;\n}\n\n\n\n\n\n\n.error-overlay[_ngcontent-%COMP%] {\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n z-index: 10;\n background: rgba(254, 242, 242, 0.95);\n border-top: 2px solid #f87171;\n backdrop-filter: blur(4px);\n padding: 16px 20px;\n animation: _ngcontent-%COMP%_slide-up 0.2s ease-out;\n}\n\n@keyframes _ngcontent-%COMP%_slide-up {\n from {\n transform: translateY(100%);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n}\n\n.error-overlay-content[_ngcontent-%COMP%] {\n max-width: 600px;\n}\n\n.error-overlay-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 6px;\n}\n\n.error-overlay-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #dc2626;\n font-size: 16px;\n}\n\n.error-overlay-header[_ngcontent-%COMP%] .error-overlay-title[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: #991b1b;\n}\n\n.error-overlay-message[_ngcontent-%COMP%] {\n margin: 0 0 12px 0;\n font-size: 13px;\n color: #7f1d1d;\n line-height: 1.4;\n}\n\n.error-overlay-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}"] });
331
+ } }, dependencies: [i2.NgClass, i3.MJReactComponent], styles: ["[_nghost-%COMP%] {\n display: block;\n width: 100%;\n height: 100%;\n}\n\n.component-preview[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--mj-bg-surface-sunken);\n overflow: hidden;\n}\n\n\n\n\n\n\n.preview-toolbar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 6px 12px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n min-height: 42px;\n gap: 12px;\n flex-shrink: 0;\n}\n\n.preview-toolbar[_ngcontent-%COMP%] .toolbar-left[_ngcontent-%COMP%], \n.preview-toolbar[_ngcontent-%COMP%] .toolbar-center[_ngcontent-%COMP%], \n.preview-toolbar[_ngcontent-%COMP%] .toolbar-right[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.preview-toolbar[_ngcontent-%COMP%] .toolbar-left[_ngcontent-%COMP%] {\n flex: 0 0 auto;\n}\n\n.preview-toolbar[_ngcontent-%COMP%] .toolbar-center[_ngcontent-%COMP%] {\n flex: 1 1 auto;\n justify-content: center;\n}\n\n.preview-toolbar[_ngcontent-%COMP%] .toolbar-right[_ngcontent-%COMP%] {\n flex: 0 0 auto;\n}\n\n.toolbar-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 5px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n white-space: nowrap;\n}\n\n.toolbar-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-border-strong);\n}\n\n.toolbar-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n}\n\n.run-btn[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n border-color: color-mix(in srgb, var(--mj-status-success) 40%, transparent);\n background: color-mix(in srgb, var(--mj-status-success) 10%, var(--mj-bg-surface));\n}\n\n.run-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-status-success) 60%, transparent);\n}\n\n.stop-btn[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n border-color: color-mix(in srgb, var(--mj-status-error) 40%, transparent);\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n}\n\n.stop-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-status-error) 60%, transparent);\n}\n\n.ai-fix-btn[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n border-color: color-mix(in srgb, var(--mj-brand-primary) 40%, transparent);\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.ai-fix-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-brand-primary) 60%, transparent);\n}\n\n.running-indicator[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: var(--mj-text-secondary);\n font-weight: 500;\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.running-indicator[_ngcontent-%COMP%] .running-dot[_ngcontent-%COMP%] {\n font-size: 7px;\n color: var(--mj-status-success);\n animation: _ngcontent-%COMP%_pulse-dot 1.5s ease-in-out infinite;\n}\n\n@keyframes _ngcontent-%COMP%_pulse-dot {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.3; }\n}\n\n\n\n\n\n\n.viewport-selector[_ngcontent-%COMP%] {\n display: inline-flex;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n overflow: hidden;\n background: var(--mj-bg-surface);\n}\n\n.viewport-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 34px;\n height: 28px;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n cursor: pointer;\n font-size: 13px;\n transition: all 0.15s ease;\n}\n\n.viewport-btn[_ngcontent-%COMP%]:not(:last-child) {\n border-right: 1px solid var(--mj-border-default);\n}\n\n.viewport-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n.viewport-btn.active[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.viewport-btn.active[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary);\n}\n\n\n\n\n\n\n.preview-area[_ngcontent-%COMP%] {\n flex: 1;\n overflow: auto;\n position: relative;\n display: flex;\n justify-content: center;\n}\n\n.preview-container[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n margin: 0 auto;\n transition: max-width 0.3s ease;\n overflow: auto;\n background: var(--mj-bg-surface);\n}\n\n.preview-container.mobile[_ngcontent-%COMP%], \n.preview-container.tablet[_ngcontent-%COMP%] {\n border-left: 1px solid var(--mj-border-default);\n border-right: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.preview-container.desktop[_ngcontent-%COMP%] {\n max-width: 100% !important;\n}\n\n\n\n\n\n\n.empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n text-align: center;\n padding: 40px 24px;\n color: var(--mj-text-secondary);\n}\n\n.empty-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-bottom: 16px;\n color: var(--mj-border-default);\n}\n\n.empty-state[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: 18px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n color: var(--mj-text-secondary);\n max-width: 320px;\n line-height: 1.5;\n}\n\n.run-state[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n}\n\n.run-component-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n margin-top: 20px;\n padding: 10px 24px;\n border: none;\n border-radius: 8px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.run-component-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary);\n transform: translateY(-1px);\n box-shadow: var(--mj-shadow-md);\n}\n\n.run-component-btn[_ngcontent-%COMP%]:active {\n transform: translateY(0);\n}\n\n.run-component-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 13px;\n}\n\n\n\n\n\n\n.error-overlay[_ngcontent-%COMP%] {\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n z-index: 10;\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n border-top: 2px solid var(--mj-status-error);\n backdrop-filter: blur(4px);\n padding: 16px 20px;\n animation: _ngcontent-%COMP%_slide-up 0.2s ease-out;\n}\n\n@keyframes _ngcontent-%COMP%_slide-up {\n from {\n transform: translateY(100%);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n}\n\n.error-overlay-content[_ngcontent-%COMP%] {\n max-width: 600px;\n}\n\n.error-overlay-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 6px;\n}\n\n.error-overlay-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n font-size: 16px;\n}\n\n.error-overlay-header[_ngcontent-%COMP%] .error-overlay-title[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-status-error);\n}\n\n.error-overlay-message[_ngcontent-%COMP%] {\n margin: 0 0 12px 0;\n font-size: 13px;\n color: var(--mj-text-primary);\n line-height: 1.4;\n}\n\n.error-overlay-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}"] });
332
332
  }
333
333
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ComponentPreviewComponent, [{
334
334
  type: Component,
335
- args: [{ standalone: false, selector: 'mj-component-preview', template: "<div class=\"component-preview\">\n <!-- Toolbar -->\n <div class=\"preview-toolbar\">\n <div class=\"toolbar-left\">\n @if (State.SelectedComponent) {\n @if (State.IsRunning) {\n <button class=\"toolbar-btn stop-btn\" (click)=\"StopComponent()\" title=\"Stop component\">\n <i class=\"fa-solid fa-stop\"></i>\n <span>Stop</span>\n </button>\n <button class=\"toolbar-btn\" (click)=\"RefreshComponent()\" title=\"Refresh component\">\n <i class=\"fa-solid fa-rotate-right\"></i>\n <span>Refresh</span>\n </button>\n } @else {\n <button class=\"toolbar-btn run-btn\" (click)=\"RunSelectedComponent()\" title=\"Run component\">\n <i class=\"fa-solid fa-play\"></i>\n <span>Run</span>\n </button>\n }\n }\n </div>\n\n <div class=\"toolbar-center\">\n <!-- Viewport Size Selector (segmented control) -->\n @if (State.IsRunning) {\n <div class=\"viewport-selector\">\n @for (preset of ViewportPresets; track preset.Size) {\n <button\n class=\"viewport-btn\"\n [class.active]=\"ActiveViewport === preset.Size\"\n (click)=\"SetViewport(preset.Size)\"\n [title]=\"preset.Label\">\n <i class=\"fa-solid\" [ngClass]=\"preset.Icon\"></i>\n </button>\n }\n </div>\n }\n </div>\n\n <div class=\"toolbar-right\">\n @if (State.CurrentError) {\n <button class=\"toolbar-btn ai-fix-btn\" (click)=\"SendErrorToAI()\" title=\"Ask AI to fix this error\">\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i>\n <span>Ask AI to Fix</span>\n </button>\n }\n @if (State.IsRunning && State.SelectedComponent) {\n <span class=\"running-indicator\">\n <i class=\"fa-solid fa-circle running-dot\"></i>\n {{ GetComponentName() }}\n </span>\n }\n </div>\n </div>\n\n <!-- Preview Area -->\n <div class=\"preview-area\">\n @if (!State.SelectedComponent) {\n <!-- Empty State: No component selected -->\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-eye fa-3x\"></i>\n <h3>Select a component to preview</h3>\n <p>Choose a component from the sidebar to see its live preview here.</p>\n </div>\n } @else if (!State.IsRunning) {\n <!-- Component selected but not running -->\n <div class=\"empty-state run-state\">\n <i class=\"fa-solid fa-play-circle fa-3x\"></i>\n <h3>{{ GetComponentName() }}</h3>\n <p>{{ GetComponentDescription() || 'No description available' }}</p>\n <button class=\"run-component-btn\" (click)=\"RunSelectedComponent()\">\n <i class=\"fa-solid fa-play\"></i> Run Component\n </button>\n </div>\n } @else if (LocalComponentSpec) {\n <!-- Live Preview Container -->\n <div class=\"preview-container\"\n [style.max-width]=\"GetPreviewContainerMaxWidth()\"\n [class.mobile]=\"ActiveViewport === 'mobile'\"\n [class.tablet]=\"ActiveViewport === 'tablet'\"\n [class.desktop]=\"ActiveViewport === 'desktop'\">\n <mj-react-component\n #reactComponent\n [component]=\"LocalComponentSpec\"\n (componentEvent)=\"OnComponentEvent($event)\"\n (openEntityRecord)=\"OnOpenEntityRecord($event)\">\n </mj-react-component>\n </div>\n\n <!-- Error Overlay (inline, does not replace the component) -->\n @if (State.CurrentError) {\n <div class=\"error-overlay\">\n <div class=\"error-overlay-content\">\n <div class=\"error-overlay-header\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n <span class=\"error-overlay-title\">{{ State.CurrentError.type }}</span>\n </div>\n <p class=\"error-overlay-message\">{{ State.CurrentError.message }}</p>\n <div class=\"error-overlay-actions\">\n <button class=\"toolbar-btn\" (click)=\"RefreshComponent()\">\n <i class=\"fa-solid fa-rotate-right\"></i> Retry\n </button>\n <button class=\"toolbar-btn ai-fix-btn\" (click)=\"SendErrorToAI()\">\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i> Ask AI to Fix\n </button>\n </div>\n </div>\n </div>\n }\n }\n </div>\n</div>\n", styles: [":host {\n display: block;\n width: 100%;\n height: 100%;\n}\n\n.component-preview {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--mat-sys-surface-container-low);\n overflow: hidden;\n}\n\n/* ============================================================\n TOOLBAR\n ============================================================ */\n\n.preview-toolbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 6px 12px;\n background: var(--mat-sys-surface);\n border-bottom: 1px solid var(--mat-sys-outline);\n min-height: 42px;\n gap: 12px;\n flex-shrink: 0;\n}\n\n.preview-toolbar .toolbar-left,\n.preview-toolbar .toolbar-center,\n.preview-toolbar .toolbar-right {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.preview-toolbar .toolbar-left {\n flex: 0 0 auto;\n}\n\n.preview-toolbar .toolbar-center {\n flex: 1 1 auto;\n justify-content: center;\n}\n\n.preview-toolbar .toolbar-right {\n flex: 0 0 auto;\n}\n\n.toolbar-btn {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 10px;\n border: 1px solid var(--mat-sys-outline);\n border-radius: 5px;\n background: var(--mat-sys-surface);\n color: var(--mat-sys-on-surface);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n white-space: nowrap;\n}\n\n.toolbar-btn:hover {\n background: var(--mat-sys-surface-variant);\n border-color: #9ca3af;\n}\n\n.toolbar-btn i {\n font-size: 11px;\n}\n\n.run-btn {\n color: #059669;\n border-color: #a7f3d0;\n background: #ecfdf5;\n}\n\n.run-btn:hover {\n background: #d1fae5;\n border-color: #6ee7b7;\n}\n\n.stop-btn {\n color: #dc2626;\n border-color: #fca5a5;\n background: #fef2f2;\n}\n\n.stop-btn:hover {\n background: #fee2e2;\n border-color: #f87171;\n}\n\n.ai-fix-btn {\n color: #7c3aed;\n border-color: #c4b5fd;\n background: #f5f3ff;\n}\n\n.ai-fix-btn:hover {\n background: #ede9fe;\n border-color: #a78bfa;\n}\n\n.running-indicator {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: var(--mat-sys-on-surface-variant);\n font-weight: 500;\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.running-indicator .running-dot {\n font-size: 7px;\n color: #22c55e;\n animation: pulse-dot 1.5s ease-in-out infinite;\n}\n\n@keyframes pulse-dot {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.3; }\n}\n\n/* ============================================================\n VIEWPORT SELECTOR (segmented control)\n ============================================================ */\n\n.viewport-selector {\n display: inline-flex;\n border: 1px solid var(--mat-sys-outline);\n border-radius: var(--mat-sys-corner-extra-small);\n overflow: hidden;\n background: var(--mat-sys-surface-container-lowest);\n}\n\n.viewport-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 34px;\n height: 28px;\n border: none;\n background: transparent;\n color: var(--mat-sys-on-surface-variant);\n cursor: pointer;\n font-size: 13px;\n transition: all 0.15s ease;\n}\n\n.viewport-btn:not(:last-child) {\n border-right: 1px solid var(--mat-sys-outline);\n}\n\n.viewport-btn:hover {\n background: var(--mat-sys-surface-container-high);\n color: var(--mat-sys-on-surface);\n}\n\n.viewport-btn.active {\n background: var(--mat-sys-primary);\n color: #ffffff;\n}\n\n.viewport-btn.active:hover {\n background: var(--mat-sys-primary);\n}\n\n/* ============================================================\n PREVIEW AREA\n ============================================================ */\n\n.preview-area {\n flex: 1;\n overflow: auto;\n position: relative;\n display: flex;\n justify-content: center;\n}\n\n.preview-container {\n width: 100%;\n height: 100%;\n margin: 0 auto;\n transition: max-width 0.3s ease;\n overflow: auto;\n background: var(--mat-sys-surface);\n}\n\n.preview-container.mobile,\n.preview-container.tablet {\n border-left: 1px solid var(--mat-sys-outline);\n border-right: 1px solid var(--mat-sys-outline);\n box-shadow: var(--mat-sys-elevation-1);\n}\n\n.preview-container.desktop {\n max-width: 100% !important;\n}\n\n/* ============================================================\n EMPTY STATES\n ============================================================ */\n\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n text-align: center;\n padding: 40px 24px;\n color: var(--mat-sys-on-surface-variant);\n}\n\n.empty-state i {\n margin-bottom: 16px;\n color: var(--mat-sys-outline);\n}\n\n.empty-state h3 {\n margin: 0 0 8px 0;\n font-size: 18px;\n font-weight: 600;\n color: var(--mat-sys-on-surface-variant);\n}\n\n.empty-state p {\n margin: 0;\n font-size: 14px;\n color: var(--mat-sys-on-surface-variant);\n max-width: 320px;\n line-height: 1.5;\n}\n\n.run-state h3 {\n color: var(--mat-sys-on-surface);\n}\n\n.run-component-btn {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n margin-top: 20px;\n padding: 10px 24px;\n border: none;\n border-radius: var(--mat-sys-corner-small);\n background: var(--mat-sys-primary);\n color: #ffffff;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.run-component-btn:hover {\n background: var(--mat-sys-primary);\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(99, 102, 241, 0.3);\n}\n\n.run-component-btn:active {\n transform: translateY(0);\n}\n\n.run-component-btn i {\n font-size: 13px;\n}\n\n/* ============================================================\n ERROR OVERLAY\n ============================================================ */\n\n.error-overlay {\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n z-index: 10;\n background: rgba(254, 242, 242, 0.95);\n border-top: 2px solid #f87171;\n backdrop-filter: blur(4px);\n padding: 16px 20px;\n animation: slide-up 0.2s ease-out;\n}\n\n@keyframes slide-up {\n from {\n transform: translateY(100%);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n}\n\n.error-overlay-content {\n max-width: 600px;\n}\n\n.error-overlay-header {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 6px;\n}\n\n.error-overlay-header i {\n color: #dc2626;\n font-size: 16px;\n}\n\n.error-overlay-header .error-overlay-title {\n font-size: 14px;\n font-weight: 600;\n color: #991b1b;\n}\n\n.error-overlay-message {\n margin: 0 0 12px 0;\n font-size: 13px;\n color: #7f1d1d;\n line-height: 1.4;\n}\n\n.error-overlay-actions {\n display: flex;\n gap: 8px;\n}\n"] }]
335
+ args: [{ standalone: false, selector: 'mj-component-preview', template: "<div class=\"component-preview\">\n <!-- Toolbar -->\n <div class=\"preview-toolbar\">\n <div class=\"toolbar-left\">\n @if (State.SelectedComponent) {\n @if (State.IsRunning) {\n <button class=\"toolbar-btn stop-btn\" (click)=\"StopComponent()\" title=\"Stop component\">\n <i class=\"fa-solid fa-stop\"></i>\n <span>Stop</span>\n </button>\n <button class=\"toolbar-btn\" (click)=\"RefreshComponent()\" title=\"Refresh component\">\n <i class=\"fa-solid fa-rotate-right\"></i>\n <span>Refresh</span>\n </button>\n } @else {\n <button class=\"toolbar-btn run-btn\" (click)=\"RunSelectedComponent()\" title=\"Run component\">\n <i class=\"fa-solid fa-play\"></i>\n <span>Run</span>\n </button>\n }\n }\n </div>\n\n <div class=\"toolbar-center\">\n <!-- Viewport Size Selector (segmented control) -->\n @if (State.IsRunning) {\n <div class=\"viewport-selector\">\n @for (preset of ViewportPresets; track preset.Size) {\n <button\n class=\"viewport-btn\"\n [class.active]=\"ActiveViewport === preset.Size\"\n (click)=\"SetViewport(preset.Size)\"\n [title]=\"preset.Label\">\n <i class=\"fa-solid\" [ngClass]=\"preset.Icon\"></i>\n </button>\n }\n </div>\n }\n </div>\n\n <div class=\"toolbar-right\">\n @if (State.CurrentError) {\n <button class=\"toolbar-btn ai-fix-btn\" (click)=\"SendErrorToAI()\" title=\"Ask AI to fix this error\">\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i>\n <span>Ask AI to Fix</span>\n </button>\n }\n @if (State.IsRunning && State.SelectedComponent) {\n <span class=\"running-indicator\">\n <i class=\"fa-solid fa-circle running-dot\"></i>\n {{ GetComponentName() }}\n </span>\n }\n </div>\n </div>\n\n <!-- Preview Area -->\n <div class=\"preview-area\">\n @if (!State.SelectedComponent) {\n <!-- Empty State: No component selected -->\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-eye fa-3x\"></i>\n <h3>Select a component to preview</h3>\n <p>Choose a component from the sidebar to see its live preview here.</p>\n </div>\n } @else if (!State.IsRunning) {\n <!-- Component selected but not running -->\n <div class=\"empty-state run-state\">\n <i class=\"fa-solid fa-play-circle fa-3x\"></i>\n <h3>{{ GetComponentName() }}</h3>\n <p>{{ GetComponentDescription() || 'No description available' }}</p>\n <button class=\"run-component-btn\" (click)=\"RunSelectedComponent()\">\n <i class=\"fa-solid fa-play\"></i> Run Component\n </button>\n </div>\n } @else if (LocalComponentSpec) {\n <!-- Live Preview Container -->\n <div class=\"preview-container\"\n [style.max-width]=\"GetPreviewContainerMaxWidth()\"\n [class.mobile]=\"ActiveViewport === 'mobile'\"\n [class.tablet]=\"ActiveViewport === 'tablet'\"\n [class.desktop]=\"ActiveViewport === 'desktop'\">\n <mj-react-component\n #reactComponent\n [component]=\"LocalComponentSpec\"\n (componentEvent)=\"OnComponentEvent($event)\"\n (openEntityRecord)=\"OnOpenEntityRecord($event)\">\n </mj-react-component>\n </div>\n\n <!-- Error Overlay (inline, does not replace the component) -->\n @if (State.CurrentError) {\n <div class=\"error-overlay\">\n <div class=\"error-overlay-content\">\n <div class=\"error-overlay-header\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n <span class=\"error-overlay-title\">{{ State.CurrentError.type }}</span>\n </div>\n <p class=\"error-overlay-message\">{{ State.CurrentError.message }}</p>\n <div class=\"error-overlay-actions\">\n <button class=\"toolbar-btn\" (click)=\"RefreshComponent()\">\n <i class=\"fa-solid fa-rotate-right\"></i> Retry\n </button>\n <button class=\"toolbar-btn ai-fix-btn\" (click)=\"SendErrorToAI()\">\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i> Ask AI to Fix\n </button>\n </div>\n </div>\n </div>\n }\n }\n </div>\n</div>\n", styles: [":host {\n display: block;\n width: 100%;\n height: 100%;\n}\n\n.component-preview {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--mj-bg-surface-sunken);\n overflow: hidden;\n}\n\n/* ============================================================\n TOOLBAR\n ============================================================ */\n\n.preview-toolbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 6px 12px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n min-height: 42px;\n gap: 12px;\n flex-shrink: 0;\n}\n\n.preview-toolbar .toolbar-left,\n.preview-toolbar .toolbar-center,\n.preview-toolbar .toolbar-right {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.preview-toolbar .toolbar-left {\n flex: 0 0 auto;\n}\n\n.preview-toolbar .toolbar-center {\n flex: 1 1 auto;\n justify-content: center;\n}\n\n.preview-toolbar .toolbar-right {\n flex: 0 0 auto;\n}\n\n.toolbar-btn {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 5px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n white-space: nowrap;\n}\n\n.toolbar-btn:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-border-strong);\n}\n\n.toolbar-btn i {\n font-size: 11px;\n}\n\n.run-btn {\n color: var(--mj-status-success);\n border-color: color-mix(in srgb, var(--mj-status-success) 40%, transparent);\n background: color-mix(in srgb, var(--mj-status-success) 10%, var(--mj-bg-surface));\n}\n\n.run-btn:hover {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-status-success) 60%, transparent);\n}\n\n.stop-btn {\n color: var(--mj-status-error);\n border-color: color-mix(in srgb, var(--mj-status-error) 40%, transparent);\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n}\n\n.stop-btn:hover {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-status-error) 60%, transparent);\n}\n\n.ai-fix-btn {\n color: var(--mj-brand-primary);\n border-color: color-mix(in srgb, var(--mj-brand-primary) 40%, transparent);\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.ai-fix-btn:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-brand-primary) 60%, transparent);\n}\n\n.running-indicator {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: var(--mj-text-secondary);\n font-weight: 500;\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.running-indicator .running-dot {\n font-size: 7px;\n color: var(--mj-status-success);\n animation: pulse-dot 1.5s ease-in-out infinite;\n}\n\n@keyframes pulse-dot {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.3; }\n}\n\n/* ============================================================\n VIEWPORT SELECTOR (segmented control)\n ============================================================ */\n\n.viewport-selector {\n display: inline-flex;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n overflow: hidden;\n background: var(--mj-bg-surface);\n}\n\n.viewport-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 34px;\n height: 28px;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n cursor: pointer;\n font-size: 13px;\n transition: all 0.15s ease;\n}\n\n.viewport-btn:not(:last-child) {\n border-right: 1px solid var(--mj-border-default);\n}\n\n.viewport-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n.viewport-btn.active {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.viewport-btn.active:hover {\n background: var(--mj-brand-primary);\n}\n\n/* ============================================================\n PREVIEW AREA\n ============================================================ */\n\n.preview-area {\n flex: 1;\n overflow: auto;\n position: relative;\n display: flex;\n justify-content: center;\n}\n\n.preview-container {\n width: 100%;\n height: 100%;\n margin: 0 auto;\n transition: max-width 0.3s ease;\n overflow: auto;\n background: var(--mj-bg-surface);\n}\n\n.preview-container.mobile,\n.preview-container.tablet {\n border-left: 1px solid var(--mj-border-default);\n border-right: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-sm);\n}\n\n.preview-container.desktop {\n max-width: 100% !important;\n}\n\n/* ============================================================\n EMPTY STATES\n ============================================================ */\n\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n width: 100%;\n text-align: center;\n padding: 40px 24px;\n color: var(--mj-text-secondary);\n}\n\n.empty-state i {\n margin-bottom: 16px;\n color: var(--mj-border-default);\n}\n\n.empty-state h3 {\n margin: 0 0 8px 0;\n font-size: 18px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.empty-state p {\n margin: 0;\n font-size: 14px;\n color: var(--mj-text-secondary);\n max-width: 320px;\n line-height: 1.5;\n}\n\n.run-state h3 {\n color: var(--mj-text-primary);\n}\n\n.run-component-btn {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n margin-top: 20px;\n padding: 10px 24px;\n border: none;\n border-radius: 8px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.run-component-btn:hover {\n background: var(--mj-brand-primary);\n transform: translateY(-1px);\n box-shadow: var(--mj-shadow-md);\n}\n\n.run-component-btn:active {\n transform: translateY(0);\n}\n\n.run-component-btn i {\n font-size: 13px;\n}\n\n/* ============================================================\n ERROR OVERLAY\n ============================================================ */\n\n.error-overlay {\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n z-index: 10;\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n border-top: 2px solid var(--mj-status-error);\n backdrop-filter: blur(4px);\n padding: 16px 20px;\n animation: slide-up 0.2s ease-out;\n}\n\n@keyframes slide-up {\n from {\n transform: translateY(100%);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n}\n\n.error-overlay-content {\n max-width: 600px;\n}\n\n.error-overlay-header {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 6px;\n}\n\n.error-overlay-header i {\n color: var(--mj-status-error);\n font-size: 16px;\n}\n\n.error-overlay-header .error-overlay-title {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-status-error);\n}\n\n.error-overlay-message {\n margin: 0 0 12px 0;\n font-size: 13px;\n color: var(--mj-text-primary);\n line-height: 1.4;\n}\n\n.error-overlay-actions {\n display: flex;\n gap: 8px;\n}\n"] }]
336
336
  }], () => [{ type: i1.ComponentStudioStateService }, { type: i0.ChangeDetectorRef }], { ReactComponentRef: [{
337
337
  type: ViewChild,
338
338
  args: ['reactComponent']
@@ -93,7 +93,7 @@ export class EditorTabsComponent {
93
93
  i0.ɵɵclassProp("active", ctx.state.ActiveTab === 4);
94
94
  i0.ɵɵadvance(5);
95
95
  i0.ɵɵconditional((tmp_5_0 = ctx.state.ActiveTab) === 0 ? 19 : tmp_5_0 === 1 ? 20 : tmp_5_0 === 2 ? 21 : tmp_5_0 === 3 ? 22 : tmp_5_0 === 4 ? 23 : -1);
96
- } }, dependencies: [i2.SpecEditorComponent, i3.CodeEditorPanelComponent, i4.RequirementsEditorComponent, i5.DataRequirementsEditorComponent], styles: ["[_nghost-%COMP%] {\n display: flex;\n flex: 1;\n overflow: hidden;\n }\n\n .editor-tabs-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n flex: 1;\n overflow: hidden;\n }\n\n .tab-bar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 0 8px;\n height: 38px;\n background: var(--mat-sys-surface-container-low);\n border-bottom: 1px solid var(--mat-sys-outline-variant);\n flex-shrink: 0;\n gap: 2px;\n }\n\n .tab-pill[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 5px 12px;\n border: none;\n border-radius: 8px;\n background: transparent;\n color: var(--mat-sys-on-surface-variant);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n white-space: nowrap;\n font-family: inherit;\n }\n\n .tab-pill[_ngcontent-%COMP%]:hover {\n background: var(--mat-sys-surface-container);\n color: var(--mat-sys-on-surface);\n }\n\n .tab-pill.active[_ngcontent-%COMP%] {\n background: var(--mat-sys-surface);\n color: var(--mat-sys-primary);\n font-weight: 600;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);\n }\n\n .tab-pill[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n }\n\n .tab-spacer[_ngcontent-%COMP%] {\n flex: 1;\n }\n\n .tab-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n }\n\n .tab-content[_ngcontent-%COMP%] > *[_ngcontent-%COMP%] {\n flex: 1;\n overflow: hidden;\n }"] });
96
+ } }, dependencies: [i2.SpecEditorComponent, i3.CodeEditorPanelComponent, i4.RequirementsEditorComponent, i5.DataRequirementsEditorComponent], styles: ["[_nghost-%COMP%] {\n display: flex;\n flex: 1;\n overflow: hidden;\n }\n\n .editor-tabs-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n flex: 1;\n overflow: hidden;\n }\n\n .tab-bar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 0 8px;\n height: 38px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n gap: 2px;\n }\n\n .tab-pill[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 5px 12px;\n border: none;\n border-radius: 8px;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n white-space: nowrap;\n font-family: inherit;\n }\n\n .tab-pill[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n }\n\n .tab-pill.active[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n font-weight: 600;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);\n }\n\n .tab-pill[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n }\n\n .tab-spacer[_ngcontent-%COMP%] {\n flex: 1;\n }\n\n .tab-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n }\n\n .tab-content[_ngcontent-%COMP%] > *[_ngcontent-%COMP%] {\n flex: 1;\n overflow: hidden;\n }"] });
97
97
  }
98
98
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(EditorTabsComponent, [{
99
99
  type: Component,
@@ -138,7 +138,7 @@ export class EditorTabsComponent {
138
138
  }
139
139
  </div>
140
140
  </div>
141
- `, styles: ["\n :host {\n display: flex;\n flex: 1;\n overflow: hidden;\n }\n\n .editor-tabs-container {\n display: flex;\n flex-direction: column;\n flex: 1;\n overflow: hidden;\n }\n\n .tab-bar {\n display: flex;\n align-items: center;\n padding: 0 8px;\n height: 38px;\n background: var(--mat-sys-surface-container-low);\n border-bottom: 1px solid var(--mat-sys-outline-variant);\n flex-shrink: 0;\n gap: 2px;\n }\n\n .tab-pill {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 5px 12px;\n border: none;\n border-radius: 8px;\n background: transparent;\n color: var(--mat-sys-on-surface-variant);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n white-space: nowrap;\n font-family: inherit;\n }\n\n .tab-pill:hover {\n background: var(--mat-sys-surface-container);\n color: var(--mat-sys-on-surface);\n }\n\n .tab-pill.active {\n background: var(--mat-sys-surface);\n color: var(--mat-sys-primary);\n font-weight: 600;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);\n }\n\n .tab-pill i {\n font-size: 11px;\n }\n\n .tab-spacer {\n flex: 1;\n }\n\n .tab-content {\n flex: 1;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n }\n\n .tab-content > * {\n flex: 1;\n overflow: hidden;\n }\n "] }]
141
+ `, styles: ["\n :host {\n display: flex;\n flex: 1;\n overflow: hidden;\n }\n\n .editor-tabs-container {\n display: flex;\n flex-direction: column;\n flex: 1;\n overflow: hidden;\n }\n\n .tab-bar {\n display: flex;\n align-items: center;\n padding: 0 8px;\n height: 38px;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n gap: 2px;\n }\n\n .tab-pill {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 5px 12px;\n border: none;\n border-radius: 8px;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n white-space: nowrap;\n font-family: inherit;\n }\n\n .tab-pill:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n }\n\n .tab-pill.active {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n font-weight: 600;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);\n }\n\n .tab-pill i {\n font-size: 11px;\n }\n\n .tab-spacer {\n flex: 1;\n }\n\n .tab-content {\n flex: 1;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n }\n\n .tab-content > * {\n flex: 1;\n overflow: hidden;\n }\n "] }]
142
142
  }], () => [{ type: i1.ComponentStudioStateService }, { type: i0.ChangeDetectorRef }], null); })();
143
143
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(EditorTabsComponent, { className: "EditorTabsComponent", filePath: "src/ComponentStudio/components/workspace/editor-tabs.component.ts", lineNumber: 125 }); })();
144
144
  //# sourceMappingURL=editor-tabs.component.js.map