@memberjunction/ng-dashboards 5.37.0 → 5.39.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 (328) hide show
  1. package/README.md +46 -7
  2. package/dist/AI/components/agents/agent-configuration.component.js +199 -198
  3. package/dist/AI/components/agents/agent-configuration.component.js.map +1 -1
  4. package/dist/AI/components/analytics/ai-analytics-resource.component.d.ts.map +1 -1
  5. package/dist/AI/components/analytics/ai-analytics-resource.component.js +20 -17
  6. package/dist/AI/components/analytics/ai-analytics-resource.component.js.map +1 -1
  7. package/dist/AI/components/analytics/cost-budget/cost-budget.component.d.ts +15 -0
  8. package/dist/AI/components/analytics/cost-budget/cost-budget.component.d.ts.map +1 -1
  9. package/dist/AI/components/analytics/cost-budget/cost-budget.component.js +166 -58
  10. package/dist/AI/components/analytics/cost-budget/cost-budget.component.js.map +1 -1
  11. package/dist/AI/components/analytics/executive-summary/executive-summary.component.d.ts.map +1 -1
  12. package/dist/AI/components/analytics/executive-summary/executive-summary.component.js +2 -1
  13. package/dist/AI/components/analytics/executive-summary/executive-summary.component.js.map +1 -1
  14. package/dist/AI/components/analytics/model-performance/model-performance.component.d.ts +1 -0
  15. package/dist/AI/components/analytics/model-performance/model-performance.component.d.ts.map +1 -1
  16. package/dist/AI/components/analytics/model-performance/model-performance.component.js +55 -36
  17. package/dist/AI/components/analytics/model-performance/model-performance.component.js.map +1 -1
  18. package/dist/AI/components/analytics/prompt-runs/prompt-run-analysis.component.d.ts +9 -1
  19. package/dist/AI/components/analytics/prompt-runs/prompt-run-analysis.component.d.ts.map +1 -1
  20. package/dist/AI/components/analytics/prompt-runs/prompt-run-analysis.component.js +158 -117
  21. package/dist/AI/components/analytics/prompt-runs/prompt-run-analysis.component.js.map +1 -1
  22. package/dist/AI/components/analytics/usage-patterns/usage-patterns.component.d.ts +1 -0
  23. package/dist/AI/components/analytics/usage-patterns/usage-patterns.component.d.ts.map +1 -1
  24. package/dist/AI/components/analytics/usage-patterns/usage-patterns.component.js +22 -8
  25. package/dist/AI/components/analytics/usage-patterns/usage-patterns.component.js.map +1 -1
  26. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts +89 -842
  27. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts.map +1 -1
  28. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js +1353 -7683
  29. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js.map +1 -1
  30. package/dist/AI/components/autotagging/dialogs/dry-run-preview.dialog.component.d.ts +87 -0
  31. package/dist/AI/components/autotagging/dialogs/dry-run-preview.dialog.component.d.ts.map +1 -0
  32. package/dist/AI/components/autotagging/dialogs/dry-run-preview.dialog.component.js +475 -0
  33. package/dist/AI/components/autotagging/dialogs/dry-run-preview.dialog.component.js.map +1 -0
  34. package/dist/AI/components/autotagging/dialogs/item-detail.dialog.component.d.ts +29 -0
  35. package/dist/AI/components/autotagging/dialogs/item-detail.dialog.component.d.ts.map +1 -0
  36. package/dist/AI/components/autotagging/dialogs/item-detail.dialog.component.js +208 -0
  37. package/dist/AI/components/autotagging/dialogs/item-detail.dialog.component.js.map +1 -0
  38. package/dist/AI/components/autotagging/dialogs/no-content-type-warning.dialog.component.d.ts +21 -0
  39. package/dist/AI/components/autotagging/dialogs/no-content-type-warning.dialog.component.d.ts.map +1 -0
  40. package/dist/AI/components/autotagging/dialogs/no-content-type-warning.dialog.component.js +70 -0
  41. package/dist/AI/components/autotagging/dialogs/no-content-type-warning.dialog.component.js.map +1 -0
  42. package/dist/AI/components/autotagging/dialogs/source-type-form.dialog.component.d.ts +235 -0
  43. package/dist/AI/components/autotagging/dialogs/source-type-form.dialog.component.d.ts.map +1 -0
  44. package/dist/AI/components/autotagging/dialogs/source-type-form.dialog.component.js +1735 -0
  45. package/dist/AI/components/autotagging/dialogs/source-type-form.dialog.component.js.map +1 -0
  46. package/dist/AI/components/autotagging/shared/classify.dryrun.d.ts +61 -0
  47. package/dist/AI/components/autotagging/shared/classify.dryrun.d.ts.map +1 -0
  48. package/dist/AI/components/autotagging/shared/classify.dryrun.js +78 -0
  49. package/dist/AI/components/autotagging/shared/classify.dryrun.js.map +1 -0
  50. package/dist/AI/components/autotagging/shared/classify.format.d.ts +43 -0
  51. package/dist/AI/components/autotagging/shared/classify.format.d.ts.map +1 -0
  52. package/dist/AI/components/autotagging/shared/classify.format.js +209 -0
  53. package/dist/AI/components/autotagging/shared/classify.format.js.map +1 -0
  54. package/dist/AI/components/autotagging/shared/classify.types.d.ts +276 -0
  55. package/dist/AI/components/autotagging/shared/classify.types.d.ts.map +1 -0
  56. package/dist/AI/components/autotagging/shared/classify.types.js +6 -0
  57. package/dist/AI/components/autotagging/shared/classify.types.js.map +1 -0
  58. package/dist/AI/components/autotagging/tabs/health-tab.component.d.ts +103 -0
  59. package/dist/AI/components/autotagging/tabs/health-tab.component.d.ts.map +1 -0
  60. package/dist/AI/components/autotagging/tabs/health-tab.component.js +571 -0
  61. package/dist/AI/components/autotagging/tabs/health-tab.component.js.map +1 -0
  62. package/dist/AI/components/autotagging/tabs/history-tab.component.d.ts +40 -0
  63. package/dist/AI/components/autotagging/tabs/history-tab.component.d.ts.map +1 -0
  64. package/dist/AI/components/autotagging/tabs/history-tab.component.js +402 -0
  65. package/dist/AI/components/autotagging/tabs/history-tab.component.js.map +1 -0
  66. package/dist/AI/components/autotagging/tabs/inbox-tab.component.d.ts +107 -0
  67. package/dist/AI/components/autotagging/tabs/inbox-tab.component.d.ts.map +1 -0
  68. package/dist/AI/components/autotagging/tabs/inbox-tab.component.js +719 -0
  69. package/dist/AI/components/autotagging/tabs/inbox-tab.component.js.map +1 -0
  70. package/dist/AI/components/autotagging/tabs/pipeline-tab.component.d.ts +122 -0
  71. package/dist/AI/components/autotagging/tabs/pipeline-tab.component.d.ts.map +1 -0
  72. package/dist/AI/components/autotagging/tabs/pipeline-tab.component.js +752 -0
  73. package/dist/AI/components/autotagging/tabs/pipeline-tab.component.js.map +1 -0
  74. package/dist/AI/components/autotagging/tabs/sources-tab.component.d.ts +166 -0
  75. package/dist/AI/components/autotagging/tabs/sources-tab.component.d.ts.map +1 -0
  76. package/dist/AI/components/autotagging/tabs/sources-tab.component.js +1384 -0
  77. package/dist/AI/components/autotagging/tabs/sources-tab.component.js.map +1 -0
  78. package/dist/AI/components/autotagging/tabs/tags-tab.component.d.ts +70 -0
  79. package/dist/AI/components/autotagging/tabs/tags-tab.component.d.ts.map +1 -0
  80. package/dist/AI/components/autotagging/tabs/tags-tab.component.js +448 -0
  81. package/dist/AI/components/autotagging/tabs/tags-tab.component.js.map +1 -0
  82. package/dist/AI/components/autotagging/tabs/taxonomy-tab.component.d.ts +397 -0
  83. package/dist/AI/components/autotagging/tabs/taxonomy-tab.component.d.ts.map +1 -0
  84. package/dist/AI/components/autotagging/tabs/taxonomy-tab.component.js +3490 -0
  85. package/dist/AI/components/autotagging/tabs/taxonomy-tab.component.js.map +1 -0
  86. package/dist/AI/components/autotagging/tabs/types-tab.component.d.ts +47 -0
  87. package/dist/AI/components/autotagging/tabs/types-tab.component.d.ts.map +1 -0
  88. package/dist/AI/components/autotagging/tabs/types-tab.component.js +220 -0
  89. package/dist/AI/components/autotagging/tabs/types-tab.component.js.map +1 -0
  90. package/dist/AI/components/duplicates/duplicate-detection-resource.component.js +293 -289
  91. package/dist/AI/components/duplicates/duplicate-detection-resource.component.js.map +1 -1
  92. package/dist/AI/components/models/model-management.component.js +209 -208
  93. package/dist/AI/components/models/model-management.component.js.map +1 -1
  94. package/dist/AI/components/prompts/prompt-management.component.js +130 -128
  95. package/dist/AI/components/prompts/prompt-management.component.js.map +1 -1
  96. package/dist/AI/components/requests/agent-requests-resource.component.js +61 -61
  97. package/dist/AI/components/requests/agent-requests-resource.component.js.map +1 -1
  98. package/dist/AI/components/system/system-configuration.component.js +17 -17
  99. package/dist/AI/components/system/system-configuration.component.js.map +1 -1
  100. package/dist/AI/components/tags/tags-resource.component.js +550 -532
  101. package/dist/AI/components/tags/tags-resource.component.js.map +1 -1
  102. package/dist/AI/components/vectors/vector-management-resource.component.js +1 -1
  103. package/dist/AI/components/vectors/vector-management-resource.component.js.map +1 -1
  104. package/dist/AI/services/ai-instrumentation.service.d.ts +5 -0
  105. package/dist/AI/services/ai-instrumentation.service.d.ts.map +1 -1
  106. package/dist/AI/services/ai-instrumentation.service.js +14 -2
  107. package/dist/AI/services/ai-instrumentation.service.js.map +1 -1
  108. package/dist/AI/services/cache-metrics.d.ts +50 -0
  109. package/dist/AI/services/cache-metrics.d.ts.map +1 -0
  110. package/dist/AI/services/cache-metrics.js +43 -0
  111. package/dist/AI/services/cache-metrics.js.map +1 -0
  112. package/dist/APIKeys/api-key-edit-panel.component.js +2 -2
  113. package/dist/APIKeys/api-keys-resource.component.js +132 -131
  114. package/dist/APIKeys/api-keys-resource.component.js.map +1 -1
  115. package/dist/Actions/components/actions-overview.component.js +141 -141
  116. package/dist/Actions/components/actions-overview.component.js.map +1 -1
  117. package/dist/Actions/components/execution-monitoring.component.js +15 -15
  118. package/dist/Actions/components/execution-monitoring.component.js.map +1 -1
  119. package/dist/Actions/components/explorer/action-explorer.component.d.ts +0 -5
  120. package/dist/Actions/components/explorer/action-explorer.component.d.ts.map +1 -1
  121. package/dist/Actions/components/explorer/action-explorer.component.js +139 -212
  122. package/dist/Actions/components/explorer/action-explorer.component.js.map +1 -1
  123. package/dist/Admin/admin-data-schema.component.js +2 -2
  124. package/dist/Admin/admin-data-schema.component.js.map +1 -1
  125. package/dist/Admin/admin-dev-tools-resource.component.js +2 -2
  126. package/dist/Admin/admin-dev-tools-resource.component.js.map +1 -1
  127. package/dist/Admin/admin-identity-access.component.js +2 -2
  128. package/dist/Admin/admin-identity-access.component.js.map +1 -1
  129. package/dist/Admin/admin-monitoring.component.js +2 -2
  130. package/dist/Admin/admin-monitoring.component.js.map +1 -1
  131. package/dist/ApplicationRoles/application-roles-resource.component.js +54 -49
  132. package/dist/ApplicationRoles/application-roles-resource.component.js.map +1 -1
  133. package/dist/Communication/communication-logs-resource.component.d.ts +6 -0
  134. package/dist/Communication/communication-logs-resource.component.d.ts.map +1 -1
  135. package/dist/Communication/communication-logs-resource.component.js +72 -50
  136. package/dist/Communication/communication-logs-resource.component.js.map +1 -1
  137. package/dist/Communication/communication-monitor-resource.component.js +103 -102
  138. package/dist/Communication/communication-monitor-resource.component.js.map +1 -1
  139. package/dist/Communication/communication-providers-resource.component.js +52 -51
  140. package/dist/Communication/communication-providers-resource.component.js.map +1 -1
  141. package/dist/Communication/communication-runs-resource.component.js +39 -38
  142. package/dist/Communication/communication-runs-resource.component.js.map +1 -1
  143. package/dist/Communication/communication-templates-resource.component.d.ts +6 -0
  144. package/dist/Communication/communication-templates-resource.component.d.ts.map +1 -1
  145. package/dist/Communication/communication-templates-resource.component.js +92 -89
  146. package/dist/Communication/communication-templates-resource.component.js.map +1 -1
  147. package/dist/ComponentStudio/component-studio-dashboard.component.d.ts +73 -1
  148. package/dist/ComponentStudio/component-studio-dashboard.component.d.ts.map +1 -1
  149. package/dist/ComponentStudio/component-studio-dashboard.component.js +512 -127
  150. package/dist/ComponentStudio/component-studio-dashboard.component.js.map +1 -1
  151. package/dist/ComponentStudio/component-studio-resource.component.d.ts +22 -0
  152. package/dist/ComponentStudio/component-studio-resource.component.d.ts.map +1 -0
  153. package/dist/ComponentStudio/component-studio-resource.component.js +55 -0
  154. package/dist/ComponentStudio/component-studio-resource.component.js.map +1 -0
  155. package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.d.ts +104 -45
  156. package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.d.ts.map +1 -1
  157. package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.js +234 -331
  158. package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.js.map +1 -1
  159. package/dist/ComponentStudio/components/form-builder/form-builder-canvas.component.d.ts +54 -0
  160. package/dist/ComponentStudio/components/form-builder/form-builder-canvas.component.d.ts.map +1 -0
  161. package/dist/ComponentStudio/components/form-builder/form-builder-canvas.component.js +339 -0
  162. package/dist/ComponentStudio/components/form-builder/form-builder-canvas.component.js.map +1 -0
  163. package/dist/ComponentStudio/components/form-builder/form-builder-right-panel.component.d.ts +65 -0
  164. package/dist/ComponentStudio/components/form-builder/form-builder-right-panel.component.d.ts.map +1 -0
  165. package/dist/ComponentStudio/components/form-builder/form-builder-right-panel.component.js +492 -0
  166. package/dist/ComponentStudio/components/form-builder/form-builder-right-panel.component.js.map +1 -0
  167. package/dist/ComponentStudio/components/form-builder/form-builder-tab.component.d.ts +88 -0
  168. package/dist/ComponentStudio/components/form-builder/form-builder-tab.component.d.ts.map +1 -0
  169. package/dist/ComponentStudio/components/form-builder/form-builder-tab.component.js +457 -0
  170. package/dist/ComponentStudio/components/form-builder/form-builder-tab.component.js.map +1 -0
  171. package/dist/ComponentStudio/components/form-override-dialog.component.d.ts +106 -0
  172. package/dist/ComponentStudio/components/form-override-dialog.component.d.ts.map +1 -0
  173. package/dist/ComponentStudio/components/form-override-dialog.component.js +478 -0
  174. package/dist/ComponentStudio/components/form-override-dialog.component.js.map +1 -0
  175. package/dist/ComponentStudio/components/workspace/component-preview.component.d.ts +54 -0
  176. package/dist/ComponentStudio/components/workspace/component-preview.component.d.ts.map +1 -1
  177. package/dist/ComponentStudio/components/workspace/component-preview.component.js +361 -50
  178. package/dist/ComponentStudio/components/workspace/component-preview.component.js.map +1 -1
  179. package/dist/ComponentStudio/components/workspace/editor-tabs.component.d.ts +10 -0
  180. package/dist/ComponentStudio/components/workspace/editor-tabs.component.d.ts.map +1 -1
  181. package/dist/ComponentStudio/components/workspace/editor-tabs.component.js +114 -45
  182. package/dist/ComponentStudio/components/workspace/editor-tabs.component.js.map +1 -1
  183. package/dist/ComponentStudio/services/canvas-to-code.d.ts +32 -0
  184. package/dist/ComponentStudio/services/canvas-to-code.d.ts.map +1 -0
  185. package/dist/ComponentStudio/services/canvas-to-code.js +347 -0
  186. package/dist/ComponentStudio/services/canvas-to-code.js.map +1 -0
  187. package/dist/ComponentStudio/services/code-to-canvas.d.ts +32 -0
  188. package/dist/ComponentStudio/services/code-to-canvas.d.ts.map +1 -0
  189. package/dist/ComponentStudio/services/code-to-canvas.js +92 -0
  190. package/dist/ComponentStudio/services/code-to-canvas.js.map +1 -0
  191. package/dist/ComponentStudio/services/component-studio-state.service.d.ts +29 -0
  192. package/dist/ComponentStudio/services/component-studio-state.service.d.ts.map +1 -1
  193. package/dist/ComponentStudio/services/component-studio-state.service.js +76 -0
  194. package/dist/ComponentStudio/services/component-studio-state.service.js.map +1 -1
  195. package/dist/ComponentStudio/services/entity-form-override.service.d.ts +86 -0
  196. package/dist/ComponentStudio/services/entity-form-override.service.d.ts.map +1 -0
  197. package/dist/ComponentStudio/services/entity-form-override.service.js +246 -0
  198. package/dist/ComponentStudio/services/entity-form-override.service.js.map +1 -0
  199. package/dist/ComponentStudio/services/field-binding-scanner.d.ts +29 -0
  200. package/dist/ComponentStudio/services/field-binding-scanner.d.ts.map +1 -0
  201. package/dist/ComponentStudio/services/field-binding-scanner.js +110 -0
  202. package/dist/ComponentStudio/services/field-binding-scanner.js.map +1 -0
  203. package/dist/ComponentStudio/services/form-canvas-model.d.ts +56 -0
  204. package/dist/ComponentStudio/services/form-canvas-model.d.ts.map +1 -0
  205. package/dist/ComponentStudio/services/form-canvas-model.js +35 -0
  206. package/dist/ComponentStudio/services/form-canvas-model.js.map +1 -0
  207. package/dist/ComponentStudio/services/form-host-props-fixture.d.ts +10 -0
  208. package/dist/ComponentStudio/services/form-host-props-fixture.d.ts.map +1 -0
  209. package/dist/ComponentStudio/services/form-host-props-fixture.js +10 -0
  210. package/dist/ComponentStudio/services/form-host-props-fixture.js.map +1 -0
  211. package/dist/Credentials/components/credentials-audit-resource.component.js +136 -135
  212. package/dist/Credentials/components/credentials-audit-resource.component.js.map +1 -1
  213. package/dist/Credentials/components/credentials-categories-resource.component.js +155 -152
  214. package/dist/Credentials/components/credentials-categories-resource.component.js.map +1 -1
  215. package/dist/Credentials/components/credentials-list-resource.component.js +119 -118
  216. package/dist/Credentials/components/credentials-list-resource.component.js.map +1 -1
  217. package/dist/Credentials/components/credentials-overview-resource.component.js +129 -128
  218. package/dist/Credentials/components/credentials-overview-resource.component.js.map +1 -1
  219. package/dist/Credentials/components/credentials-types-resource.component.js +107 -106
  220. package/dist/Credentials/components/credentials-types-resource.component.js.map +1 -1
  221. package/dist/DataExplorer/data-explorer-dashboard.component.js +2 -2
  222. package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
  223. package/dist/DatabaseDesigner/components/database-designer-dashboard.component.js +1 -1
  224. package/dist/DatabaseDesigner/components/entity-list.component.js +115 -114
  225. package/dist/DatabaseDesigner/components/entity-list.component.js.map +1 -1
  226. package/dist/DatabaseDesigner/database-designer-dashboards.module.d.ts +5 -6
  227. package/dist/DatabaseDesigner/database-designer-dashboards.module.d.ts.map +1 -1
  228. package/dist/DatabaseDesigner/database-designer-dashboards.module.js +4 -5
  229. package/dist/DatabaseDesigner/database-designer-dashboards.module.js.map +1 -1
  230. package/dist/DevTools/app-state-inspector.component.js +18 -17
  231. package/dist/DevTools/app-state-inspector.component.js.map +1 -1
  232. package/dist/DevTools/class-registry.component.js +88 -85
  233. package/dist/DevTools/class-registry.component.js.map +1 -1
  234. package/dist/DevTools/event-monitor.component.js +155 -150
  235. package/dist/DevTools/event-monitor.component.js.map +1 -1
  236. package/dist/DevTools/graphql-console.component.js +245 -243
  237. package/dist/DevTools/graphql-console.component.js.map +1 -1
  238. package/dist/DevTools/layout-inspector.component.js +18 -17
  239. package/dist/DevTools/layout-inspector.component.js.map +1 -1
  240. package/dist/EntityAdmin/entity-admin-dashboard.component.js +20 -19
  241. package/dist/EntityAdmin/entity-admin-dashboard.component.js.map +1 -1
  242. package/dist/FormBuilder/form-builder-resource.component.d.ts +964 -0
  243. package/dist/FormBuilder/form-builder-resource.component.d.ts.map +1 -0
  244. package/dist/FormBuilder/form-builder-resource.component.js +4487 -0
  245. package/dist/FormBuilder/form-builder-resource.component.js.map +1 -0
  246. package/dist/FormBuilder/form-builder-version-rail.helpers.d.ts +55 -0
  247. package/dist/FormBuilder/form-builder-version-rail.helpers.d.ts.map +1 -0
  248. package/dist/FormBuilder/form-builder-version-rail.helpers.js +73 -0
  249. package/dist/FormBuilder/form-builder-version-rail.helpers.js.map +1 -0
  250. package/dist/Home/home-application.d.ts +21 -1
  251. package/dist/Home/home-application.d.ts.map +1 -1
  252. package/dist/Home/home-application.js +60 -8
  253. package/dist/Home/home-application.js.map +1 -1
  254. package/dist/Home/home-dashboard.component.js +2 -2
  255. package/dist/Integration/components/activity/activity.component.d.ts.map +1 -1
  256. package/dist/Integration/components/activity/activity.component.js +236 -229
  257. package/dist/Integration/components/activity/activity.component.js.map +1 -1
  258. package/dist/Integration/components/connections/connections.component.js +390 -389
  259. package/dist/Integration/components/connections/connections.component.js.map +1 -1
  260. package/dist/Integration/components/overview/overview.component.js +2 -2
  261. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js +2 -2
  262. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js.map +1 -1
  263. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js +45 -44
  264. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js.map +1 -1
  265. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js +293 -291
  266. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js.map +1 -1
  267. package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.js +62 -61
  268. package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.js.map +1 -1
  269. package/dist/Lists/components/lists-browse-resource.component.d.ts +6 -2
  270. package/dist/Lists/components/lists-browse-resource.component.d.ts.map +1 -1
  271. package/dist/Lists/components/lists-browse-resource.component.js +525 -566
  272. package/dist/Lists/components/lists-browse-resource.component.js.map +1 -1
  273. package/dist/Lists/components/lists-categories-resource.component.js +135 -134
  274. package/dist/Lists/components/lists-categories-resource.component.js.map +1 -1
  275. package/dist/Lists/components/lists-my-lists-resource.component.js +199 -198
  276. package/dist/Lists/components/lists-my-lists-resource.component.js.map +1 -1
  277. package/dist/MCP/mcp-dashboard.component.js +443 -438
  278. package/dist/MCP/mcp-dashboard.component.js.map +1 -1
  279. package/dist/QueryBrowser/query-browser-resource.component.d.ts +14 -14
  280. package/dist/QueryBrowser/query-browser-resource.component.d.ts.map +1 -1
  281. package/dist/QueryBrowser/query-browser-resource.component.js +11 -10
  282. package/dist/QueryBrowser/query-browser-resource.component.js.map +1 -1
  283. package/dist/Scheduling/components/scheduling-activity.component.d.ts.map +1 -1
  284. package/dist/Scheduling/components/scheduling-activity.component.js +146 -147
  285. package/dist/Scheduling/components/scheduling-activity.component.js.map +1 -1
  286. package/dist/Scheduling/components/scheduling-jobs.component.js +76 -75
  287. package/dist/Scheduling/components/scheduling-jobs.component.js.map +1 -1
  288. package/dist/Scheduling/components/scheduling-overview.component.js +97 -96
  289. package/dist/Scheduling/components/scheduling-overview.component.js.map +1 -1
  290. package/dist/Scheduling/scheduling-dashboard.component.js +24 -22
  291. package/dist/Scheduling/scheduling-dashboard.component.js.map +1 -1
  292. package/dist/Scheduling/services/scheduling-instrumentation.service.d.ts +2 -0
  293. package/dist/Scheduling/services/scheduling-instrumentation.service.d.ts.map +1 -1
  294. package/dist/Scheduling/services/scheduling-instrumentation.service.js +1 -0
  295. package/dist/Scheduling/services/scheduling-instrumentation.service.js.map +1 -1
  296. package/dist/Testing/components/testing-dashboard-tab-resource.component.js +1 -1
  297. package/dist/Testing/components/testing-explorer.component.d.ts +14 -4
  298. package/dist/Testing/components/testing-explorer.component.d.ts.map +1 -1
  299. package/dist/Testing/components/testing-explorer.component.js +436 -427
  300. package/dist/Testing/components/testing-explorer.component.js.map +1 -1
  301. package/dist/Testing/components/testing-runs-resource.component.js +1 -1
  302. package/dist/Testing/components/testing-runs.component.js +116 -115
  303. package/dist/Testing/components/testing-runs.component.js.map +1 -1
  304. package/dist/Testing/testing-dashboard.component.js +6 -7
  305. package/dist/Testing/testing-dashboard.component.js.map +1 -1
  306. package/dist/VersionHistory/components/labels-resource.component.js +173 -172
  307. package/dist/VersionHistory/components/labels-resource.component.js.map +1 -1
  308. package/dist/VersionHistory/components/restore-resource.component.d.ts +6 -0
  309. package/dist/VersionHistory/components/restore-resource.component.d.ts.map +1 -1
  310. package/dist/VersionHistory/components/restore-resource.component.js +116 -92
  311. package/dist/VersionHistory/components/restore-resource.component.js.map +1 -1
  312. package/dist/ai-dashboards.module.d.ts +47 -35
  313. package/dist/ai-dashboards.module.d.ts.map +1 -1
  314. package/dist/ai-dashboards.module.js +40 -1
  315. package/dist/ai-dashboards.module.js.map +1 -1
  316. package/dist/communication-dashboards.module.d.ts +1 -1
  317. package/dist/communication-dashboards.module.d.ts.map +1 -1
  318. package/dist/communication-dashboards.module.js +7 -1
  319. package/dist/communication-dashboards.module.js.map +1 -1
  320. package/dist/component-studio-dashboards.module.d.ts +34 -22
  321. package/dist/component-studio-dashboards.module.d.ts.map +1 -1
  322. package/dist/component-studio-dashboards.module.js +65 -9
  323. package/dist/component-studio-dashboards.module.js.map +1 -1
  324. package/dist/testing-dashboards.module.d.ts +4 -5
  325. package/dist/testing-dashboards.module.d.ts.map +1 -1
  326. package/dist/testing-dashboards.module.js +7 -5
  327. package/dist/testing-dashboards.module.js.map +1 -1
  328. package/package.json +55 -53
@@ -13,33 +13,36 @@ import { Subject, takeUntil } from 'rxjs';
13
13
  import { ComponentStudioStateService } from './services/component-studio-state.service';
14
14
  import { ComponentVersionService } from './services/component-version.service';
15
15
  import { RunView } from '@memberjunction/core';
16
+ import { generateCanvasId, } from './services/form-canvas-model';
17
+ import { generateCodeFromCanvas } from './services/canvas-to-code';
16
18
  import * as i0 from "@angular/core";
17
19
  import * as i1 from "./services/component-studio-state.service";
18
20
  import * as i2 from "./services/component-version.service";
19
21
  import * as i3 from "@memberjunction/ng-notifications";
22
+ import * as i4 from "./services/entity-form-override.service";
20
23
  const _c0 = ["fileInput"];
21
24
  function ComponentStudioDashboardComponent_Conditional_5_Conditional_7_Template(rf, ctx) { if (rf & 1) {
22
- i0.ɵɵelementStart(0, "span", 38);
23
- i0.ɵɵelement(1, "span", 40);
25
+ i0.ɵɵelementStart(0, "span", 37);
26
+ i0.ɵɵelement(1, "span", 39);
24
27
  i0.ɵɵtext(2, " Running ");
25
28
  i0.ɵɵelementEnd();
26
29
  } }
27
30
  function ComponentStudioDashboardComponent_Conditional_5_Conditional_8_Template(rf, ctx) { if (rf & 1) {
28
- i0.ɵɵelement(0, "span", 39);
31
+ i0.ɵɵelement(0, "span", 38);
29
32
  } }
30
33
  function ComponentStudioDashboardComponent_Conditional_5_Template(rf, ctx) { if (rf & 1) {
31
- i0.ɵɵelementStart(0, "span", 34);
32
- i0.ɵɵelement(1, "i", 27);
34
+ i0.ɵɵelementStart(0, "span", 33);
35
+ i0.ɵɵelement(1, "i", 25);
33
36
  i0.ɵɵtext(2);
34
37
  i0.ɵɵelementEnd();
35
- i0.ɵɵelementStart(3, "span", 35);
36
- i0.ɵɵelement(4, "i", 36);
38
+ i0.ɵɵelementStart(3, "span", 34);
39
+ i0.ɵɵelement(4, "i", 35);
37
40
  i0.ɵɵelementEnd();
38
- i0.ɵɵelementStart(5, "span", 37);
41
+ i0.ɵɵelementStart(5, "span", 36);
39
42
  i0.ɵɵtext(6);
40
43
  i0.ɵɵelementEnd();
41
- i0.ɵɵconditionalCreate(7, ComponentStudioDashboardComponent_Conditional_5_Conditional_7_Template, 3, 0, "span", 38);
42
- i0.ɵɵconditionalCreate(8, ComponentStudioDashboardComponent_Conditional_5_Conditional_8_Template, 1, 0, "span", 39);
44
+ i0.ɵɵconditionalCreate(7, ComponentStudioDashboardComponent_Conditional_5_Conditional_7_Template, 3, 0, "span", 37);
45
+ i0.ɵɵconditionalCreate(8, ComponentStudioDashboardComponent_Conditional_5_Conditional_8_Template, 1, 0, "span", 38);
43
46
  } if (rf & 2) {
44
47
  const ctx_r1 = i0.ɵɵnextContext();
45
48
  i0.ɵɵadvance(2);
@@ -53,15 +56,15 @@ function ComponentStudioDashboardComponent_Conditional_5_Template(rf, ctx) { if
53
56
  } }
54
57
  function ComponentStudioDashboardComponent_Conditional_8_Template(rf, ctx) { if (rf & 1) {
55
58
  const _r3 = i0.ɵɵgetCurrentView();
56
- i0.ɵɵelementStart(0, "button", 41);
59
+ i0.ɵɵelementStart(0, "button", 40);
57
60
  i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_8_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.SaveVersion()); });
58
- i0.ɵɵelement(1, "i", 42);
61
+ i0.ɵɵelement(1, "i", 41);
59
62
  i0.ɵɵtext(2, " Save ");
60
63
  i0.ɵɵelementEnd();
61
64
  } }
62
65
  function ComponentStudioDashboardComponent_Conditional_9_Template(rf, ctx) { if (rf & 1) {
63
66
  const _r4 = i0.ɵɵgetCurrentView();
64
- i0.ɵɵelementStart(0, "button", 43);
67
+ i0.ɵɵelementStart(0, "button", 42);
65
68
  i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_9_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.RefreshComponent()); });
66
69
  i0.ɵɵelement(1, "i", 17);
67
70
  i0.ɵɵtext(2, " Refresh ");
@@ -69,31 +72,31 @@ function ComponentStudioDashboardComponent_Conditional_9_Template(rf, ctx) { if
69
72
  } }
70
73
  function ComponentStudioDashboardComponent_Conditional_10_Conditional_5_Template(rf, ctx) { if (rf & 1) {
71
74
  const _r6 = i0.ɵɵgetCurrentView();
72
- i0.ɵɵelementStart(0, "div", 48)(1, "button", 49);
75
+ i0.ɵɵelementStart(0, "div", 47)(1, "button", 48);
73
76
  i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_10_Conditional_5_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.ExportToArtifact()); });
74
- i0.ɵɵelement(2, "i", 42);
77
+ i0.ɵɵelement(2, "i", 41);
75
78
  i0.ɵɵtext(3, " To Artifact ");
76
79
  i0.ɵɵelementEnd();
77
- i0.ɵɵelementStart(4, "button", 49);
80
+ i0.ɵɵelementStart(4, "button", 48);
78
81
  i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_10_Conditional_5_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.ExportToFile()); });
79
- i0.ɵɵelement(5, "i", 50);
82
+ i0.ɵɵelement(5, "i", 49);
80
83
  i0.ɵɵtext(6, " To File ");
81
84
  i0.ɵɵelementEnd();
82
- i0.ɵɵelementStart(7, "button", 49);
85
+ i0.ɵɵelementStart(7, "button", 48);
83
86
  i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_10_Conditional_5_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.ExportToClipboard()); });
84
- i0.ɵɵelement(8, "i", 51);
87
+ i0.ɵɵelement(8, "i", 50);
85
88
  i0.ɵɵtext(9, " To Clipboard ");
86
89
  i0.ɵɵelementEnd()();
87
90
  } }
88
91
  function ComponentStudioDashboardComponent_Conditional_10_Template(rf, ctx) { if (rf & 1) {
89
92
  const _r5 = i0.ɵɵgetCurrentView();
90
- i0.ɵɵelementStart(0, "div", 44)(1, "button", 45);
93
+ i0.ɵɵelementStart(0, "div", 43)(1, "button", 44);
91
94
  i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_10_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ToggleExportDropdown()); });
92
- i0.ɵɵelement(2, "i", 46);
95
+ i0.ɵɵelement(2, "i", 45);
93
96
  i0.ɵɵtext(3, " Export ");
94
- i0.ɵɵelement(4, "i", 47);
97
+ i0.ɵɵelement(4, "i", 46);
95
98
  i0.ɵɵelementEnd();
96
- i0.ɵɵconditionalCreate(5, ComponentStudioDashboardComponent_Conditional_10_Conditional_5_Template, 10, 0, "div", 48);
99
+ i0.ɵɵconditionalCreate(5, ComponentStudioDashboardComponent_Conditional_10_Conditional_5_Template, 10, 0, "div", 47);
97
100
  i0.ɵɵelementEnd();
98
101
  } if (rf & 2) {
99
102
  const ctx_r1 = i0.ɵɵnextContext();
@@ -103,10 +106,10 @@ function ComponentStudioDashboardComponent_Conditional_10_Template(rf, ctx) { if
103
106
  } }
104
107
  function ComponentStudioDashboardComponent_Conditional_21_Template(rf, ctx) { if (rf & 1) {
105
108
  const _r7 = i0.ɵɵgetCurrentView();
106
- i0.ɵɵelementStart(0, "div", 52)(1, "mj-component-browser", 53);
109
+ i0.ɵɵelementStart(0, "div", 51)(1, "mj-component-browser", 52);
107
110
  i0.ɵɵlistener("NewComponent", function ComponentStudioDashboardComponent_Conditional_21_Template_mj_component_browser_NewComponent_1_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnNewComponent()); })("ImportFromFile", function ComponentStudioDashboardComponent_Conditional_21_Template_mj_component_browser_ImportFromFile_1_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ImportFromFile()); })("ImportFromText", function ComponentStudioDashboardComponent_Conditional_21_Template_mj_component_browser_ImportFromText_1_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ImportFromText()); })("ImportFromArtifact", function ComponentStudioDashboardComponent_Conditional_21_Template_mj_component_browser_ImportFromArtifact_1_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ImportFromArtifact()); });
108
111
  i0.ɵɵelementEnd()();
109
- i0.ɵɵelementStart(2, "div", 54);
112
+ i0.ɵɵelementStart(2, "div", 53);
110
113
  i0.ɵɵlistener("mousedown", function ComponentStudioDashboardComponent_Conditional_21_Template_div_mousedown_2_listener($event) { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnLeftResizeStart($event)); });
111
114
  i0.ɵɵelementEnd();
112
115
  } if (rf & 2) {
@@ -115,13 +118,13 @@ function ComponentStudioDashboardComponent_Conditional_21_Template(rf, ctx) { if
115
118
  } }
116
119
  function ComponentStudioDashboardComponent_Conditional_23_Conditional_11_Template(rf, ctx) { if (rf & 1) {
117
120
  const _r9 = i0.ɵɵgetCurrentView();
118
- i0.ɵɵelementStart(0, "div", 66);
121
+ i0.ɵɵelementStart(0, "div", 65);
119
122
  i0.ɵɵlistener("mousedown", function ComponentStudioDashboardComponent_Conditional_23_Conditional_11_Template_div_mousedown_0_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnCenterResizeStart($event)); });
120
- i0.ɵɵelement(1, "div", 67);
123
+ i0.ɵɵelement(1, "div", 66);
121
124
  i0.ɵɵelementEnd();
122
125
  } }
123
126
  function ComponentStudioDashboardComponent_Conditional_23_Conditional_12_Template(rf, ctx) { if (rf & 1) {
124
- i0.ɵɵelementStart(0, "div", 68);
127
+ i0.ɵɵelementStart(0, "div", 67);
125
128
  i0.ɵɵelement(1, "mj-editor-tabs");
126
129
  i0.ɵɵelementEnd();
127
130
  } if (rf & 2) {
@@ -130,20 +133,20 @@ function ComponentStudioDashboardComponent_Conditional_23_Conditional_12_Templat
130
133
  } }
131
134
  function ComponentStudioDashboardComponent_Conditional_23_Template(rf, ctx) { if (rf & 1) {
132
135
  const _r8 = i0.ɵɵgetCurrentView();
133
- i0.ɵɵelementStart(0, "div", 55)(1, "div", 56)(2, "div", 57);
134
- i0.ɵɵelement(3, "i", 58);
136
+ i0.ɵɵelementStart(0, "div", 54)(1, "div", 55)(2, "div", 56);
137
+ i0.ɵɵelement(3, "i", 57);
135
138
  i0.ɵɵelementStart(4, "span");
136
139
  i0.ɵɵtext(5, "Preview");
137
140
  i0.ɵɵelementEnd()();
138
- i0.ɵɵelementStart(6, "div", 59)(7, "button", 60);
141
+ i0.ɵɵelementStart(6, "div", 58)(7, "button", 59);
139
142
  i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_23_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ToggleEditorPanel()); });
140
- i0.ɵɵelement(8, "i", 61);
143
+ i0.ɵɵelement(8, "i", 60);
141
144
  i0.ɵɵelementEnd()()();
142
- i0.ɵɵelementStart(9, "div", 62)(10, "mj-component-preview", 63);
145
+ i0.ɵɵelementStart(9, "div", 61)(10, "mj-component-preview", 62);
143
146
  i0.ɵɵlistener("AskAIToFix", function ComponentStudioDashboardComponent_Conditional_23_Template_mj_component_preview_AskAIToFix_10_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnAskAIToFix($event)); });
144
147
  i0.ɵɵelementEnd()()();
145
- i0.ɵɵconditionalCreate(11, ComponentStudioDashboardComponent_Conditional_23_Conditional_11_Template, 2, 0, "div", 64);
146
- i0.ɵɵconditionalCreate(12, ComponentStudioDashboardComponent_Conditional_23_Conditional_12_Template, 2, 2, "div", 65);
148
+ i0.ɵɵconditionalCreate(11, ComponentStudioDashboardComponent_Conditional_23_Conditional_11_Template, 2, 0, "div", 63);
149
+ i0.ɵɵconditionalCreate(12, ComponentStudioDashboardComponent_Conditional_23_Conditional_12_Template, 2, 2, "div", 64);
147
150
  } if (rf & 2) {
148
151
  const ctx_r1 = i0.ɵɵnextContext();
149
152
  i0.ɵɵstyleProp("flex", ctx_r1.IsEditorPanelCollapsed ? "1 1 100%" : ctx_r1.previewFlex);
@@ -157,8 +160,8 @@ function ComponentStudioDashboardComponent_Conditional_23_Template(rf, ctx) { if
157
160
  } }
158
161
  function ComponentStudioDashboardComponent_Conditional_24_Template(rf, ctx) { if (rf & 1) {
159
162
  const _r10 = i0.ɵɵgetCurrentView();
160
- i0.ɵɵelementStart(0, "div", 21)(1, "div", 69)(2, "div", 70);
161
- i0.ɵɵelement(3, "i", 71);
163
+ i0.ɵɵelementStart(0, "div", 21)(1, "div", 68)(2, "div", 69);
164
+ i0.ɵɵelement(3, "i", 70);
162
165
  i0.ɵɵelementEnd();
163
166
  i0.ɵɵelementStart(4, "h2");
164
167
  i0.ɵɵtext(5, "Ready to Build");
@@ -166,57 +169,70 @@ function ComponentStudioDashboardComponent_Conditional_24_Template(rf, ctx) { if
166
169
  i0.ɵɵelementStart(6, "p");
167
170
  i0.ɵɵtext(7, "Select a component from the browser or create a new one to get started");
168
171
  i0.ɵɵelementEnd();
169
- i0.ɵɵelementStart(8, "div", 72)(9, "button", 73);
172
+ i0.ɵɵelementStart(8, "div", 71)(9, "button", 72);
170
173
  i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_24_Template_button_click_9_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnNewComponent()); });
171
- i0.ɵɵelement(10, "span", 74);
174
+ i0.ɵɵelement(10, "span", 73);
172
175
  i0.ɵɵtext(11, " New Component ");
173
176
  i0.ɵɵelementEnd();
174
- i0.ɵɵelementStart(12, "button", 75);
177
+ i0.ɵɵelementStart(12, "button", 74);
175
178
  i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_24_Template_button_click_12_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ImportFromFile()); });
176
- i0.ɵɵelement(13, "span", 76);
179
+ i0.ɵɵelement(13, "span", 75);
177
180
  i0.ɵɵtext(14, " Import ");
178
181
  i0.ɵɵelementEnd()();
179
- i0.ɵɵelementStart(15, "div", 77)(16, "span", 78);
182
+ i0.ɵɵelementStart(15, "div", 76)(16, "span", 77);
180
183
  i0.ɵɵtext(17, "Quick start:");
181
184
  i0.ɵɵelementEnd();
182
- i0.ɵɵelementStart(18, "button", 79);
185
+ i0.ɵɵelementStart(18, "button", 78);
183
186
  i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_24_Template_button_click_18_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnQuickStart("dashboard")); });
184
- i0.ɵɵelement(19, "i", 80);
187
+ i0.ɵɵelement(19, "i", 79);
185
188
  i0.ɵɵtext(20, " Dashboard ");
186
189
  i0.ɵɵelementEnd();
187
- i0.ɵɵelementStart(21, "button", 79);
190
+ i0.ɵɵelementStart(21, "button", 78);
188
191
  i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_24_Template_button_click_21_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnQuickStart("report")); });
189
- i0.ɵɵelement(22, "i", 81);
192
+ i0.ɵɵelement(22, "i", 80);
190
193
  i0.ɵɵtext(23, " Report ");
191
194
  i0.ɵɵelementEnd();
192
- i0.ɵɵelementStart(24, "button", 79);
195
+ i0.ɵɵelementStart(24, "button", 78);
193
196
  i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_24_Template_button_click_24_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnQuickStart("chart")); });
194
- i0.ɵɵelement(25, "i", 82);
197
+ i0.ɵɵelement(25, "i", 81);
195
198
  i0.ɵɵtext(26, " Chart ");
196
199
  i0.ɵɵelementEnd();
197
- i0.ɵɵelementStart(27, "button", 79);
200
+ i0.ɵɵelementStart(27, "button", 78);
198
201
  i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_24_Template_button_click_27_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnQuickStart("form")); });
199
- i0.ɵɵelement(28, "i", 83);
202
+ i0.ɵɵelement(28, "i", 82);
200
203
  i0.ɵɵtext(29, " Form ");
201
204
  i0.ɵɵelementEnd()()()();
202
205
  } }
206
+ function ComponentStudioDashboardComponent_Conditional_25_Conditional_2_Template(rf, ctx) { if (rf & 1) {
207
+ const _r12 = i0.ɵɵgetCurrentView();
208
+ i0.ɵɵelementStart(0, "mj-form-builder-right-panel", 85);
209
+ i0.ɵɵlistener("ElementChanged", function ComponentStudioDashboardComponent_Conditional_25_Conditional_2_Template_mj_form_builder_right_panel_ElementChanged_0_listener($event) { i0.ɵɵrestoreView(_r12); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnFormBuilderElementChanged($event)); })("SectionChanged", function ComponentStudioDashboardComponent_Conditional_25_Conditional_2_Template_mj_form_builder_right_panel_SectionChanged_0_listener($event) { i0.ɵɵrestoreView(_r12); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnFormBuilderSectionChanged($event)); })("ElementDeleted", function ComponentStudioDashboardComponent_Conditional_25_Conditional_2_Template_mj_form_builder_right_panel_ElementDeleted_0_listener($event) { i0.ɵɵrestoreView(_r12); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnFormBuilderElementDeleted($event)); })("SectionDeleted", function ComponentStudioDashboardComponent_Conditional_25_Conditional_2_Template_mj_form_builder_right_panel_SectionDeleted_0_listener($event) { i0.ɵɵrestoreView(_r12); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnFormBuilderSectionDeleted($event)); })("FieldAdded", function ComponentStudioDashboardComponent_Conditional_25_Conditional_2_Template_mj_form_builder_right_panel_FieldAdded_0_listener($event) { i0.ɵɵrestoreView(_r12); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnFormBuilderFieldAdded($event)); });
210
+ i0.ɵɵelementEnd();
211
+ } if (rf & 2) {
212
+ const ctx_r1 = i0.ɵɵnextContext(2);
213
+ i0.ɵɵproperty("Schema", ctx_r1.state.FormSchema)("Canvas", ctx_r1.state.FormCanvas)("SelectedElementId", ctx_r1.state.FormSelectedElementId)("SelectedSectionId", ctx_r1.state.FormSelectedSectionId);
214
+ } }
215
+ function ComponentStudioDashboardComponent_Conditional_25_Conditional_3_Template(rf, ctx) { if (rf & 1) {
216
+ i0.ɵɵelement(0, "mj-ai-assistant-panel");
217
+ } }
203
218
  function ComponentStudioDashboardComponent_Conditional_25_Template(rf, ctx) { if (rf & 1) {
204
219
  const _r11 = i0.ɵɵgetCurrentView();
205
- i0.ɵɵelementStart(0, "div", 54);
220
+ i0.ɵɵelementStart(0, "div", 53);
206
221
  i0.ɵɵlistener("mousedown", function ComponentStudioDashboardComponent_Conditional_25_Template_div_mousedown_0_listener($event) { i0.ɵɵrestoreView(_r11); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnRightResizeStart($event)); });
207
222
  i0.ɵɵelementEnd();
208
- } }
209
- function ComponentStudioDashboardComponent_Conditional_26_Template(rf, ctx) { if (rf & 1) {
210
- i0.ɵɵelementStart(0, "div", 84);
211
- i0.ɵɵelement(1, "mj-ai-assistant-panel");
223
+ i0.ɵɵelementStart(1, "div", 83);
224
+ i0.ɵɵconditionalCreate(2, ComponentStudioDashboardComponent_Conditional_25_Conditional_2_Template, 1, 4, "mj-form-builder-right-panel", 84)(3, ComponentStudioDashboardComponent_Conditional_25_Conditional_3_Template, 1, 0, "mj-ai-assistant-panel");
212
225
  i0.ɵɵelementEnd();
213
226
  } if (rf & 2) {
214
227
  const ctx_r1 = i0.ɵɵnextContext();
228
+ i0.ɵɵadvance();
215
229
  i0.ɵɵstyleProp("width", ctx_r1.rightPanelWidth, "px");
230
+ i0.ɵɵadvance();
231
+ i0.ɵɵconditional(ctx_r1.IsFormRoleComponent ? 2 : 3);
216
232
  } }
217
- function ComponentStudioDashboardComponent_Conditional_33_Template(rf, ctx) { if (rf & 1) {
218
- i0.ɵɵelementStart(0, "span", 26);
219
- i0.ɵɵelement(1, "i", 85);
233
+ function ComponentStudioDashboardComponent_Conditional_32_Template(rf, ctx) { if (rf & 1) {
234
+ i0.ɵɵelementStart(0, "span", 24);
235
+ i0.ɵɵelement(1, "i", 86);
220
236
  i0.ɵɵtext(2);
221
237
  i0.ɵɵpipe(3, "date");
222
238
  i0.ɵɵelementEnd();
@@ -225,96 +241,96 @@ function ComponentStudioDashboardComponent_Conditional_33_Template(rf, ctx) { if
225
241
  i0.ɵɵadvance(2);
226
242
  i0.ɵɵtextInterpolate1(" Saved ", i0.ɵɵpipeBind2(3, 1, ctx_r1.LastSavedTime, "shortTime"), " ");
227
243
  } }
228
- function ComponentStudioDashboardComponent_Conditional_38_Template(rf, ctx) { if (rf & 1) {
229
- const _r12 = i0.ɵɵgetCurrentView();
230
- i0.ɵɵelementStart(0, "div", 86);
231
- i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_38_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r12); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ShowKeyboardShortcuts = false); });
232
- i0.ɵɵelementStart(1, "div", 87);
233
- i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_38_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r12); return i0.ɵɵresetView($event.stopPropagation()); });
234
- i0.ɵɵelementStart(2, "div", 88)(3, "h3");
244
+ function ComponentStudioDashboardComponent_Conditional_37_Template(rf, ctx) { if (rf & 1) {
245
+ const _r13 = i0.ɵɵgetCurrentView();
246
+ i0.ɵɵelementStart(0, "div", 87);
247
+ i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_37_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ShowKeyboardShortcuts = false); });
248
+ i0.ɵɵelementStart(1, "div", 88);
249
+ i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_37_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r13); return i0.ɵɵresetView($event.stopPropagation()); });
250
+ i0.ɵɵelementStart(2, "div", 89)(3, "h3");
235
251
  i0.ɵɵtext(4, "Keyboard Shortcuts");
236
252
  i0.ɵɵelementEnd();
237
- i0.ɵɵelementStart(5, "button", 89);
238
- i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_38_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r12); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ShowKeyboardShortcuts = false); });
239
- i0.ɵɵelement(6, "i", 90);
253
+ i0.ɵɵelementStart(5, "button", 90);
254
+ i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Conditional_37_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ShowKeyboardShortcuts = false); });
255
+ i0.ɵɵelement(6, "i", 91);
240
256
  i0.ɵɵelementEnd()();
241
- i0.ɵɵelementStart(7, "div", 91)(8, "div", 92)(9, "h4");
257
+ i0.ɵɵelementStart(7, "div", 92)(8, "div", 93)(9, "h4");
242
258
  i0.ɵɵtext(10, "General");
243
259
  i0.ɵɵelementEnd();
244
- i0.ɵɵelementStart(11, "div", 93)(12, "span", 94)(13, "kbd");
260
+ i0.ɵɵelementStart(11, "div", 94)(12, "span", 95)(13, "kbd");
245
261
  i0.ɵɵtext(14, "Ctrl");
246
262
  i0.ɵɵelementEnd();
247
263
  i0.ɵɵtext(15, " + ");
248
264
  i0.ɵɵelementStart(16, "kbd");
249
265
  i0.ɵɵtext(17, "S");
250
266
  i0.ɵɵelementEnd()();
251
- i0.ɵɵelementStart(18, "span", 95);
267
+ i0.ɵɵelementStart(18, "span", 96);
252
268
  i0.ɵɵtext(19, "Save version");
253
269
  i0.ɵɵelementEnd()();
254
- i0.ɵɵelementStart(20, "div", 93)(21, "span", 94)(22, "kbd");
270
+ i0.ɵɵelementStart(20, "div", 94)(21, "span", 95)(22, "kbd");
255
271
  i0.ɵɵtext(23, "Ctrl");
256
272
  i0.ɵɵelementEnd();
257
273
  i0.ɵɵtext(24, " + ");
258
274
  i0.ɵɵelementStart(25, "kbd");
259
275
  i0.ɵɵtext(26, "N");
260
276
  i0.ɵɵelementEnd()();
261
- i0.ɵɵelementStart(27, "span", 95);
277
+ i0.ɵɵelementStart(27, "span", 96);
262
278
  i0.ɵɵtext(28, "New component");
263
279
  i0.ɵɵelementEnd()();
264
- i0.ɵɵelementStart(29, "div", 93)(30, "span", 94)(31, "kbd");
280
+ i0.ɵɵelementStart(29, "div", 94)(30, "span", 95)(31, "kbd");
265
281
  i0.ɵɵtext(32, "?");
266
282
  i0.ɵɵelementEnd()();
267
- i0.ɵɵelementStart(33, "span", 95);
283
+ i0.ɵɵelementStart(33, "span", 96);
268
284
  i0.ɵɵtext(34, "Toggle shortcuts");
269
285
  i0.ɵɵelementEnd()();
270
- i0.ɵɵelementStart(35, "div", 93)(36, "span", 94)(37, "kbd");
286
+ i0.ɵɵelementStart(35, "div", 94)(36, "span", 95)(37, "kbd");
271
287
  i0.ɵɵtext(38, "Esc");
272
288
  i0.ɵɵelementEnd()();
273
- i0.ɵɵelementStart(39, "span", 95);
289
+ i0.ɵɵelementStart(39, "span", 96);
274
290
  i0.ɵɵtext(40, "Close overlay");
275
291
  i0.ɵɵelementEnd()()()()()();
276
292
  } }
277
- function ComponentStudioDashboardComponent_Conditional_39_Template(rf, ctx) { if (rf & 1) {
278
- const _r13 = i0.ɵɵgetCurrentView();
279
- i0.ɵɵelementStart(0, "mj-new-component-dialog", 96);
280
- i0.ɵɵlistener("Close", function ComponentStudioDashboardComponent_Conditional_39_Template_mj_new_component_dialog_Close_0_listener($event) { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnNewComponentDialogClose($event)); });
293
+ function ComponentStudioDashboardComponent_Conditional_38_Template(rf, ctx) { if (rf & 1) {
294
+ const _r14 = i0.ɵɵgetCurrentView();
295
+ i0.ɵɵelementStart(0, "mj-new-component-dialog", 97);
296
+ i0.ɵɵlistener("Close", function ComponentStudioDashboardComponent_Conditional_38_Template_mj_new_component_dialog_Close_0_listener($event) { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnNewComponentDialogClose($event)); });
281
297
  i0.ɵɵelementEnd();
282
298
  } if (rf & 2) {
283
299
  const ctx_r1 = i0.ɵɵnextContext();
284
300
  i0.ɵɵproperty("Visible", ctx_r1.ShowNewComponentDialog);
285
301
  } }
286
- function ComponentStudioDashboardComponent_Conditional_40_Template(rf, ctx) { if (rf & 1) {
287
- const _r14 = i0.ɵɵgetCurrentView();
288
- i0.ɵɵelementStart(0, "mj-save-version-dialog", 97);
289
- i0.ɵɵlistener("Save", function ComponentStudioDashboardComponent_Conditional_40_Template_mj_save_version_dialog_Save_0_listener($event) { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnSaveVersionConfirm($event)); })("Cancel", function ComponentStudioDashboardComponent_Conditional_40_Template_mj_save_version_dialog_Cancel_0_listener() { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ShowSaveVersionDialog = false); });
302
+ function ComponentStudioDashboardComponent_Conditional_39_Template(rf, ctx) { if (rf & 1) {
303
+ const _r15 = i0.ɵɵgetCurrentView();
304
+ i0.ɵɵelementStart(0, "mj-save-version-dialog", 98);
305
+ i0.ɵɵlistener("Save", function ComponentStudioDashboardComponent_Conditional_39_Template_mj_save_version_dialog_Save_0_listener($event) { i0.ɵɵrestoreView(_r15); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnSaveVersionConfirm($event)); })("Cancel", function ComponentStudioDashboardComponent_Conditional_39_Template_mj_save_version_dialog_Cancel_0_listener() { i0.ɵɵrestoreView(_r15); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ShowSaveVersionDialog = false); });
290
306
  i0.ɵɵelementEnd();
291
307
  } if (rf & 2) {
292
308
  const ctx_r1 = i0.ɵɵnextContext();
293
309
  i0.ɵɵproperty("Visible", ctx_r1.ShowSaveVersionDialog)("CurrentVersion", ctx_r1.versionService.CurrentVersionNumber);
294
310
  } }
295
311
  function ComponentStudioDashboardComponent_Conditional_41_Template(rf, ctx) { if (rf & 1) {
296
- const _r15 = i0.ɵɵgetCurrentView();
297
- i0.ɵɵelementStart(0, "mj-dialog", 98);
298
- i0.ɵɵlistener("Close", function ComponentStudioDashboardComponent_Conditional_41_Template_mj_dialog_Close_0_listener() { i0.ɵɵrestoreView(_r15); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnTextImportCancel()); });
299
- i0.ɵɵelementStart(1, "app-text-import-dialog", 99);
300
- i0.ɵɵlistener("importSpec", function ComponentStudioDashboardComponent_Conditional_41_Template_app_text_import_dialog_importSpec_1_listener($event) { i0.ɵɵrestoreView(_r15); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnTextImportSpec($event)); })("cancelDialog", function ComponentStudioDashboardComponent_Conditional_41_Template_app_text_import_dialog_cancelDialog_1_listener() { i0.ɵɵrestoreView(_r15); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnTextImportCancel()); });
312
+ const _r16 = i0.ɵɵgetCurrentView();
313
+ i0.ɵɵelementStart(0, "mj-dialog", 99);
314
+ i0.ɵɵlistener("Close", function ComponentStudioDashboardComponent_Conditional_41_Template_mj_dialog_Close_0_listener() { i0.ɵɵrestoreView(_r16); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnTextImportCancel()); });
315
+ i0.ɵɵelementStart(1, "app-text-import-dialog", 100);
316
+ i0.ɵɵlistener("importSpec", function ComponentStudioDashboardComponent_Conditional_41_Template_app_text_import_dialog_importSpec_1_listener($event) { i0.ɵɵrestoreView(_r16); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnTextImportSpec($event)); })("cancelDialog", function ComponentStudioDashboardComponent_Conditional_41_Template_app_text_import_dialog_cancelDialog_1_listener() { i0.ɵɵrestoreView(_r16); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnTextImportCancel()); });
301
317
  i0.ɵɵelementEnd()();
302
318
  } if (rf & 2) {
303
319
  i0.ɵɵproperty("Visible", true)("Width", 700)("MinWidth", 500);
304
320
  } }
305
321
  function ComponentStudioDashboardComponent_Conditional_42_Template(rf, ctx) { if (rf & 1) {
306
- const _r16 = i0.ɵɵgetCurrentView();
307
- i0.ɵɵelementStart(0, "app-artifact-load-dialog", 96);
308
- i0.ɵɵlistener("Close", function ComponentStudioDashboardComponent_Conditional_42_Template_app_artifact_load_dialog_Close_0_listener($event) { i0.ɵɵrestoreView(_r16); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnArtifactLoadClose($event)); });
322
+ const _r17 = i0.ɵɵgetCurrentView();
323
+ i0.ɵɵelementStart(0, "app-artifact-load-dialog", 97);
324
+ i0.ɵɵlistener("Close", function ComponentStudioDashboardComponent_Conditional_42_Template_app_artifact_load_dialog_Close_0_listener($event) { i0.ɵɵrestoreView(_r17); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnArtifactLoadClose($event)); });
309
325
  i0.ɵɵelementEnd();
310
326
  } if (rf & 2) {
311
327
  const ctx_r1 = i0.ɵɵnextContext();
312
328
  i0.ɵɵproperty("Visible", ctx_r1.ShowArtifactLoadDialog);
313
329
  } }
314
330
  function ComponentStudioDashboardComponent_Conditional_43_Template(rf, ctx) { if (rf & 1) {
315
- const _r17 = i0.ɵɵgetCurrentView();
316
- i0.ɵɵelementStart(0, "app-artifact-selection-dialog", 96);
317
- i0.ɵɵlistener("Close", function ComponentStudioDashboardComponent_Conditional_43_Template_app_artifact_selection_dialog_Close_0_listener($event) { i0.ɵɵrestoreView(_r17); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnArtifactSelectionClose($event)); });
331
+ const _r18 = i0.ɵɵgetCurrentView();
332
+ i0.ɵɵelementStart(0, "app-artifact-selection-dialog", 97);
333
+ i0.ɵɵlistener("Close", function ComponentStudioDashboardComponent_Conditional_43_Template_app_artifact_selection_dialog_Close_0_listener($event) { i0.ɵɵrestoreView(_r18); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnArtifactSelectionClose($event)); });
318
334
  i0.ɵɵelementEnd();
319
335
  } if (rf & 2) {
320
336
  const ctx_r1 = i0.ɵɵnextContext();
@@ -326,6 +342,7 @@ let ComponentStudioDashboardComponent = class ComponentStudioDashboardComponent
326
342
  versionService;
327
343
  cdr;
328
344
  notificationService;
345
+ entityFormOverrideService;
329
346
  static USER_PREFS_KEY = 'ComponentStudio.UserPreferences';
330
347
  // --- Panel widths ---
331
348
  leftPanelWidth = 340;
@@ -350,6 +367,14 @@ let ComponentStudioDashboardComponent = class ComponentStudioDashboardComponent
350
367
  ShowTextImportDialog = false;
351
368
  ShowArtifactLoadDialog = false;
352
369
  ShowArtifactSelectionDialog = false;
370
+ /** Toggled after a form-role Component is saved (see OnSaveVersionConfirm). */
371
+ ShowFormOverrideDialog = false;
372
+ /** ComponentID of the just-saved Component, set when ShowFormOverrideDialog flips on. */
373
+ PendingOverrideComponentID = null;
374
+ /** Entity name to seed the override dialog from (mirrors state.FormTargetEntityName). */
375
+ PendingOverrideEntityName = '';
376
+ /** Component name to seed the override Name field. */
377
+ PendingOverrideComponentName = '';
353
378
  // --- Status bar ---
354
379
  LastSavedTime = null;
355
380
  // --- Preferences ---
@@ -357,12 +382,13 @@ let ComponentStudioDashboardComponent = class ComponentStudioDashboardComponent
357
382
  fileInput;
358
383
  destroy$ = new Subject();
359
384
  get metadata() { return this.ProviderToUse; }
360
- constructor(state, versionService, cdr, notificationService) {
385
+ constructor(state, versionService, cdr, notificationService, entityFormOverrideService) {
361
386
  super();
362
387
  this.state = state;
363
388
  this.versionService = versionService;
364
389
  this.cdr = cdr;
365
390
  this.notificationService = notificationService;
391
+ this.entityFormOverrideService = entityFormOverrideService;
366
392
  }
367
393
  async GetResourceDisplayName(data) {
368
394
  return 'Component Studio';
@@ -373,6 +399,10 @@ let ComponentStudioDashboardComponent = class ComponentStudioDashboardComponent
373
399
  this.state.StateChanged.pipe(takeUntil(this.destroy$)).subscribe(() => {
374
400
  this.cdr.detectChanges();
375
401
  });
402
+ // Form Builder tab "Open in Chat" — relay to NavigationService.
403
+ this.state.OpenInChatRequested.pipe(takeUntil(this.destroy$)).subscribe(() => {
404
+ this.OnOpenFormInChat();
405
+ });
376
406
  this.loadUserPreferences();
377
407
  await this.state.LoadComponents();
378
408
  this.NotifyLoadComplete();
@@ -505,6 +535,16 @@ let ComponentStudioDashboardComponent = class ComponentStudioDashboardComponent
505
535
  }
506
536
  async OnSaveVersionConfirm(result) {
507
537
  this.ShowSaveVersionDialog = false;
538
+ // If the Form Builder tab is the active surface and the canvas has
539
+ // content, serialize it to JSX BEFORE the version save so the canvas
540
+ // edits actually persist. If the user is in the Code tab instead, the
541
+ // EditableCode they hand-edited is already the source of truth.
542
+ if (this.IsFormRoleComponent && this.state.ActiveTab === 5 && this.state.FormCanvas && this.state.FormSchema) {
543
+ const canvas = this.state.FormCanvas;
544
+ const schema = this.state.FormSchema;
545
+ const name = canvas.title?.trim() || schema.displayName;
546
+ this.state.EditableCode = generateCodeFromCanvas(canvas, schema, name);
547
+ }
508
548
  let success;
509
549
  if (result.Mode === 'update') {
510
550
  success = await this.versionService.UpdateCurrentVersion(result.Comment || undefined);
@@ -516,12 +556,62 @@ let ComponentStudioDashboardComponent = class ComponentStudioDashboardComponent
516
556
  this.LastSavedTime = new Date();
517
557
  this.notificationService.CreateSimpleNotification(`Saved as v${this.versionService.CurrentVersionNumber}`, 'success', 3000);
518
558
  this.state.HasUnsavedChanges = false;
559
+ // For form-role Components, prompt the user to create an
560
+ // EntityFormOverride so the saved Component actually activates for
561
+ // someone. Skip silently if the post-save state didn't yield a
562
+ // ComponentID (loading state, network blip).
563
+ if (this.IsFormRoleComponent && this.state.FormTargetEntityName) {
564
+ const spec = this.state.GetCurrentSpec?.();
565
+ const componentID = spec?.id ?? null;
566
+ if (componentID) {
567
+ this.PendingOverrideComponentID = componentID;
568
+ this.PendingOverrideEntityName = this.state.FormTargetEntityName;
569
+ this.PendingOverrideComponentName = spec?.name ?? '';
570
+ this.ShowFormOverrideDialog = true;
571
+ }
572
+ }
519
573
  }
520
574
  else {
521
575
  this.notificationService.CreateSimpleNotification('Failed to save version', 'error');
522
576
  }
523
577
  this.cdr.detectChanges();
524
578
  }
579
+ /**
580
+ * Handle the post-save override dialog. Persists an EntityFormOverride
581
+ * row via {@link EntityFormOverrideService}. Currently surfaces an error
582
+ * because the underlying write is blocked on the generated
583
+ * `EntityFormOverrideEntity` class (Task 15) — the UI is wired so the
584
+ * unblock is one swap of the service stub.
585
+ */
586
+ async OnFormOverrideDialogConfirm(result) {
587
+ this.ShowFormOverrideDialog = false;
588
+ if (!this.PendingOverrideComponentID) {
589
+ this.cdr.detectChanges();
590
+ return;
591
+ }
592
+ const overrideService = this.entityFormOverrideService;
593
+ const provider = this.ProviderToUse;
594
+ const user = provider?.CurrentUser;
595
+ if (!user) {
596
+ this.notificationService.CreateSimpleNotification('No current user — cannot create override.', 'error');
597
+ this.cdr.detectChanges();
598
+ return;
599
+ }
600
+ const writeResult = await overrideService.CreateOverride(this.PendingOverrideComponentID, result, user, provider);
601
+ if (writeResult.Success) {
602
+ this.notificationService.CreateSimpleNotification(`Override "${result.Name}" created. Next time you open a ${result.EntityName} record you'll see this form.`, 'success', 4000);
603
+ }
604
+ else {
605
+ this.notificationService.CreateSimpleNotification(writeResult.Error || 'Failed to create override.', 'warning', 6000);
606
+ }
607
+ this.PendingOverrideComponentID = null;
608
+ this.cdr.detectChanges();
609
+ }
610
+ OnFormOverrideDialogDismiss() {
611
+ this.ShowFormOverrideDialog = false;
612
+ this.PendingOverrideComponentID = null;
613
+ this.cdr.detectChanges();
614
+ }
525
615
  // ============================================================
526
616
  // REFRESH COMPONENT
527
617
  // ============================================================
@@ -562,6 +652,180 @@ let ComponentStudioDashboardComponent = class ComponentStudioDashboardComponent
562
652
  this.ShowNewComponentDialog = true;
563
653
  this.cdr.detectChanges();
564
654
  }
655
+ /**
656
+ * True iff the currently-loaded Component declares itself as a form-role
657
+ * component. Controls whether the right rail renders the field-binding
658
+ * inspector or the default AI assistant panel.
659
+ */
660
+ get IsFormRoleComponent() {
661
+ const spec = this.state.GetCurrentSpec?.();
662
+ return spec?.componentRole === 'form' || spec?.type === 'form';
663
+ }
664
+ /**
665
+ * Forwards a snippet emitted by the field-binding inspector to the code
666
+ * editor. Inserts at the end of the current code with a leading blank
667
+ * line so it lands inside the function body but doesn't clobber the
668
+ * cursor's current position. (Cursor-aware insertion is a follow-up —
669
+ * it requires plumbing EditorView refs from this component through
670
+ * EditorTabs → CodeEditorPanel → mj-code-editor.)
671
+ */
672
+ OnFieldSnippetRequested(snippet) {
673
+ if (!snippet)
674
+ return;
675
+ const existing = this.state.EditableCode ?? '';
676
+ const separator = existing.endsWith('\n') ? '\n' : '\n\n';
677
+ this.state.EditableCode = existing + separator + snippet + '\n';
678
+ this.cdr.detectChanges();
679
+ }
680
+ // ============================================================
681
+ // FORM BUILDER — right-panel event handlers
682
+ // (Mirrors what the Form Builder tab does internally, but routed
683
+ // through here so the right panel works regardless of which editor
684
+ // tab is currently active.)
685
+ // ============================================================
686
+ OnFormBuilderElementChanged(next) {
687
+ const canvas = this.state.FormCanvas;
688
+ if (!canvas)
689
+ return;
690
+ const updated = {
691
+ ...canvas,
692
+ sections: canvas.sections.map(s => ({
693
+ ...s,
694
+ elements: s.elements.map(e => e.id === next.id ? next : e),
695
+ })),
696
+ };
697
+ this.applyCanvasUpdate(updated);
698
+ }
699
+ OnFormBuilderSectionChanged(next) {
700
+ const canvas = this.state.FormCanvas;
701
+ if (!canvas)
702
+ return;
703
+ const updated = {
704
+ ...canvas,
705
+ sections: canvas.sections.map(s => s.id === next.id ? next : s),
706
+ };
707
+ this.applyCanvasUpdate(updated);
708
+ }
709
+ OnFormBuilderElementDeleted(elementId) {
710
+ const canvas = this.state.FormCanvas;
711
+ if (!canvas)
712
+ return;
713
+ const updated = {
714
+ ...canvas,
715
+ sections: canvas.sections.map(s => ({
716
+ ...s,
717
+ elements: s.elements.filter(e => e.id !== elementId),
718
+ })),
719
+ };
720
+ this.state.FormSelectedElementId = null;
721
+ this.applyCanvasUpdate(updated);
722
+ }
723
+ OnFormBuilderSectionDeleted(sectionId) {
724
+ const canvas = this.state.FormCanvas;
725
+ if (!canvas)
726
+ return;
727
+ const updated = {
728
+ ...canvas,
729
+ sections: canvas.sections.filter(s => s.id !== sectionId),
730
+ };
731
+ this.state.FormSelectedSectionId = null;
732
+ this.applyCanvasUpdate(updated);
733
+ }
734
+ OnFormBuilderFieldAdded(payload) {
735
+ const canvas = this.state.FormCanvas;
736
+ if (!canvas)
737
+ return;
738
+ const targetId = this.state.FormSelectedSectionId
739
+ ?? canvas.sections.find(s => s.elements.some(e => e.id === this.state.FormSelectedElementId))?.id
740
+ ?? canvas.sections[0]?.id;
741
+ if (!targetId)
742
+ return;
743
+ const updated = {
744
+ ...canvas,
745
+ sections: canvas.sections.map(s => s.id === targetId
746
+ ? { ...s, elements: [...s.elements, {
747
+ id: generateCanvasId('field'),
748
+ type: 'field',
749
+ fieldName: payload.fieldName,
750
+ span: 1,
751
+ }] }
752
+ : s),
753
+ };
754
+ this.applyCanvasUpdate(updated);
755
+ }
756
+ /**
757
+ * Persist the canvas mutation, mirror it into code, mark the dashboard
758
+ * dirty. Centralised so right-panel events and tab events share the same
759
+ * pipeline.
760
+ */
761
+ applyCanvasUpdate(next) {
762
+ this.state.FormCanvas = next;
763
+ this.state.HasUnsavedChanges = true;
764
+ this.regenerateFormCodeFromCanvas();
765
+ this.cdr.detectChanges();
766
+ }
767
+ /**
768
+ * Serialise the canvas → JSX into state.EditableCode. Quietly no-ops if
769
+ * we don't have both a canvas and a schema (the FormSelected* events
770
+ * shouldn't fire in that case anyway).
771
+ */
772
+ regenerateFormCodeFromCanvas() {
773
+ const canvas = this.state.FormCanvas;
774
+ const schema = this.state.FormSchema;
775
+ if (!canvas || !schema)
776
+ return;
777
+ const name = canvas.title?.trim() || schema.displayName;
778
+ this.state.EditableCode = generateCodeFromCanvas(canvas, schema, name);
779
+ }
780
+ /**
781
+ * Bridge the Form Builder tab's "Open in Chat" button to NavigationService.
782
+ * Publishes the active canvas as agent context and registers an UpdateForm
783
+ * tool so Sage can mutate the canvas live. Falls back to clipboard if the
784
+ * navigation service isn't available (e.g. embedded host).
785
+ */
786
+ async OnOpenFormInChat() {
787
+ const canvas = this.state.FormCanvas;
788
+ if (!canvas) {
789
+ this.notificationService.CreateSimpleNotification('No active form to send to chat.', 'warning');
790
+ return;
791
+ }
792
+ try {
793
+ this.navigationService?.SetAgentContext(this, {
794
+ activeForm: {
795
+ entityName: canvas.entityName,
796
+ title: canvas.title,
797
+ sections: canvas.sections,
798
+ },
799
+ });
800
+ this.navigationService?.SetAgentClientTools(this, [{
801
+ Name: 'UpdateForm',
802
+ Description: 'Replace the canvas model of the active form. Accepts a FormCanvasModel JSON object.',
803
+ ParameterSchema: {
804
+ type: 'object',
805
+ properties: { canvas: { type: 'object', description: 'A FormCanvasModel matching the Form Builder shape.' } },
806
+ required: ['canvas'],
807
+ },
808
+ Handler: async (params) => {
809
+ const next = params['canvas'] ?? null;
810
+ if (next && Array.isArray(next.sections)) {
811
+ this.applyCanvasUpdate(next);
812
+ return { Success: true };
813
+ }
814
+ return { Success: false, Error: 'Missing or malformed canvas payload.' };
815
+ },
816
+ }]);
817
+ this.notificationService.CreateSimpleNotification('Form context sent to chat. Open the chat panel to continue.', 'info', 4000);
818
+ }
819
+ catch {
820
+ try {
821
+ await navigator.clipboard.writeText(JSON.stringify(canvas, null, 2));
822
+ this.notificationService.CreateSimpleNotification('Canvas JSON copied to clipboard. Paste it into chat.', 'info', 4000);
823
+ }
824
+ catch {
825
+ this.notificationService.CreateSimpleNotification('Could not hand off to chat.', 'warning');
826
+ }
827
+ }
828
+ }
565
829
  OnNewComponentDialogClose(result) {
566
830
  this.ShowNewComponentDialog = false;
567
831
  if (!result) {
@@ -587,17 +851,26 @@ let ComponentStudioDashboardComponent = class ComponentStudioDashboardComponent
587
851
  });
588
852
  }
589
853
  createComponentFromResult(result) {
854
+ const isForm = result.type === 'form';
590
855
  const newSpec = {
591
856
  name: result.name,
592
857
  title: result.title,
593
858
  description: result.description,
594
859
  type: result.type,
860
+ // Form-role components opt in to the FormHostProps contract so the
861
+ // resolver mounts them via InteractiveFormComponent at runtime and
862
+ // the linter enforces form-specific shape checks.
863
+ componentRole: isForm ? 'form' : undefined,
595
864
  location: 'embedded',
596
865
  exampleUsage: '',
597
866
  code: this.getTemplateCode(result.name, result.type),
598
- functionalRequirements: '',
867
+ functionalRequirements: isForm
868
+ ? 'Renders a single entity record using FormHostProps. Supports view / edit / create modes. Emits BeforeSave with the dirty-field diff and BeforeDelete; the Angular wrapper owns BaseEntity persistence.'
869
+ : '',
599
870
  dataRequirements: { mode: 'views', entities: [], queries: [], description: '' },
600
- technicalDesign: ''
871
+ technicalDesign: isForm
872
+ ? 'Form-role component. Local React state holds a draft diff that overlays FormHostProps.record. Save dispatches NotifyEvent(\'BeforeSave\', { dirtyFields }) — the host applies the diff to the BaseEntity. Mode flips are requested via EditModeChangeRequested, never set locally.'
873
+ : ''
601
874
  };
602
875
  const fileComponent = {
603
876
  id: this.state.GenerateId(),
@@ -615,6 +888,9 @@ let ComponentStudioDashboardComponent = class ComponentStudioDashboardComponent
615
888
  this.state.RunComponent(fileComponent);
616
889
  }
617
890
  getTemplateCode(name, type) {
891
+ if (type === 'form') {
892
+ return this.getFormTemplateCode(name);
893
+ }
618
894
  return `function Component({ utilities, settings }) {
619
895
  const React = utilities.React;
620
896
  const { useState } = React;
@@ -627,6 +903,113 @@ let ComponentStudioDashboardComponent = class ComponentStudioDashboardComponent
627
903
  );
628
904
  }`;
629
905
  }
906
+ /**
907
+ * JSX skeleton for form-role components. Pre-wires destructured
908
+ * FormHostProps, local `draft` state for the dirty-field diff, and the
909
+ * three canonical lifecycle events (BeforeSave, BeforeDelete,
910
+ * EditModeChangeRequested). Authors fill in the field rendering; the
911
+ * persistence path is already correct.
912
+ */
913
+ getFormTemplateCode(name) {
914
+ const componentName = this.toIdentifier(name) || 'Form';
915
+ return `function ${componentName}({
916
+ // FormHostProps (from the Angular wrapper)
917
+ entityName,
918
+ primaryKey,
919
+ record,
920
+ entityMetadata,
921
+ mode,
922
+ canEdit,
923
+ canDelete,
924
+ canCreate,
925
+ // Standard interactive-component props
926
+ utilities,
927
+ styles,
928
+ components,
929
+ callbacks,
930
+ savedUserSettings,
931
+ onSaveUserSettings,
932
+ }) {
933
+ const [draft, setDraft] = React.useState({});
934
+
935
+ // Track latest draft in a ref so the methods we register below always
936
+ // see the current value without re-registering on every keystroke.
937
+ const draftRef = React.useRef({});
938
+ React.useEffect(() => { draftRef.current = draft; }, [draft]);
939
+
940
+ const isCreate = mode === "create";
941
+ const isEdit = mode === "edit";
942
+ const isView = mode === "view";
943
+ const editing = isEdit || isCreate;
944
+
945
+ // Reset the draft diff whenever a new record loads or we return to view.
946
+ React.useEffect(() => {
947
+ setDraft({});
948
+ }, [primaryKey && JSON.stringify(primaryKey), isView]);
949
+
950
+ // Register the host-callable methods exactly once. The wrapper invokes
951
+ // these when the toolbar (above this component) fires Save / Cancel.
952
+ React.useEffect(() => {
953
+ callbacks?.RegisterMethod?.("RequestSave", () => {
954
+ callbacks?.NotifyEvent?.("BeforeSave", {
955
+ dirtyFields: { ...draftRef.current },
956
+ cancel: false,
957
+ timestamp: new Date(),
958
+ });
959
+ });
960
+ callbacks?.RegisterMethod?.("RequestCancel", () => {
961
+ setDraft({});
962
+ });
963
+ }, []);
964
+
965
+ const value = (f) => (f in draft ? draft[f] : record?.[f] ?? "");
966
+
967
+ const setField = (f, v) => {
968
+ setDraft((d) => ({ ...d, [f]: v }));
969
+ callbacks?.NotifyEvent?.("FieldChanged", {
970
+ fieldName: f,
971
+ oldValue: record?.[f],
972
+ newValue: v,
973
+ timestamp: new Date(),
974
+ });
975
+ };
976
+
977
+ if (!record && !isCreate) {
978
+ return <div style={{ padding: 24 }}>No record loaded.</div>;
979
+ }
980
+
981
+ return (
982
+ <div style={{
983
+ padding: 24,
984
+ background: "var(--mj-bg-surface, #fff)",
985
+ color: "var(--mj-text-primary, #1f2937)",
986
+ borderRadius: 8,
987
+ border: "1px solid var(--mj-border-default, #e0e0e0)",
988
+ }}>
989
+ <h2 style={{ margin: 0, marginBottom: 16 }}>
990
+ {isCreate ? "New " + (entityMetadata?.displayName || entityName) : value(entityMetadata?.nameField || "Name") || "(unnamed)"}
991
+ </h2>
992
+
993
+ {/* TODO: render each entityMetadata.fields entry as an input.
994
+ Use value(fieldName) to read, setField(fieldName, newValue) to write.
995
+ See the form-builder template at metadata/prompts/templates/sage/form-builder.template.md
996
+ for full guidance, or open this component in chat to have the
997
+ Form Builder agent extend it.
998
+
999
+ DO NOT render Save / Cancel / Edit / Delete buttons here — the
1000
+ host toolbar above this component provides all four. Save is
1001
+ wired via the RequestSave method registered above. */}
1002
+ </div>
1003
+ );
1004
+ }`;
1005
+ }
1006
+ /** Sanitises a human-readable component name into a JS identifier. */
1007
+ toIdentifier(name) {
1008
+ const cleaned = name.replace(/[^A-Za-z0-9]/g, '');
1009
+ if (!cleaned)
1010
+ return '';
1011
+ return cleaned.charAt(0).toUpperCase() + cleaned.slice(1);
1012
+ }
630
1013
  // ============================================================
631
1014
  // IMPORT / EXPORT
632
1015
  // ============================================================
@@ -892,7 +1275,7 @@ let ComponentStudioDashboardComponent = class ComponentStudioDashboardComponent
892
1275
  const hashArray = Array.from(new Uint8Array(hashBuffer));
893
1276
  return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
894
1277
  }
895
- static ɵfac = function ComponentStudioDashboardComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || ComponentStudioDashboardComponent)(i0.ɵɵdirectiveInject(i1.ComponentStudioStateService), i0.ɵɵdirectiveInject(i2.ComponentVersionService), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i3.MJNotificationService)); };
1278
+ static ɵfac = function ComponentStudioDashboardComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || ComponentStudioDashboardComponent)(i0.ɵɵdirectiveInject(i1.ComponentStudioStateService), i0.ɵɵdirectiveInject(i2.ComponentVersionService), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i3.MJNotificationService), i0.ɵɵdirectiveInject(i4.EntityFormOverrideService)); };
896
1279
  static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ComponentStudioDashboardComponent, selectors: [["mj-component-studio-dashboard"]], viewQuery: function ComponentStudioDashboardComponent_Query(rf, ctx) { if (rf & 1) {
897
1280
  i0.ɵɵviewQuery(_c0, 5);
898
1281
  } if (rf & 2) {
@@ -900,7 +1283,7 @@ let ComponentStudioDashboardComponent = class ComponentStudioDashboardComponent
900
1283
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.fileInput = _t.first);
901
1284
  } }, hostBindings: function ComponentStudioDashboardComponent_HostBindings(rf, ctx) { if (rf & 1) {
902
1285
  i0.ɵɵlistener("keydown", function ComponentStudioDashboardComponent_keydown_HostBindingHandler($event) { return ctx.OnKeyDown($event); }, i0.ɵɵresolveDocument)("click", function ComponentStudioDashboardComponent_click_HostBindingHandler($event) { return ctx.OnDocumentClick($event); }, i0.ɵɵresolveDocument);
903
- } }, standalone: false, features: [i0.ɵɵProvidersFeature([ComponentStudioStateService, ComponentVersionService]), i0.ɵɵInheritDefinitionFeature], decls: 44, vars: 23, consts: [["fileInput", ""], [1, "component-studio"], [1, "studio-toolbar"], [1, "toolbar-context"], ["title", "Toggle browser panel", 1, "tb-btn", "icon-only", 3, "click"], [1, "fa-solid", "fa-bars"], [1, "toolbar-spacer"], [1, "toolbar-actions"], ["title", "Save version (Ctrl+S)", 1, "tb-btn", "primary"], ["title", "Refresh component", 1, "tb-btn"], [1, "header-dropdown", 3, "open"], [1, "toolbar-divider"], [1, "tb-btn", "icon-only", 3, "click", "title"], [1, "fa-solid", "fa-robot"], ["title", "Keyboard shortcuts (?)", 1, "tb-btn", "icon-only", 3, "click"], [1, "fa-solid", "fa-keyboard"], ["title", "Refresh data", 1, "tb-btn", "icon-only", 3, "click", "disabled"], [1, "fa-solid", "fa-arrows-rotate"], ["type", "file", "accept", ".json", 2, "display", "none", 3, "change"], [1, "studio-body"], [1, "panel", "panel-center"], [1, "empty-state"], [1, "resize-handle"], [1, "panel", "panel-right", 3, "width"], [1, "status-bar"], [1, "status-left"], [1, "status-item"], [1, "fa-solid", "fa-cube"], [1, "status-right"], [1, "status-item", "shortcut-hint"], [1, "shortcuts-overlay"], [3, "Visible"], [3, "Visible", "CurrentVersion"], ["Title", "Import Component from Text", 3, "Visible", "Width", "MinWidth"], [1, "breadcrumb-type"], [1, "breadcrumb-sep"], [1, "fa-solid", "fa-chevron-right"], [1, "component-label"], [1, "running-badge"], ["title", "Unsaved changes", 1, "unsaved-dot"], [1, "running-dot-small"], ["title", "Save version (Ctrl+S)", 1, "tb-btn", "primary", 3, "click"], [1, "fa-solid", "fa-save"], ["title", "Refresh component", 1, "tb-btn", 3, "click"], [1, "header-dropdown"], [1, "tb-btn", 3, "click"], [1, "fa-solid", "fa-file-export"], [1, "fa-solid", "fa-chevron-down", "dropdown-icon"], [1, "dropdown-menu"], [1, "dropdown-item", 3, "click"], [1, "fa-solid", "fa-file"], [1, "fa-solid", "fa-clipboard"], [1, "panel", "panel-left"], [3, "NewComponent", "ImportFromFile", "ImportFromText", "ImportFromArtifact"], [1, "resize-handle", 3, "mousedown"], [1, "workspace-preview"], [1, "preview-sub-header"], [1, "preview-sub-left"], [1, "fa-solid", "fa-eye"], [1, "preview-sub-right"], ["title", "Toggle editor panel", 1, "toggle-editors-btn", 3, "click"], [1, "fa-solid", "fa-columns"], [1, "preview-body"], [3, "AskAIToFix"], [1, "resize-handle", "center-divider"], [1, "workspace-editors", 3, "flex"], [1, "resize-handle", "center-divider", 3, "mousedown"], [1, "divider-grip"], [1, "workspace-editors"], [1, "empty-state-content"], [1, "empty-state-icon"], [1, "fa-solid", "fa-rocket"], [1, "empty-state-actions"], ["mjButton", "", "variant", "primary", 3, "click"], [1, "fa-solid", "fa-plus"], ["mjButton", "", 3, "click"], [1, "fa-solid", "fa-file-import"], [1, "quick-start-templates"], [1, "quick-start-label"], [1, "quick-start-btn", 3, "click"], [1, "fa-solid", "fa-chart-line"], [1, "fa-solid", "fa-file-alt"], [1, "fa-solid", "fa-chart-pie"], [1, "fa-solid", "fa-edit"], [1, "panel", "panel-right"], [1, "fa-solid", "fa-check-circle"], [1, "shortcuts-overlay", 3, "click"], [1, "shortcuts-panel", 3, "click"], [1, "shortcuts-header"], [1, "shortcuts-close", 3, "click"], [1, "fa-solid", "fa-times"], [1, "shortcuts-body"], [1, "shortcut-group"], [1, "shortcut-row"], [1, "shortcut-keys"], [1, "shortcut-desc"], [3, "Close", "Visible"], [3, "Save", "Cancel", "Visible", "CurrentVersion"], ["Title", "Import Component from Text", 3, "Close", "Visible", "Width", "MinWidth"], [3, "importSpec", "cancelDialog"]], template: function ComponentStudioDashboardComponent_Template(rf, ctx) { if (rf & 1) {
1286
+ } }, standalone: false, features: [i0.ɵɵProvidersFeature([ComponentStudioStateService, ComponentVersionService]), i0.ɵɵInheritDefinitionFeature], decls: 44, vars: 25, consts: [["fileInput", ""], [1, "component-studio"], [1, "studio-toolbar"], [1, "toolbar-context"], ["title", "Toggle browser panel", 1, "tb-btn", "icon-only", 3, "click"], [1, "fa-solid", "fa-bars"], [1, "toolbar-spacer"], [1, "toolbar-actions"], ["title", "Save version (Ctrl+S)", 1, "tb-btn", "primary"], ["title", "Refresh component", 1, "tb-btn"], [1, "header-dropdown", 3, "open"], [1, "toolbar-divider"], [1, "tb-btn", "icon-only", 3, "click", "title"], [1, "fa-solid", "fa-robot"], ["title", "Keyboard shortcuts (?)", 1, "tb-btn", "icon-only", 3, "click"], [1, "fa-solid", "fa-keyboard"], ["title", "Refresh data", 1, "tb-btn", "icon-only", 3, "click", "disabled"], [1, "fa-solid", "fa-arrows-rotate"], ["type", "file", "accept", ".json", 2, "display", "none", 3, "change"], [1, "studio-body"], [1, "panel", "panel-center"], [1, "empty-state"], [1, "status-bar"], [1, "status-left"], [1, "status-item"], [1, "fa-solid", "fa-cube"], [1, "status-right"], [1, "status-item", "shortcut-hint"], [1, "shortcuts-overlay"], [3, "Visible"], [3, "Visible", "CurrentVersion"], [3, "confirmed", "dismissed", "Visible", "ComponentName", "EntityName"], ["Title", "Import Component from Text", 3, "Visible", "Width", "MinWidth"], [1, "breadcrumb-type"], [1, "breadcrumb-sep"], [1, "fa-solid", "fa-chevron-right"], [1, "component-label"], [1, "running-badge"], ["title", "Unsaved changes", 1, "unsaved-dot"], [1, "running-dot-small"], ["title", "Save version (Ctrl+S)", 1, "tb-btn", "primary", 3, "click"], [1, "fa-solid", "fa-save"], ["title", "Refresh component", 1, "tb-btn", 3, "click"], [1, "header-dropdown"], [1, "tb-btn", 3, "click"], [1, "fa-solid", "fa-file-export"], [1, "fa-solid", "fa-chevron-down", "dropdown-icon"], [1, "dropdown-menu"], [1, "dropdown-item", 3, "click"], [1, "fa-solid", "fa-file"], [1, "fa-solid", "fa-clipboard"], [1, "panel", "panel-left"], [3, "NewComponent", "ImportFromFile", "ImportFromText", "ImportFromArtifact"], [1, "resize-handle", 3, "mousedown"], [1, "workspace-preview"], [1, "preview-sub-header"], [1, "preview-sub-left"], [1, "fa-solid", "fa-eye"], [1, "preview-sub-right"], ["title", "Toggle editor panel", 1, "toggle-editors-btn", 3, "click"], [1, "fa-solid", "fa-columns"], [1, "preview-body"], [3, "AskAIToFix"], [1, "resize-handle", "center-divider"], [1, "workspace-editors", 3, "flex"], [1, "resize-handle", "center-divider", 3, "mousedown"], [1, "divider-grip"], [1, "workspace-editors"], [1, "empty-state-content"], [1, "empty-state-icon"], [1, "fa-solid", "fa-rocket"], [1, "empty-state-actions"], ["mjButton", "", "variant", "primary", 3, "click"], [1, "fa-solid", "fa-plus"], ["mjButton", "", 3, "click"], [1, "fa-solid", "fa-file-import"], [1, "quick-start-templates"], [1, "quick-start-label"], [1, "quick-start-btn", 3, "click"], [1, "fa-solid", "fa-chart-line"], [1, "fa-solid", "fa-file-alt"], [1, "fa-solid", "fa-chart-pie"], [1, "fa-solid", "fa-edit"], [1, "panel", "panel-right"], [3, "Schema", "Canvas", "SelectedElementId", "SelectedSectionId"], [3, "ElementChanged", "SectionChanged", "ElementDeleted", "SectionDeleted", "FieldAdded", "Schema", "Canvas", "SelectedElementId", "SelectedSectionId"], [1, "fa-solid", "fa-check-circle"], [1, "shortcuts-overlay", 3, "click"], [1, "shortcuts-panel", 3, "click"], [1, "shortcuts-header"], [1, "shortcuts-close", 3, "click"], [1, "fa-solid", "fa-times"], [1, "shortcuts-body"], [1, "shortcut-group"], [1, "shortcut-row"], [1, "shortcut-keys"], [1, "shortcut-desc"], [3, "Close", "Visible"], [3, "Save", "Cancel", "Visible", "CurrentVersion"], ["Title", "Import Component from Text", 3, "Close", "Visible", "Width", "MinWidth"], [3, "importSpec", "cancelDialog"]], template: function ComponentStudioDashboardComponent_Template(rf, ctx) { if (rf & 1) {
904
1287
  const _r1 = i0.ɵɵgetCurrentView();
905
1288
  i0.ɵɵelementStart(0, "div", 1)(1, "div", 2)(2, "div", 3)(3, "button", 4);
906
1289
  i0.ɵɵlistener("click", function ComponentStudioDashboardComponent_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.ToggleLeftPanel()); });
@@ -934,26 +1317,28 @@ let ComponentStudioDashboardComponent = class ComponentStudioDashboardComponent
934
1317
  i0.ɵɵelementStart(22, "div", 20);
935
1318
  i0.ɵɵconditionalCreate(23, ComponentStudioDashboardComponent_Conditional_23_Template, 13, 8)(24, ComponentStudioDashboardComponent_Conditional_24_Template, 30, 0, "div", 21);
936
1319
  i0.ɵɵelementEnd();
937
- i0.ɵɵconditionalCreate(25, ComponentStudioDashboardComponent_Conditional_25_Template, 1, 0, "div", 22);
938
- i0.ɵɵconditionalCreate(26, ComponentStudioDashboardComponent_Conditional_26_Template, 2, 2, "div", 23);
1320
+ i0.ɵɵconditionalCreate(25, ComponentStudioDashboardComponent_Conditional_25_Template, 4, 3);
939
1321
  i0.ɵɵelementEnd();
940
- i0.ɵɵelementStart(27, "div", 24)(28, "div", 25)(29, "span", 26);
941
- i0.ɵɵelement(30, "i", 27);
942
- i0.ɵɵtext(31);
1322
+ i0.ɵɵelementStart(26, "div", 22)(27, "div", 23)(28, "span", 24);
1323
+ i0.ɵɵelement(29, "i", 25);
1324
+ i0.ɵɵtext(30);
943
1325
  i0.ɵɵelementEnd()();
944
- i0.ɵɵelementStart(32, "div", 28);
945
- i0.ɵɵconditionalCreate(33, ComponentStudioDashboardComponent_Conditional_33_Template, 4, 4, "span", 26);
946
- i0.ɵɵelementStart(34, "span", 29)(35, "kbd");
947
- i0.ɵɵtext(36, "?");
1326
+ i0.ɵɵelementStart(31, "div", 26);
1327
+ i0.ɵɵconditionalCreate(32, ComponentStudioDashboardComponent_Conditional_32_Template, 4, 4, "span", 24);
1328
+ i0.ɵɵelementStart(33, "span", 27)(34, "kbd");
1329
+ i0.ɵɵtext(35, "?");
948
1330
  i0.ɵɵelementEnd();
949
- i0.ɵɵtext(37, " Shortcuts ");
1331
+ i0.ɵɵtext(36, " Shortcuts ");
950
1332
  i0.ɵɵelementEnd()()();
951
- i0.ɵɵconditionalCreate(38, ComponentStudioDashboardComponent_Conditional_38_Template, 41, 0, "div", 30);
952
- i0.ɵɵconditionalCreate(39, ComponentStudioDashboardComponent_Conditional_39_Template, 1, 1, "mj-new-component-dialog", 31);
953
- i0.ɵɵconditionalCreate(40, ComponentStudioDashboardComponent_Conditional_40_Template, 1, 2, "mj-save-version-dialog", 32);
954
- i0.ɵɵconditionalCreate(41, ComponentStudioDashboardComponent_Conditional_41_Template, 2, 3, "mj-dialog", 33);
955
- i0.ɵɵconditionalCreate(42, ComponentStudioDashboardComponent_Conditional_42_Template, 1, 1, "app-artifact-load-dialog", 31);
956
- i0.ɵɵconditionalCreate(43, ComponentStudioDashboardComponent_Conditional_43_Template, 1, 1, "app-artifact-selection-dialog", 31);
1333
+ i0.ɵɵconditionalCreate(37, ComponentStudioDashboardComponent_Conditional_37_Template, 41, 0, "div", 28);
1334
+ i0.ɵɵconditionalCreate(38, ComponentStudioDashboardComponent_Conditional_38_Template, 1, 1, "mj-new-component-dialog", 29);
1335
+ i0.ɵɵconditionalCreate(39, ComponentStudioDashboardComponent_Conditional_39_Template, 1, 2, "mj-save-version-dialog", 30);
1336
+ i0.ɵɵelementStart(40, "mj-form-override-dialog", 31);
1337
+ i0.ɵɵlistener("confirmed", function ComponentStudioDashboardComponent_Template_mj_form_override_dialog_confirmed_40_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnFormOverrideDialogConfirm($event)); })("dismissed", function ComponentStudioDashboardComponent_Template_mj_form_override_dialog_dismissed_40_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnFormOverrideDialogDismiss()); });
1338
+ i0.ɵɵelementEnd();
1339
+ i0.ɵɵconditionalCreate(41, ComponentStudioDashboardComponent_Conditional_41_Template, 2, 3, "mj-dialog", 32);
1340
+ i0.ɵɵconditionalCreate(42, ComponentStudioDashboardComponent_Conditional_42_Template, 1, 1, "app-artifact-load-dialog", 29);
1341
+ i0.ɵɵconditionalCreate(43, ComponentStudioDashboardComponent_Conditional_43_Template, 1, 1, "app-artifact-selection-dialog", 29);
957
1342
  i0.ɵɵelementEnd();
958
1343
  } if (rf & 2) {
959
1344
  i0.ɵɵclassProp("resizing", ctx.IsResizing);
@@ -975,19 +1360,19 @@ let ComponentStudioDashboardComponent = class ComponentStudioDashboardComponent
975
1360
  i0.ɵɵadvance(2);
976
1361
  i0.ɵɵconditional(ctx.state.SelectedComponent ? 23 : 24);
977
1362
  i0.ɵɵadvance(2);
978
- i0.ɵɵconditional(!ctx.state.IsAIPanelCollapsed ? 25 : -1);
979
- i0.ɵɵadvance();
980
- i0.ɵɵconditional(!ctx.state.IsAIPanelCollapsed ? 26 : -1);
1363
+ i0.ɵɵconditional(!ctx.state.IsAIPanelCollapsed && ctx.state.SelectedComponent ? 25 : -1);
981
1364
  i0.ɵɵadvance(5);
982
1365
  i0.ɵɵtextInterpolate2(" ", ctx.state.FilteredComponents.length, " component", ctx.state.FilteredComponents.length !== 1 ? "s" : "", " ");
983
1366
  i0.ɵɵadvance(2);
984
- i0.ɵɵconditional(ctx.LastSavedTime ? 33 : -1);
1367
+ i0.ɵɵconditional(ctx.LastSavedTime ? 32 : -1);
985
1368
  i0.ɵɵadvance(5);
986
- i0.ɵɵconditional(ctx.ShowKeyboardShortcuts ? 38 : -1);
1369
+ i0.ɵɵconditional(ctx.ShowKeyboardShortcuts ? 37 : -1);
1370
+ i0.ɵɵadvance();
1371
+ i0.ɵɵconditional(ctx.ShowNewComponentDialog ? 38 : -1);
987
1372
  i0.ɵɵadvance();
988
- i0.ɵɵconditional(ctx.ShowNewComponentDialog ? 39 : -1);
1373
+ i0.ɵɵconditional(ctx.ShowSaveVersionDialog ? 39 : -1);
989
1374
  i0.ɵɵadvance();
990
- i0.ɵɵconditional(ctx.ShowSaveVersionDialog ? 40 : -1);
1375
+ i0.ɵɵproperty("Visible", ctx.ShowFormOverrideDialog)("ComponentName", ctx.PendingOverrideComponentName)("EntityName", ctx.PendingOverrideEntityName);
991
1376
  i0.ɵɵadvance();
992
1377
  i0.ɵɵconditional(ctx.ShowTextImportDialog ? 41 : -1);
993
1378
  i0.ɵɵadvance();
@@ -1002,8 +1387,8 @@ ComponentStudioDashboardComponent = ComponentStudioDashboardComponent_1 = __deco
1002
1387
  export { ComponentStudioDashboardComponent };
1003
1388
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ComponentStudioDashboardComponent, [{
1004
1389
  type: Component,
1005
- args: [{ standalone: false, selector: 'mj-component-studio-dashboard', providers: [ComponentStudioStateService, ComponentVersionService], template: "<div class=\"component-studio\" [class.resizing]=\"IsResizing\">\n\n <!-- ============================================================\n TOOLBAR \u2014 Unified bar with integrated breadcrumb\n Left: hamburger + breadcrumb context\n Right: Save | Export | divider | AI | Keyboard | Refresh\n ============================================================ -->\n <div class=\"studio-toolbar\">\n <div class=\"toolbar-context\">\n <!-- Toggle left panel -->\n <button class=\"tb-btn icon-only\" title=\"Toggle browser panel\" (click)=\"ToggleLeftPanel()\">\n <i class=\"fa-solid fa-bars\"></i>\n </button>\n\n @if (state.SelectedComponent) {\n <span class=\"breadcrumb-type\">\n <i class=\"fa-solid fa-cube\"></i>\n {{ state.GetComponentType(state.SelectedComponent) || 'Component' }}\n </span>\n <span class=\"breadcrumb-sep\"><i class=\"fa-solid fa-chevron-right\"></i></span>\n <span class=\"component-label\">{{ state.GetComponentName(state.SelectedComponent) }}</span>\n\n @if (state.IsRunning) {\n <span class=\"running-badge\">\n <span class=\"running-dot-small\"></span>\n Running\n </span>\n }\n @if (state.HasUnsavedChanges) {\n <span class=\"unsaved-dot\" title=\"Unsaved changes\"></span>\n }\n }\n </div>\n\n <div class=\"toolbar-spacer\"></div>\n\n <div class=\"toolbar-actions\">\n <!-- Save Version -->\n @if (state.SelectedComponent) {\n <button class=\"tb-btn primary\" (click)=\"SaveVersion()\" title=\"Save version (Ctrl+S)\">\n <i class=\"fa-solid fa-save\"></i> Save\n </button>\n }\n\n <!-- Refresh Component -->\n @if (state.SelectedComponent && state.IsRunning) {\n <button class=\"tb-btn\" (click)=\"RefreshComponent()\" title=\"Refresh component\">\n <i class=\"fa-solid fa-arrows-rotate\"></i> Refresh\n </button>\n }\n\n <!-- Export -->\n @if (state.SelectedComponent && state.IsRunning) {\n <div class=\"header-dropdown\" [class.open]=\"exportDropdownOpen\">\n <button class=\"tb-btn\" (click)=\"ToggleExportDropdown()\">\n <i class=\"fa-solid fa-file-export\"></i> Export\n <i class=\"fa-solid fa-chevron-down dropdown-icon\"></i>\n </button>\n @if (exportDropdownOpen) {\n <div class=\"dropdown-menu\">\n <button class=\"dropdown-item\" (click)=\"ExportToArtifact()\">\n <i class=\"fa-solid fa-save\"></i> To Artifact\n </button>\n <button class=\"dropdown-item\" (click)=\"ExportToFile()\">\n <i class=\"fa-solid fa-file\"></i> To File\n </button>\n <button class=\"dropdown-item\" (click)=\"ExportToClipboard()\">\n <i class=\"fa-solid fa-clipboard\"></i> To Clipboard\n </button>\n </div>\n }\n </div>\n }\n\n <span class=\"toolbar-divider\"></span>\n\n <!-- AI Panel Toggle -->\n <button class=\"tb-btn icon-only\" [class.active-toggle]=\"!state.IsAIPanelCollapsed\"\n (click)=\"ToggleAIPanel()\"\n [title]=\"state.IsAIPanelCollapsed ? 'Show AI Assistant' : 'Hide AI Assistant'\">\n <i class=\"fa-solid fa-robot\"></i>\n </button>\n\n <!-- Keyboard Shortcuts -->\n <button class=\"tb-btn icon-only\" (click)=\"ShowKeyboardShortcuts = !ShowKeyboardShortcuts\"\n title=\"Keyboard shortcuts (?)\">\n <i class=\"fa-solid fa-keyboard\"></i>\n </button>\n\n <!-- Refresh -->\n <button class=\"tb-btn icon-only\" (click)=\"RefreshData()\" [disabled]=\"state.IsLoading\" title=\"Refresh data\">\n <i class=\"fa-solid fa-arrows-rotate\"></i>\n </button>\n </div>\n\n <!-- Hidden file input -->\n <input #fileInput type=\"file\" accept=\".json\" (change)=\"HandleFileSelect($event)\" style=\"display: none;\" />\n </div>\n\n <!-- ============================================================\n THREE-PANEL BODY\n ============================================================ -->\n <div class=\"studio-body\">\n\n <!-- Left Panel: Component Browser (collapsible) -->\n @if (!IsLeftPanelCollapsed) {\n <div class=\"panel panel-left\" [style.width.px]=\"leftPanelWidth\">\n <mj-component-browser\n (NewComponent)=\"OnNewComponent()\"\n (ImportFromFile)=\"ImportFromFile()\"\n (ImportFromText)=\"ImportFromText()\"\n (ImportFromArtifact)=\"ImportFromArtifact()\">\n </mj-component-browser>\n </div>\n\n <!-- Resize Handle: Left <-> Center -->\n <div class=\"resize-handle\" (mousedown)=\"OnLeftResizeStart($event)\"></div>\n }\n\n <!-- Center Panel: Workspace (side-by-side: Preview LEFT, Editor RIGHT) -->\n <div class=\"panel panel-center\">\n @if (state.SelectedComponent) {\n <!-- Preview (left side) -->\n <div class=\"workspace-preview\" [class.full-width]=\"IsEditorPanelCollapsed\" [style.flex]=\"IsEditorPanelCollapsed ? '1 1 100%' : previewFlex\">\n <div class=\"preview-sub-header\">\n <div class=\"preview-sub-left\">\n <i class=\"fa-solid fa-eye\"></i>\n <span>Preview</span>\n </div>\n <div class=\"preview-sub-right\">\n <!-- Toggle editor panel -->\n <button class=\"toggle-editors-btn\" [class.active]=\"!IsEditorPanelCollapsed\"\n (click)=\"ToggleEditorPanel()\" title=\"Toggle editor panel\">\n <i class=\"fa-solid fa-columns\"></i>\n </button>\n </div>\n </div>\n <div class=\"preview-body\">\n <mj-component-preview\n (AskAIToFix)=\"OnAskAIToFix($event)\">\n </mj-component-preview>\n </div>\n </div>\n\n <!-- Resize Handle: Preview <-> Editor (obvious center divider) -->\n @if (!IsEditorPanelCollapsed) {\n <div class=\"resize-handle center-divider\" (mousedown)=\"OnCenterResizeStart($event)\">\n <div class=\"divider-grip\"></div>\n </div>\n }\n\n <!-- Editor Tabs (right side, collapsible) -->\n @if (!IsEditorPanelCollapsed) {\n <div class=\"workspace-editors\" [style.flex]=\"editorFlex\">\n <mj-editor-tabs></mj-editor-tabs>\n </div>\n }\n } @else {\n <!-- Enhanced Empty State -->\n <div class=\"empty-state\">\n <div class=\"empty-state-content\">\n <div class=\"empty-state-icon\">\n <i class=\"fa-solid fa-rocket\"></i>\n </div>\n <h2>Ready to Build</h2>\n <p>Select a component from the browser or create a new one to get started</p>\n <div class=\"empty-state-actions\">\n <button mjButton variant=\"primary\" (click)=\"OnNewComponent()\">\n <span class=\"fa-solid fa-plus\"></span> New Component\n </button>\n <button mjButton (click)=\"ImportFromFile()\">\n <span class=\"fa-solid fa-file-import\"></span> Import\n </button>\n </div>\n <div class=\"quick-start-templates\">\n <span class=\"quick-start-label\">Quick start:</span>\n <button class=\"quick-start-btn\" (click)=\"OnQuickStart('dashboard')\">\n <i class=\"fa-solid fa-chart-line\"></i> Dashboard\n </button>\n <button class=\"quick-start-btn\" (click)=\"OnQuickStart('report')\">\n <i class=\"fa-solid fa-file-alt\"></i> Report\n </button>\n <button class=\"quick-start-btn\" (click)=\"OnQuickStart('chart')\">\n <i class=\"fa-solid fa-chart-pie\"></i> Chart\n </button>\n <button class=\"quick-start-btn\" (click)=\"OnQuickStart('form')\">\n <i class=\"fa-solid fa-edit\"></i> Form\n </button>\n </div>\n </div>\n </div>\n }\n </div>\n\n <!-- Resize Handle: Center <-> Right -->\n @if (!state.IsAIPanelCollapsed) {\n <div class=\"resize-handle\" (mousedown)=\"OnRightResizeStart($event)\"></div>\n }\n\n <!-- Right Panel: AI Assistant -->\n @if (!state.IsAIPanelCollapsed) {\n <div class=\"panel panel-right\" [style.width.px]=\"rightPanelWidth\">\n <mj-ai-assistant-panel></mj-ai-assistant-panel>\n </div>\n }\n </div>\n\n <!-- ============================================================\n STATUS BAR\n ============================================================ -->\n <div class=\"status-bar\">\n <div class=\"status-left\">\n <span class=\"status-item\">\n <i class=\"fa-solid fa-cube\"></i>\n {{ state.FilteredComponents.length }} component{{ state.FilteredComponents.length !== 1 ? 's' : '' }}\n </span>\n </div>\n <div class=\"status-right\">\n @if (LastSavedTime) {\n <span class=\"status-item\">\n <i class=\"fa-solid fa-check-circle\"></i>\n Saved {{ LastSavedTime | date:'shortTime' }}\n </span>\n }\n <span class=\"status-item shortcut-hint\">\n <kbd>?</kbd> Shortcuts\n </span>\n </div>\n </div>\n\n <!-- ============================================================\n KEYBOARD SHORTCUTS OVERLAY\n ============================================================ -->\n @if (ShowKeyboardShortcuts) {\n <div class=\"shortcuts-overlay\" (click)=\"ShowKeyboardShortcuts = false\">\n <div class=\"shortcuts-panel\" (click)=\"$event.stopPropagation()\">\n <div class=\"shortcuts-header\">\n <h3>Keyboard Shortcuts</h3>\n <button class=\"shortcuts-close\" (click)=\"ShowKeyboardShortcuts = false\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n <div class=\"shortcuts-body\">\n <div class=\"shortcut-group\">\n <h4>General</h4>\n <div class=\"shortcut-row\">\n <span class=\"shortcut-keys\"><kbd>Ctrl</kbd> + <kbd>S</kbd></span>\n <span class=\"shortcut-desc\">Save version</span>\n </div>\n <div class=\"shortcut-row\">\n <span class=\"shortcut-keys\"><kbd>Ctrl</kbd> + <kbd>N</kbd></span>\n <span class=\"shortcut-desc\">New component</span>\n </div>\n <div class=\"shortcut-row\">\n <span class=\"shortcut-keys\"><kbd>?</kbd></span>\n <span class=\"shortcut-desc\">Toggle shortcuts</span>\n </div>\n <div class=\"shortcut-row\">\n <span class=\"shortcut-keys\"><kbd>Esc</kbd></span>\n <span class=\"shortcut-desc\">Close overlay</span>\n </div>\n </div>\n </div>\n </div>\n </div>\n }\n\n <!-- ============================================================\n NEW COMPONENT DIALOG\n ============================================================ -->\n @if (ShowNewComponentDialog) {\n <mj-new-component-dialog\n [Visible]=\"ShowNewComponentDialog\"\n (Close)=\"OnNewComponentDialogClose($event)\">\n </mj-new-component-dialog>\n }\n\n @if (ShowSaveVersionDialog) {\n <mj-save-version-dialog\n [Visible]=\"ShowSaveVersionDialog\"\n [CurrentVersion]=\"versionService.CurrentVersionNumber\"\n (Save)=\"OnSaveVersionConfirm($event)\"\n (Cancel)=\"ShowSaveVersionDialog = false\">\n </mj-save-version-dialog>\n }\n\n <!-- Text Import Dialog -->\n @if (ShowTextImportDialog) {\n <mj-dialog [Visible]=\"true\" Title=\"Import Component from Text\" (Close)=\"OnTextImportCancel()\" [Width]=\"700\" [MinWidth]=\"500\">\n <app-text-import-dialog\n (importSpec)=\"OnTextImportSpec($event)\"\n (cancelDialog)=\"OnTextImportCancel()\">\n </app-text-import-dialog>\n </mj-dialog>\n }\n\n <!-- Artifact Load Dialog -->\n @if (ShowArtifactLoadDialog) {\n <app-artifact-load-dialog\n [Visible]=\"ShowArtifactLoadDialog\"\n (Close)=\"OnArtifactLoadClose($event)\">\n </app-artifact-load-dialog>\n }\n\n <!-- Artifact Selection Dialog -->\n @if (ShowArtifactSelectionDialog) {\n <app-artifact-selection-dialog\n [Visible]=\"ShowArtifactSelectionDialog\"\n (Close)=\"OnArtifactSelectionClose($event)\">\n </app-artifact-selection-dialog>\n }\n</div>\n", styles: [":host {\n display: block;\n width: 100%;\n height: 100%;\n}\n\n.component-studio {\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 \u2014 unified bar with integrated breadcrumb\n ============================================================ */\n\n.component-studio .studio-toolbar {\n display: flex;\n align-items: center;\n padding: 0 8px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n z-index: 10;\n min-height: 42px;\n gap: 8px;\n}\n\n/* Left: hamburger + breadcrumb context */\n.component-studio .toolbar-context {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 0;\n flex-shrink: 1;\n overflow: hidden;\n}\n\n.component-studio .toolbar-spacer {\n flex: 1;\n}\n\n/* Right: action buttons */\n.component-studio .toolbar-actions {\n display: flex;\n align-items: center;\n gap: 4px;\n flex-shrink: 0;\n}\n\n/* ---- Toolbar buttons ---- */\n.component-studio .tb-btn {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 5px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n background: var(--mj-bg-surface);\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 line-height: 1;\n}\n\n.component-studio .tb-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n border-color: var(--mj-border-default);\n}\n\n.component-studio .tb-btn:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n}\n\n.component-studio .tb-btn i {\n font-size: 12px;\n}\n\n.component-studio .tb-btn.icon-only {\n padding: 5px 7px;\n}\n\n.component-studio .tb-btn.primary {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-color: var(--mj-brand-primary);\n}\n\n.component-studio .tb-btn.primary:hover {\n opacity: 0.9;\n}\n\n.component-studio .tb-btn.active-toggle {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n}\n\n/* ---- Breadcrumb elements inside toolbar ---- */\n.component-studio .breadcrumb-type {\n display: flex;\n align-items: center;\n gap: 5px;\n font-size: 12px;\n color: var(--mj-text-secondary);\n white-space: nowrap;\n}\n\n.component-studio .breadcrumb-type i {\n font-size: 11px;\n color: var(--mj-brand-primary);\n}\n\n.component-studio .breadcrumb-sep {\n font-size: 9px;\n color: var(--mj-border-default);\n}\n\n.component-studio .component-label {\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 240px;\n}\n\n.component-studio .running-badge {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 2px 8px;\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n font-size: 11px;\n font-weight: 600;\n border-radius: 10px;\n white-space: nowrap;\n}\n\n.component-studio .running-dot-small {\n display: inline-block;\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: var(--mj-status-success);\n animation: pulse 1.5s ease-in-out infinite;\n}\n\n.component-studio .unsaved-dot {\n display: inline-block;\n width: 7px;\n height: 7px;\n border-radius: 50%;\n background: var(--mj-status-warning);\n animation: pulse 2s infinite;\n flex-shrink: 0;\n}\n\n.component-studio .toolbar-divider {\n width: 1px;\n height: 18px;\n background: var(--mj-border-default);\n margin: 0 2px;\n flex-shrink: 0;\n}\n\n.component-studio .dropdown-icon {\n font-size: 9px;\n opacity: 0.6;\n}\n\n/* ---- Dropdown menus ---- */\n.component-studio .header-dropdown {\n position: relative;\n}\n\n.component-studio .header-dropdown .dropdown-menu {\n position: absolute;\n top: calc(100% + 4px);\n right: 0;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n box-shadow: var(--mj-shadow-lg);\n z-index: 100;\n min-width: 180px;\n overflow: hidden;\n}\n\n.component-studio .header-dropdown .dropdown-menu .dropdown-item {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n padding: 10px 16px;\n border: none;\n background: none;\n text-align: left;\n cursor: pointer;\n font-size: 13px;\n color: var(--mj-text-primary);\n transition: background 0.15s ease;\n}\n\n.component-studio .header-dropdown .dropdown-menu .dropdown-item:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.component-studio .header-dropdown .dropdown-menu .dropdown-item:not(:last-child) {\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.component-studio .header-dropdown .dropdown-menu .dropdown-item i {\n width: 16px;\n text-align: center;\n color: var(--mj-brand-primary);\n font-size: 13px;\n}\n\n/* ============================================================\n THREE-PANEL BODY\n ============================================================ */\n\n.component-studio .studio-body {\n display: flex;\n flex: 1;\n overflow: hidden;\n}\n\n.component-studio .panel {\n display: flex;\n flex-direction: column;\n overflow: hidden;\n background: var(--mj-bg-surface);\n}\n\n.component-studio .panel-left {\n flex-shrink: 0;\n border-right: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n}\n\n.component-studio .panel-center {\n flex: 1;\n display: flex;\n flex-direction: row;\n min-width: 400px;\n}\n\n/* Preview pane (left side of center) */\n.component-studio .panel-center .workspace-preview {\n display: flex;\n flex-direction: column;\n overflow: hidden;\n border-right: 1px solid var(--mj-border-default);\n}\n\n.component-studio .panel-center .workspace-preview.full-width {\n border-right: none;\n}\n\n/* Preview sub-header */\n.component-studio .preview-sub-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 4px 10px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n min-height: 32px;\n}\n\n.component-studio .preview-sub-left {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.component-studio .preview-sub-left i {\n font-size: 11px;\n color: var(--mj-brand-primary);\n}\n\n.component-studio .preview-sub-right {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.component-studio .toggle-editors-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 26px;\n height: 26px;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n cursor: pointer;\n font-size: 12px;\n transition: all 0.15s ease;\n}\n\n.component-studio .toggle-editors-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n.component-studio .toggle-editors-btn.active {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n}\n\n.component-studio .preview-body {\n flex: 1;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n}\n\n/* Editor pane (right side of center) */\n.component-studio .panel-center .workspace-editors {\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n/* Right panel: AI Assistant */\n.component-studio .panel-right {\n flex-shrink: 0;\n border-left: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n}\n\n/* ============================================================\n RESIZE HANDLES\n ============================================================ */\n\n.component-studio .resize-handle {\n flex-shrink: 0;\n width: 5px;\n cursor: col-resize;\n background: transparent;\n position: relative;\n z-index: 5;\n transition: background 0.15s ease;\n}\n\n.component-studio .resize-handle:hover,\n.component-studio .resize-handle:active {\n background: color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n}\n\n/* Center divider \u2014 more obvious separator between preview and editors */\n.component-studio .resize-handle.center-divider {\n width: 7px;\n background: var(--mj-border-default);\n}\n\n.component-studio .resize-handle.center-divider:hover,\n.component-studio .resize-handle.center-divider:active {\n background: color-mix(in srgb, var(--mj-brand-primary) 40%, transparent);\n}\n\n.component-studio .resize-handle .divider-grip {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 3px;\n height: 32px;\n border-radius: 2px;\n background: var(--mj-text-secondary);\n opacity: 0;\n transition: opacity 0.15s ease;\n}\n\n.component-studio .resize-handle:hover .divider-grip {\n opacity: 0.5;\n}\n\n/* SMOOTH RESIZE TRANSITIONS */\n.component-studio:not(.resizing) .panel {\n transition: width 0.15s ease, flex 0.15s ease;\n}\n\n.component-studio:not(.resizing) .workspace-preview,\n.component-studio:not(.resizing) .workspace-editors {\n transition: flex 0.15s ease;\n}\n\n/* ============================================================\n STATUS BAR\n ============================================================ */\n\n.component-studio .status-bar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 2px 16px;\n background: var(--mj-bg-surface-sunken);\n border-top: 1px solid var(--mj-border-default);\n font-size: 11px;\n color: var(--mj-text-secondary);\n flex-shrink: 0;\n min-height: 24px;\n}\n\n.component-studio .status-bar .status-left {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.component-studio .status-bar .status-right {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.component-studio .status-bar .status-item {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.component-studio .status-bar kbd {\n display: inline-block;\n padding: 0 4px;\n font-size: 10px;\n font-family: inherit;\n line-height: 16px;\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 3px;\n}\n\n.component-studio .status-bar .shortcut-hint {\n display: flex;\n align-items: center;\n gap: 4px;\n opacity: 0.8;\n}\n\n/* ============================================================\n KEYBOARD SHORTCUTS OVERLAY\n ============================================================ */\n\n.component-studio .shortcuts-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n}\n\n.component-studio .shortcuts-overlay .shortcuts-panel {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 16px;\n box-shadow: var(--mj-shadow-lg);\n width: 520px;\n max-height: 80vh;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n.component-studio .shortcuts-overlay .shortcuts-panel .shortcuts-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.component-studio .shortcuts-overlay .shortcuts-panel .shortcuts-header h3 {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.component-studio .shortcuts-overlay .shortcuts-panel .shortcuts-header button {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-secondary);\n font-size: 16px;\n padding: 4px;\n border-radius: 4px;\n transition: background 0.15s ease;\n}\n\n.component-studio .shortcuts-overlay .shortcuts-panel .shortcuts-header button:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.component-studio .shortcuts-overlay .shortcuts-panel .shortcuts-body {\n padding: 16px 20px;\n overflow-y: auto;\n}\n\n.component-studio .shortcuts-overlay .shortcuts-panel .shortcuts-body .shortcut-group h4 {\n margin: 0 0 8px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.component-studio .shortcuts-overlay .shortcuts-panel .shortcuts-body .shortcut-group + .shortcut-group {\n margin-top: 16px;\n padding-top: 16px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.component-studio .shortcuts-overlay .shortcuts-panel .shortcuts-body .shortcut-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 6px 0;\n font-size: 13px;\n color: var(--mj-text-primary);\n}\n\n.component-studio .shortcuts-overlay .shortcuts-panel .shortcuts-body .shortcut-row kbd {\n display: inline-block;\n padding: 2px 8px;\n font-size: 12px;\n font-family: inherit;\n line-height: 20px;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n box-shadow: 0 1px 0 var(--mj-border-default);\n min-width: 24px;\n text-align: center;\n}\n\n/* ============================================================\n EMPTY STATE\n ============================================================ */\n\n.component-studio .empty-state {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-bg-surface-sunken);\n}\n\n.component-studio .empty-state .empty-state-content {\n text-align: center;\n max-width: 400px;\n}\n\n.component-studio .empty-state .empty-state-content .empty-state-icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 72px;\n height: 72px;\n border-radius: 50%;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n margin-bottom: 16px;\n}\n\n.component-studio .empty-state .empty-state-content .empty-state-icon i {\n font-size: 28px;\n color: var(--mj-brand-primary);\n}\n\n.component-studio .empty-state .empty-state-content i {\n color: var(--mj-border-default);\n margin-bottom: 16px;\n}\n\n.component-studio .empty-state .empty-state-content h2 {\n margin: 0 0 8px;\n font-size: 22px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.component-studio .empty-state .empty-state-content p {\n margin: 0 0 24px;\n color: var(--mj-text-secondary);\n font-size: 14px;\n line-height: 1.5;\n}\n\n.component-studio .empty-state .empty-state-content .empty-state-actions {\n display: flex;\n gap: 8px;\n justify-content: center;\n}\n\n.component-studio .empty-state .empty-state-content .quick-start-templates {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n flex-wrap: wrap;\n margin-top: 16px;\n}\n\n.component-studio .empty-state .empty-state-content .quick-start-templates .quick-start-label {\n font-size: 12px;\n color: var(--mj-text-secondary);\n margin-right: 4px;\n}\n\n.component-studio .empty-state .empty-state-content .quick-start-templates .quick-start-btn {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 12px;\n font-size: 12px;\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 16px;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.component-studio .empty-state .empty-state-content .quick-start-templates .quick-start-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n border-color: var(--mj-border-default);\n}\n\n.component-studio .empty-state .empty-state-content .quick-start-templates .quick-start-btn i {\n font-size: 11px;\n color: var(--mj-brand-primary);\n margin-bottom: 0;\n}\n\n@keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.4; }\n}\n"] }]
1006
- }], () => [{ type: i1.ComponentStudioStateService }, { type: i2.ComponentVersionService }, { type: i0.ChangeDetectorRef }, { type: i3.MJNotificationService }], { fileInput: [{
1390
+ args: [{ standalone: false, selector: 'mj-component-studio-dashboard', providers: [ComponentStudioStateService, ComponentVersionService], template: "<div class=\"component-studio\" [class.resizing]=\"IsResizing\">\n\n <!-- ============================================================\n TOOLBAR \u2014 Unified bar with integrated breadcrumb\n Left: hamburger + breadcrumb context\n Right: Save | Export | divider | AI | Keyboard | Refresh\n ============================================================ -->\n <div class=\"studio-toolbar\">\n <div class=\"toolbar-context\">\n <!-- Toggle left panel -->\n <button class=\"tb-btn icon-only\" title=\"Toggle browser panel\" (click)=\"ToggleLeftPanel()\">\n <i class=\"fa-solid fa-bars\"></i>\n </button>\n\n @if (state.SelectedComponent) {\n <span class=\"breadcrumb-type\">\n <i class=\"fa-solid fa-cube\"></i>\n {{ state.GetComponentType(state.SelectedComponent) || 'Component' }}\n </span>\n <span class=\"breadcrumb-sep\"><i class=\"fa-solid fa-chevron-right\"></i></span>\n <span class=\"component-label\">{{ state.GetComponentName(state.SelectedComponent) }}</span>\n\n @if (state.IsRunning) {\n <span class=\"running-badge\">\n <span class=\"running-dot-small\"></span>\n Running\n </span>\n }\n @if (state.HasUnsavedChanges) {\n <span class=\"unsaved-dot\" title=\"Unsaved changes\"></span>\n }\n }\n </div>\n\n <div class=\"toolbar-spacer\"></div>\n\n <div class=\"toolbar-actions\">\n <!-- Save Version -->\n @if (state.SelectedComponent) {\n <button class=\"tb-btn primary\" (click)=\"SaveVersion()\" title=\"Save version (Ctrl+S)\">\n <i class=\"fa-solid fa-save\"></i> Save\n </button>\n }\n\n <!-- Refresh Component -->\n @if (state.SelectedComponent && state.IsRunning) {\n <button class=\"tb-btn\" (click)=\"RefreshComponent()\" title=\"Refresh component\">\n <i class=\"fa-solid fa-arrows-rotate\"></i> Refresh\n </button>\n }\n\n <!-- Export -->\n @if (state.SelectedComponent && state.IsRunning) {\n <div class=\"header-dropdown\" [class.open]=\"exportDropdownOpen\">\n <button class=\"tb-btn\" (click)=\"ToggleExportDropdown()\">\n <i class=\"fa-solid fa-file-export\"></i> Export\n <i class=\"fa-solid fa-chevron-down dropdown-icon\"></i>\n </button>\n @if (exportDropdownOpen) {\n <div class=\"dropdown-menu\">\n <button class=\"dropdown-item\" (click)=\"ExportToArtifact()\">\n <i class=\"fa-solid fa-save\"></i> To Artifact\n </button>\n <button class=\"dropdown-item\" (click)=\"ExportToFile()\">\n <i class=\"fa-solid fa-file\"></i> To File\n </button>\n <button class=\"dropdown-item\" (click)=\"ExportToClipboard()\">\n <i class=\"fa-solid fa-clipboard\"></i> To Clipboard\n </button>\n </div>\n }\n </div>\n }\n\n <span class=\"toolbar-divider\"></span>\n\n <!-- AI Panel Toggle -->\n <button class=\"tb-btn icon-only\" [class.active-toggle]=\"!state.IsAIPanelCollapsed\"\n (click)=\"ToggleAIPanel()\"\n [title]=\"state.IsAIPanelCollapsed ? 'Show AI Assistant' : 'Hide AI Assistant'\">\n <i class=\"fa-solid fa-robot\"></i>\n </button>\n\n <!-- Keyboard Shortcuts -->\n <button class=\"tb-btn icon-only\" (click)=\"ShowKeyboardShortcuts = !ShowKeyboardShortcuts\"\n title=\"Keyboard shortcuts (?)\">\n <i class=\"fa-solid fa-keyboard\"></i>\n </button>\n\n <!-- Refresh -->\n <button class=\"tb-btn icon-only\" (click)=\"RefreshData()\" [disabled]=\"state.IsLoading\" title=\"Refresh data\">\n <i class=\"fa-solid fa-arrows-rotate\"></i>\n </button>\n </div>\n\n <!-- Hidden file input -->\n <input #fileInput type=\"file\" accept=\".json\" (change)=\"HandleFileSelect($event)\" style=\"display: none;\" />\n </div>\n\n <!-- ============================================================\n THREE-PANEL BODY\n ============================================================ -->\n <div class=\"studio-body\">\n\n <!-- Left Panel: Component Browser (collapsible) -->\n @if (!IsLeftPanelCollapsed) {\n <div class=\"panel panel-left\" [style.width.px]=\"leftPanelWidth\">\n <mj-component-browser\n (NewComponent)=\"OnNewComponent()\"\n (ImportFromFile)=\"ImportFromFile()\"\n (ImportFromText)=\"ImportFromText()\"\n (ImportFromArtifact)=\"ImportFromArtifact()\">\n </mj-component-browser>\n </div>\n\n <!-- Resize Handle: Left <-> Center -->\n <div class=\"resize-handle\" (mousedown)=\"OnLeftResizeStart($event)\"></div>\n }\n\n <!-- Center Panel: Workspace (side-by-side: Preview LEFT, Editor RIGHT) -->\n <div class=\"panel panel-center\">\n @if (state.SelectedComponent) {\n <!-- Preview (left side) -->\n <div class=\"workspace-preview\" [class.full-width]=\"IsEditorPanelCollapsed\" [style.flex]=\"IsEditorPanelCollapsed ? '1 1 100%' : previewFlex\">\n <div class=\"preview-sub-header\">\n <div class=\"preview-sub-left\">\n <i class=\"fa-solid fa-eye\"></i>\n <span>Preview</span>\n </div>\n <div class=\"preview-sub-right\">\n <!-- Toggle editor panel -->\n <button class=\"toggle-editors-btn\" [class.active]=\"!IsEditorPanelCollapsed\"\n (click)=\"ToggleEditorPanel()\" title=\"Toggle editor panel\">\n <i class=\"fa-solid fa-columns\"></i>\n </button>\n </div>\n </div>\n <div class=\"preview-body\">\n <mj-component-preview\n (AskAIToFix)=\"OnAskAIToFix($event)\">\n </mj-component-preview>\n </div>\n </div>\n\n <!-- Resize Handle: Preview <-> Editor (obvious center divider) -->\n @if (!IsEditorPanelCollapsed) {\n <div class=\"resize-handle center-divider\" (mousedown)=\"OnCenterResizeStart($event)\">\n <div class=\"divider-grip\"></div>\n </div>\n }\n\n <!-- Editor Tabs (right side, collapsible) -->\n @if (!IsEditorPanelCollapsed) {\n <div class=\"workspace-editors\" [style.flex]=\"editorFlex\">\n <mj-editor-tabs></mj-editor-tabs>\n </div>\n }\n } @else {\n <!-- Enhanced Empty State -->\n <div class=\"empty-state\">\n <div class=\"empty-state-content\">\n <div class=\"empty-state-icon\">\n <i class=\"fa-solid fa-rocket\"></i>\n </div>\n <h2>Ready to Build</h2>\n <p>Select a component from the browser or create a new one to get started</p>\n <div class=\"empty-state-actions\">\n <button mjButton variant=\"primary\" (click)=\"OnNewComponent()\">\n <span class=\"fa-solid fa-plus\"></span> New Component\n </button>\n <button mjButton (click)=\"ImportFromFile()\">\n <span class=\"fa-solid fa-file-import\"></span> Import\n </button>\n </div>\n <div class=\"quick-start-templates\">\n <span class=\"quick-start-label\">Quick start:</span>\n <button class=\"quick-start-btn\" (click)=\"OnQuickStart('dashboard')\">\n <i class=\"fa-solid fa-chart-line\"></i> Dashboard\n </button>\n <button class=\"quick-start-btn\" (click)=\"OnQuickStart('report')\">\n <i class=\"fa-solid fa-file-alt\"></i> Report\n </button>\n <button class=\"quick-start-btn\" (click)=\"OnQuickStart('chart')\">\n <i class=\"fa-solid fa-chart-pie\"></i> Chart\n </button>\n <button class=\"quick-start-btn\" (click)=\"OnQuickStart('form')\">\n <i class=\"fa-solid fa-edit\"></i> Form\n </button>\n </div>\n </div>\n </div>\n }\n </div>\n\n <!-- Right panel \u2014 only renders when the user has actively selected a\n component (form palette OR AI assistant). Showing an empty chat\n against no component is more noise than help, so we collapse the\n whole pane in that case. The collapse-button state is still\n honored: user can also explicitly hide. -->\n @if (!state.IsAIPanelCollapsed && state.SelectedComponent) {\n <!-- Resize Handle: Center <-> Right -->\n <div class=\"resize-handle\" (mousedown)=\"OnRightResizeStart($event)\"></div>\n <div class=\"panel panel-right\" [style.width.px]=\"rightPanelWidth\">\n @if (IsFormRoleComponent) {\n <mj-form-builder-right-panel\n [Schema]=\"state.FormSchema\"\n [Canvas]=\"state.FormCanvas\"\n [SelectedElementId]=\"state.FormSelectedElementId\"\n [SelectedSectionId]=\"state.FormSelectedSectionId\"\n (ElementChanged)=\"OnFormBuilderElementChanged($event)\"\n (SectionChanged)=\"OnFormBuilderSectionChanged($event)\"\n (ElementDeleted)=\"OnFormBuilderElementDeleted($event)\"\n (SectionDeleted)=\"OnFormBuilderSectionDeleted($event)\"\n (FieldAdded)=\"OnFormBuilderFieldAdded($event)\">\n </mj-form-builder-right-panel>\n } @else {\n <mj-ai-assistant-panel></mj-ai-assistant-panel>\n }\n </div>\n }\n </div>\n\n <!-- ============================================================\n STATUS BAR\n ============================================================ -->\n <div class=\"status-bar\">\n <div class=\"status-left\">\n <span class=\"status-item\">\n <i class=\"fa-solid fa-cube\"></i>\n {{ state.FilteredComponents.length }} component{{ state.FilteredComponents.length !== 1 ? 's' : '' }}\n </span>\n </div>\n <div class=\"status-right\">\n @if (LastSavedTime) {\n <span class=\"status-item\">\n <i class=\"fa-solid fa-check-circle\"></i>\n Saved {{ LastSavedTime | date:'shortTime' }}\n </span>\n }\n <span class=\"status-item shortcut-hint\">\n <kbd>?</kbd> Shortcuts\n </span>\n </div>\n </div>\n\n <!-- ============================================================\n KEYBOARD SHORTCUTS OVERLAY\n ============================================================ -->\n @if (ShowKeyboardShortcuts) {\n <div class=\"shortcuts-overlay\" (click)=\"ShowKeyboardShortcuts = false\">\n <div class=\"shortcuts-panel\" (click)=\"$event.stopPropagation()\">\n <div class=\"shortcuts-header\">\n <h3>Keyboard Shortcuts</h3>\n <button class=\"shortcuts-close\" (click)=\"ShowKeyboardShortcuts = false\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n <div class=\"shortcuts-body\">\n <div class=\"shortcut-group\">\n <h4>General</h4>\n <div class=\"shortcut-row\">\n <span class=\"shortcut-keys\"><kbd>Ctrl</kbd> + <kbd>S</kbd></span>\n <span class=\"shortcut-desc\">Save version</span>\n </div>\n <div class=\"shortcut-row\">\n <span class=\"shortcut-keys\"><kbd>Ctrl</kbd> + <kbd>N</kbd></span>\n <span class=\"shortcut-desc\">New component</span>\n </div>\n <div class=\"shortcut-row\">\n <span class=\"shortcut-keys\"><kbd>?</kbd></span>\n <span class=\"shortcut-desc\">Toggle shortcuts</span>\n </div>\n <div class=\"shortcut-row\">\n <span class=\"shortcut-keys\"><kbd>Esc</kbd></span>\n <span class=\"shortcut-desc\">Close overlay</span>\n </div>\n </div>\n </div>\n </div>\n </div>\n }\n\n <!-- ============================================================\n NEW COMPONENT DIALOG\n ============================================================ -->\n @if (ShowNewComponentDialog) {\n <mj-new-component-dialog\n [Visible]=\"ShowNewComponentDialog\"\n (Close)=\"OnNewComponentDialogClose($event)\">\n </mj-new-component-dialog>\n }\n\n @if (ShowSaveVersionDialog) {\n <mj-save-version-dialog\n [Visible]=\"ShowSaveVersionDialog\"\n [CurrentVersion]=\"versionService.CurrentVersionNumber\"\n (Save)=\"OnSaveVersionConfirm($event)\"\n (Cancel)=\"ShowSaveVersionDialog = false\">\n </mj-save-version-dialog>\n }\n\n <!-- Post-save Override dialog for form-role Components. Fires after a\n successful version save when the spec declares componentRole='form'\n and the user has picked a target entity in the Field Binding inspector. -->\n <mj-form-override-dialog\n [Visible]=\"ShowFormOverrideDialog\"\n [ComponentName]=\"PendingOverrideComponentName\"\n [EntityName]=\"PendingOverrideEntityName\"\n (confirmed)=\"OnFormOverrideDialogConfirm($event)\"\n (dismissed)=\"OnFormOverrideDialogDismiss()\">\n </mj-form-override-dialog>\n\n <!-- Text Import Dialog -->\n @if (ShowTextImportDialog) {\n <mj-dialog [Visible]=\"true\" Title=\"Import Component from Text\" (Close)=\"OnTextImportCancel()\" [Width]=\"700\" [MinWidth]=\"500\">\n <app-text-import-dialog\n (importSpec)=\"OnTextImportSpec($event)\"\n (cancelDialog)=\"OnTextImportCancel()\">\n </app-text-import-dialog>\n </mj-dialog>\n }\n\n <!-- Artifact Load Dialog -->\n @if (ShowArtifactLoadDialog) {\n <app-artifact-load-dialog\n [Visible]=\"ShowArtifactLoadDialog\"\n (Close)=\"OnArtifactLoadClose($event)\">\n </app-artifact-load-dialog>\n }\n\n <!-- Artifact Selection Dialog -->\n @if (ShowArtifactSelectionDialog) {\n <app-artifact-selection-dialog\n [Visible]=\"ShowArtifactSelectionDialog\"\n (Close)=\"OnArtifactSelectionClose($event)\">\n </app-artifact-selection-dialog>\n }\n</div>\n", styles: [":host {\n display: block;\n width: 100%;\n height: 100%;\n}\n\n.component-studio {\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 \u2014 unified bar with integrated breadcrumb\n ============================================================ */\n\n.component-studio .studio-toolbar {\n display: flex;\n align-items: center;\n padding: 0 8px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n z-index: 10;\n min-height: 42px;\n gap: 8px;\n}\n\n/* Left: hamburger + breadcrumb context */\n.component-studio .toolbar-context {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 0;\n flex-shrink: 1;\n overflow: hidden;\n}\n\n.component-studio .toolbar-spacer {\n flex: 1;\n}\n\n/* Right: action buttons */\n.component-studio .toolbar-actions {\n display: flex;\n align-items: center;\n gap: 4px;\n flex-shrink: 0;\n}\n\n/* ---- Toolbar buttons ---- */\n.component-studio .tb-btn {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 5px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n background: var(--mj-bg-surface);\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 line-height: 1;\n}\n\n.component-studio .tb-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n border-color: var(--mj-border-default);\n}\n\n.component-studio .tb-btn:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n}\n\n.component-studio .tb-btn i {\n font-size: 12px;\n}\n\n.component-studio .tb-btn.icon-only {\n padding: 5px 7px;\n}\n\n.component-studio .tb-btn.primary {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-color: var(--mj-brand-primary);\n}\n\n.component-studio .tb-btn.primary:hover {\n opacity: 0.9;\n}\n\n.component-studio .tb-btn.active-toggle {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n}\n\n/* ---- Breadcrumb elements inside toolbar ---- */\n.component-studio .breadcrumb-type {\n display: flex;\n align-items: center;\n gap: 5px;\n font-size: 12px;\n color: var(--mj-text-secondary);\n white-space: nowrap;\n}\n\n.component-studio .breadcrumb-type i {\n font-size: 11px;\n color: var(--mj-brand-primary);\n}\n\n.component-studio .breadcrumb-sep {\n font-size: 9px;\n color: var(--mj-border-default);\n}\n\n.component-studio .component-label {\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 240px;\n}\n\n.component-studio .running-badge {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 2px 8px;\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n font-size: 11px;\n font-weight: 600;\n border-radius: 10px;\n white-space: nowrap;\n}\n\n.component-studio .running-dot-small {\n display: inline-block;\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: var(--mj-status-success);\n animation: pulse 1.5s ease-in-out infinite;\n}\n\n.component-studio .unsaved-dot {\n display: inline-block;\n width: 7px;\n height: 7px;\n border-radius: 50%;\n background: var(--mj-status-warning);\n animation: pulse 2s infinite;\n flex-shrink: 0;\n}\n\n.component-studio .toolbar-divider {\n width: 1px;\n height: 18px;\n background: var(--mj-border-default);\n margin: 0 2px;\n flex-shrink: 0;\n}\n\n.component-studio .dropdown-icon {\n font-size: 9px;\n opacity: 0.6;\n}\n\n/* ---- Dropdown menus ---- */\n.component-studio .header-dropdown {\n position: relative;\n}\n\n.component-studio .header-dropdown .dropdown-menu {\n position: absolute;\n top: calc(100% + 4px);\n right: 0;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n box-shadow: var(--mj-shadow-lg);\n z-index: 100;\n min-width: 180px;\n overflow: hidden;\n}\n\n.component-studio .header-dropdown .dropdown-menu .dropdown-item {\n display: flex;\n align-items: center;\n gap: 10px;\n width: 100%;\n padding: 10px 16px;\n border: none;\n background: none;\n text-align: left;\n cursor: pointer;\n font-size: 13px;\n color: var(--mj-text-primary);\n transition: background 0.15s ease;\n}\n\n.component-studio .header-dropdown .dropdown-menu .dropdown-item:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.component-studio .header-dropdown .dropdown-menu .dropdown-item:not(:last-child) {\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.component-studio .header-dropdown .dropdown-menu .dropdown-item i {\n width: 16px;\n text-align: center;\n color: var(--mj-brand-primary);\n font-size: 13px;\n}\n\n/* ============================================================\n THREE-PANEL BODY\n ============================================================ */\n\n.component-studio .studio-body {\n display: flex;\n flex: 1;\n overflow: hidden;\n}\n\n.component-studio .panel {\n display: flex;\n flex-direction: column;\n overflow: hidden;\n background: var(--mj-bg-surface);\n}\n\n.component-studio .panel-left {\n flex-shrink: 0;\n border-right: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n}\n\n.component-studio .panel-center {\n flex: 1;\n display: flex;\n flex-direction: row;\n min-width: 400px;\n}\n\n/* Preview pane (left side of center) */\n.component-studio .panel-center .workspace-preview {\n display: flex;\n flex-direction: column;\n overflow: hidden;\n border-right: 1px solid var(--mj-border-default);\n}\n\n.component-studio .panel-center .workspace-preview.full-width {\n border-right: none;\n}\n\n/* Preview sub-header */\n.component-studio .preview-sub-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 4px 10px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n min-height: 32px;\n}\n\n.component-studio .preview-sub-left {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.component-studio .preview-sub-left i {\n font-size: 11px;\n color: var(--mj-brand-primary);\n}\n\n.component-studio .preview-sub-right {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.component-studio .toggle-editors-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 26px;\n height: 26px;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n cursor: pointer;\n font-size: 12px;\n transition: all 0.15s ease;\n}\n\n.component-studio .toggle-editors-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n}\n\n.component-studio .toggle-editors-btn.active {\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n}\n\n.component-studio .preview-body {\n flex: 1;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n}\n\n/* Editor pane (right side of center) */\n.component-studio .panel-center .workspace-editors {\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n/* Right panel: AI Assistant */\n.component-studio .panel-right {\n flex-shrink: 0;\n border-left: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n}\n\n/* ============================================================\n RESIZE HANDLES\n ============================================================ */\n\n.component-studio .resize-handle {\n flex-shrink: 0;\n width: 5px;\n cursor: col-resize;\n background: transparent;\n position: relative;\n z-index: 5;\n transition: background 0.15s ease;\n}\n\n.component-studio .resize-handle:hover,\n.component-studio .resize-handle:active {\n background: color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n}\n\n/* Center divider \u2014 more obvious separator between preview and editors */\n.component-studio .resize-handle.center-divider {\n width: 7px;\n background: var(--mj-border-default);\n}\n\n.component-studio .resize-handle.center-divider:hover,\n.component-studio .resize-handle.center-divider:active {\n background: color-mix(in srgb, var(--mj-brand-primary) 40%, transparent);\n}\n\n.component-studio .resize-handle .divider-grip {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 3px;\n height: 32px;\n border-radius: 2px;\n background: var(--mj-text-secondary);\n opacity: 0;\n transition: opacity 0.15s ease;\n}\n\n.component-studio .resize-handle:hover .divider-grip {\n opacity: 0.5;\n}\n\n/* SMOOTH RESIZE TRANSITIONS */\n.component-studio:not(.resizing) .panel {\n transition: width 0.15s ease, flex 0.15s ease;\n}\n\n.component-studio:not(.resizing) .workspace-preview,\n.component-studio:not(.resizing) .workspace-editors {\n transition: flex 0.15s ease;\n}\n\n/* ============================================================\n STATUS BAR\n ============================================================ */\n\n.component-studio .status-bar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 2px 16px;\n background: var(--mj-bg-surface-sunken);\n border-top: 1px solid var(--mj-border-default);\n font-size: 11px;\n color: var(--mj-text-secondary);\n flex-shrink: 0;\n min-height: 24px;\n}\n\n.component-studio .status-bar .status-left {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.component-studio .status-bar .status-right {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.component-studio .status-bar .status-item {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.component-studio .status-bar kbd {\n display: inline-block;\n padding: 0 4px;\n font-size: 10px;\n font-family: inherit;\n line-height: 16px;\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 3px;\n}\n\n.component-studio .status-bar .shortcut-hint {\n display: flex;\n align-items: center;\n gap: 4px;\n opacity: 0.8;\n}\n\n/* ============================================================\n KEYBOARD SHORTCUTS OVERLAY\n ============================================================ */\n\n.component-studio .shortcuts-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n}\n\n.component-studio .shortcuts-overlay .shortcuts-panel {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 16px;\n box-shadow: var(--mj-shadow-lg);\n width: 520px;\n max-height: 80vh;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n.component-studio .shortcuts-overlay .shortcuts-panel .shortcuts-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.component-studio .shortcuts-overlay .shortcuts-panel .shortcuts-header h3 {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.component-studio .shortcuts-overlay .shortcuts-panel .shortcuts-header button {\n background: none;\n border: none;\n cursor: pointer;\n color: var(--mj-text-secondary);\n font-size: 16px;\n padding: 4px;\n border-radius: 4px;\n transition: background 0.15s ease;\n}\n\n.component-studio .shortcuts-overlay .shortcuts-panel .shortcuts-header button:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.component-studio .shortcuts-overlay .shortcuts-panel .shortcuts-body {\n padding: 16px 20px;\n overflow-y: auto;\n}\n\n.component-studio .shortcuts-overlay .shortcuts-panel .shortcuts-body .shortcut-group h4 {\n margin: 0 0 8px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.component-studio .shortcuts-overlay .shortcuts-panel .shortcuts-body .shortcut-group + .shortcut-group {\n margin-top: 16px;\n padding-top: 16px;\n border-top: 1px solid var(--mj-border-default);\n}\n\n.component-studio .shortcuts-overlay .shortcuts-panel .shortcuts-body .shortcut-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 6px 0;\n font-size: 13px;\n color: var(--mj-text-primary);\n}\n\n.component-studio .shortcuts-overlay .shortcuts-panel .shortcuts-body .shortcut-row kbd {\n display: inline-block;\n padding: 2px 8px;\n font-size: 12px;\n font-family: inherit;\n line-height: 20px;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n box-shadow: 0 1px 0 var(--mj-border-default);\n min-width: 24px;\n text-align: center;\n}\n\n/* ============================================================\n EMPTY STATE\n ============================================================ */\n\n.component-studio .empty-state {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-bg-surface-sunken);\n}\n\n.component-studio .empty-state .empty-state-content {\n text-align: center;\n max-width: 400px;\n}\n\n.component-studio .empty-state .empty-state-content .empty-state-icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 72px;\n height: 72px;\n border-radius: 50%;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n margin-bottom: 16px;\n}\n\n.component-studio .empty-state .empty-state-content .empty-state-icon i {\n font-size: 28px;\n color: var(--mj-brand-primary);\n}\n\n.component-studio .empty-state .empty-state-content i {\n color: var(--mj-border-default);\n margin-bottom: 16px;\n}\n\n.component-studio .empty-state .empty-state-content h2 {\n margin: 0 0 8px;\n font-size: 22px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.component-studio .empty-state .empty-state-content p {\n margin: 0 0 24px;\n color: var(--mj-text-secondary);\n font-size: 14px;\n line-height: 1.5;\n}\n\n.component-studio .empty-state .empty-state-content .empty-state-actions {\n display: flex;\n gap: 8px;\n justify-content: center;\n}\n\n.component-studio .empty-state .empty-state-content .quick-start-templates {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n flex-wrap: wrap;\n margin-top: 16px;\n}\n\n.component-studio .empty-state .empty-state-content .quick-start-templates .quick-start-label {\n font-size: 12px;\n color: var(--mj-text-secondary);\n margin-right: 4px;\n}\n\n.component-studio .empty-state .empty-state-content .quick-start-templates .quick-start-btn {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 12px;\n font-size: 12px;\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 16px;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.component-studio .empty-state .empty-state-content .quick-start-templates .quick-start-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-primary);\n border-color: var(--mj-border-default);\n}\n\n.component-studio .empty-state .empty-state-content .quick-start-templates .quick-start-btn i {\n font-size: 11px;\n color: var(--mj-brand-primary);\n margin-bottom: 0;\n}\n\n@keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.4; }\n}\n"] }]
1391
+ }], () => [{ type: i1.ComponentStudioStateService }, { type: i2.ComponentVersionService }, { type: i0.ChangeDetectorRef }, { type: i3.MJNotificationService }, { type: i4.EntityFormOverrideService }], { fileInput: [{
1007
1392
  type: ViewChild,
1008
1393
  args: ['fileInput', { static: false }]
1009
1394
  }], OnKeyDown: [{
@@ -1013,5 +1398,5 @@ export { ComponentStudioDashboardComponent };
1013
1398
  type: HostListener,
1014
1399
  args: ['document:click', ['$event']]
1015
1400
  }] }); })();
1016
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ComponentStudioDashboardComponent, { className: "ComponentStudioDashboardComponent", filePath: "src/ComponentStudio/component-studio-dashboard.component.ts", lineNumber: 52 }); })();
1401
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ComponentStudioDashboardComponent, { className: "ComponentStudioDashboardComponent", filePath: "src/ComponentStudio/component-studio-dashboard.component.ts", lineNumber: 61 }); })();
1017
1402
  //# sourceMappingURL=component-studio-dashboard.component.js.map