@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
@@ -0,0 +1,246 @@
1
+ import { Injectable } from '@angular/core';
2
+ import { Metadata, RunView, LogError } from '@memberjunction/core';
3
+ import * as i0 from "@angular/core";
4
+ /**
5
+ * Studio-side service for managing `EntityFormOverride` rows from Component
6
+ * Studio (post-save dialog + sub-list of existing overrides).
7
+ *
8
+ * Reads use `RunView` with `ResultType: 'simple'` for the list view —
9
+ * cheaper than loading entity objects when we just want to render rows.
10
+ * Writes (`CreateOverride`, `DeactivateOverride`) load the strongly-typed
11
+ * `MJEntityFormOverrideEntity` and call `Save()`. Per the project
12
+ * "NO WEAK TYPING" rule we never use `.Set('FieldName', ...)`.
13
+ *
14
+ * Unlike the Form Builder agent's action (`__CreateInteractiveForm`),
15
+ * which clamps Scope='User' as a security boundary, the Studio service
16
+ * **honors the dialog's Scope/Role/Priority choices** — Studio is the
17
+ * deliberate human-authoring path where promotion to Role / Global is a
18
+ * core feature. The dialog already enforces that Scope='Role' requires a
19
+ * RoleID.
20
+ */
21
+ export class EntityFormOverrideService {
22
+ /**
23
+ * Fetch existing overrides for an entity, scoped to the calling user's
24
+ * visibility (User, their roles, Global). Used by the Studio sub-list
25
+ * showing "what overrides already exist for this entity."
26
+ */
27
+ async ListOverridesForEntity(entityName, user, provider) {
28
+ const p = provider ?? Metadata.Provider;
29
+ if (!p)
30
+ return [];
31
+ const entityInfo = p.EntityByName(entityName);
32
+ if (!entityInfo)
33
+ return [];
34
+ const userRoleIds = (user.UserRoles ?? []).map(r => r.RoleID).filter(Boolean);
35
+ const roleClause = userRoleIds.length > 0
36
+ ? `(Scope='Role' AND RoleID IN (${userRoleIds.map(id => `'${id}'`).join(',')}))`
37
+ : "(1=0)";
38
+ const filter = `
39
+ EntityID='${entityInfo.ID}' AND (
40
+ (Scope='User' AND UserID='${user.ID}')
41
+ OR ${roleClause}
42
+ OR Scope='Global'
43
+ )
44
+ `.trim();
45
+ const rv = RunView.FromMetadataProvider(p);
46
+ const result = await rv.RunView({
47
+ EntityName: 'MJ: Entity Form Overrides',
48
+ Fields: ['ID', 'EntityID', 'ComponentID', 'Name', 'Description',
49
+ 'Scope', 'UserID', 'RoleID', 'Priority', 'Status'],
50
+ ExtraFilter: filter,
51
+ OrderBy: `CASE Scope WHEN 'User' THEN 1 WHEN 'Role' THEN 2 ELSE 3 END, Priority DESC`,
52
+ ResultType: 'simple',
53
+ BypassCache: true,
54
+ }, user);
55
+ if (!result.Success) {
56
+ LogError(`EntityFormOverrideService.ListOverridesForEntity: ${result.ErrorMessage}`);
57
+ return [];
58
+ }
59
+ return result.Results ?? [];
60
+ }
61
+ /**
62
+ * Create an `EntityFormOverride` row pointing the just-saved Component
63
+ * at an entity. Honors the dialog's Scope/Role/Priority/Status choices
64
+ * (unlike the Form Builder action which clamps to User scope).
65
+ */
66
+ async CreateOverride(componentID, result, user, provider) {
67
+ const p = provider ?? Metadata.Provider;
68
+ if (!p) {
69
+ return { Success: false, Error: 'No metadata provider available.' };
70
+ }
71
+ const entityInfo = p.EntityByName(result.EntityName);
72
+ if (!entityInfo) {
73
+ return { Success: false, Error: `Entity '${result.EntityName}' is not registered.` };
74
+ }
75
+ try {
76
+ const override = await p.GetEntityObject('MJ: Entity Form Overrides', user);
77
+ override.NewRecord();
78
+ override.EntityID = entityInfo.ID;
79
+ override.ComponentID = componentID;
80
+ override.Name = result.Name;
81
+ override.Description = result.Description;
82
+ override.Scope = result.Scope;
83
+ // Mutual exclusion enforced by the DB CHECK constraint
84
+ // (see migrations/v5/V202605161430...Interactive_Forms.sql).
85
+ // We mirror it here so the row is well-shaped before the round
86
+ // trip and the CHECK constraint never has to fire.
87
+ override.UserID = result.Scope === 'User' ? user.ID : null;
88
+ override.RoleID = result.Scope === 'Role' ? result.RoleID : null;
89
+ override.Priority = result.Priority;
90
+ override.Status = result.Status;
91
+ const saved = await override.Save();
92
+ if (!saved) {
93
+ return {
94
+ Success: false,
95
+ Error: override.LatestResult?.CompleteMessage ?? 'Save returned false with no diagnostic.',
96
+ };
97
+ }
98
+ return { Success: true, ID: override.ID };
99
+ }
100
+ catch (err) {
101
+ const message = err instanceof Error ? err.message : String(err);
102
+ LogError(`EntityFormOverrideService.CreateOverride: ${message}`);
103
+ return { Success: false, Error: message };
104
+ }
105
+ }
106
+ /**
107
+ * Promote a Pending override to Active. Mirrors the server-side
108
+ * `Activate Interactive Form Version` action's intent without round-
109
+ * tripping through the Action layer — for cockpit-internal usage where
110
+ * the user is explicitly clicking "Make Active".
111
+ *
112
+ * Atomically flips the target Override to Active AND demotes any sibling
113
+ * Active override at the same scope target to Inactive. Components
114
+ * mirror the override status (Published / Draft / Deprecated).
115
+ */
116
+ async activateVersion(id, user, provider) {
117
+ const p = provider ?? Metadata.Provider;
118
+ const u = user ?? p?.CurrentUser;
119
+ if (!p || !u)
120
+ return { Success: false, Error: 'No provider/user available.' };
121
+ try {
122
+ const target = await p.GetEntityObject('MJ: Entity Form Overrides', u);
123
+ const loaded = await target.Load(id);
124
+ if (!loaded)
125
+ return { Success: false, Error: `Override ${id} not found.` };
126
+ // Find sibling Actives at the same scope target.
127
+ const rv = RunView.FromMetadataProvider(p);
128
+ const scopeClause = target.Scope === 'User'
129
+ ? `Scope='User' AND UserID='${target.UserID}'`
130
+ : target.Scope === 'Role'
131
+ ? `Scope='Role' AND RoleID='${target.RoleID}'`
132
+ : `Scope='Global' AND UserID IS NULL AND RoleID IS NULL`;
133
+ const priors = await rv.RunView({
134
+ EntityName: 'MJ: Entity Form Overrides',
135
+ ExtraFilter: `EntityID='${target.EntityID}' AND ${scopeClause} AND Status='Active' AND ID <> '${target.ID}'`,
136
+ Fields: ['ID', 'ComponentID'],
137
+ ResultType: 'simple',
138
+ }, u);
139
+ // Promote target.
140
+ target.Status = 'Active';
141
+ await target.Save();
142
+ const targetComp = await p.GetEntityObject('MJ: Components', u);
143
+ if (await targetComp.Load(target.ComponentID)) {
144
+ targetComp.Status = 'Published';
145
+ await targetComp.Save();
146
+ }
147
+ // Demote priors.
148
+ for (const prior of priors.Results ?? []) {
149
+ const priorO = await p.GetEntityObject('MJ: Entity Form Overrides', u);
150
+ if (await priorO.Load(prior.ID)) {
151
+ priorO.Status = 'Inactive';
152
+ await priorO.Save();
153
+ }
154
+ const priorC = await p.GetEntityObject('MJ: Components', u);
155
+ if (await priorC.Load(prior.ComponentID)) {
156
+ priorC.Status = 'Deprecated';
157
+ await priorC.Save();
158
+ }
159
+ }
160
+ return { Success: true };
161
+ }
162
+ catch (err) {
163
+ const message = err instanceof Error ? err.message : String(err);
164
+ LogError(`EntityFormOverrideService.activateVersion: ${message}`);
165
+ return { Success: false, Error: message };
166
+ }
167
+ }
168
+ /**
169
+ * Re-point an Active override at an older Component row in the same Name
170
+ * lineage. Pure UPDATE on the override; no new rows created. Mirrors the
171
+ * server-side `Revert Interactive Form` action.
172
+ */
173
+ async revertToComponent(activeOverrideID, targetComponentID, user, provider) {
174
+ const p = provider ?? Metadata.Provider;
175
+ const u = user ?? p?.CurrentUser;
176
+ if (!p || !u)
177
+ return { Success: false, Error: 'No provider/user available.' };
178
+ try {
179
+ const override = await p.GetEntityObject('MJ: Entity Form Overrides', u);
180
+ if (!await override.Load(activeOverrideID)) {
181
+ return { Success: false, Error: `Override ${activeOverrideID} not found.` };
182
+ }
183
+ const previousComponentID = override.ComponentID;
184
+ override.ComponentID = targetComponentID;
185
+ const saved = await override.Save();
186
+ if (!saved) {
187
+ return { Success: false, Error: override.LatestResult?.CompleteMessage ?? 'Save returned false.' };
188
+ }
189
+ // Flip Component statuses to keep them coherent.
190
+ const newActive = await p.GetEntityObject('MJ: Components', u);
191
+ if (await newActive.Load(targetComponentID)) {
192
+ newActive.Status = 'Published';
193
+ await newActive.Save();
194
+ }
195
+ const oldActive = await p.GetEntityObject('MJ: Components', u);
196
+ if (await oldActive.Load(previousComponentID)) {
197
+ oldActive.Status = 'Deprecated';
198
+ await oldActive.Save();
199
+ }
200
+ return { Success: true };
201
+ }
202
+ catch (err) {
203
+ const message = err instanceof Error ? err.message : String(err);
204
+ LogError(`EntityFormOverrideService.revertToComponent: ${message}`);
205
+ return { Success: false, Error: message };
206
+ }
207
+ }
208
+ /**
209
+ * Flip an override's Status to `Inactive`. Preserves the row so it can
210
+ * be re-activated later (vs. deleting outright, which would lose the
211
+ * Component link and require re-authoring).
212
+ */
213
+ async DeactivateOverride(id, user, provider) {
214
+ const p = provider ?? Metadata.Provider;
215
+ if (!p)
216
+ return { Success: false, Error: 'No metadata provider available.' };
217
+ try {
218
+ const override = await p.GetEntityObject('MJ: Entity Form Overrides', user);
219
+ const loaded = await override.Load(id);
220
+ if (!loaded) {
221
+ return { Success: false, Error: `Override ${id} not found.` };
222
+ }
223
+ override.Status = 'Inactive';
224
+ const saved = await override.Save();
225
+ if (!saved) {
226
+ return {
227
+ Success: false,
228
+ Error: override.LatestResult?.CompleteMessage ?? 'Save returned false.',
229
+ };
230
+ }
231
+ return { Success: true };
232
+ }
233
+ catch (err) {
234
+ const message = err instanceof Error ? err.message : String(err);
235
+ LogError(`EntityFormOverrideService.DeactivateOverride: ${message}`);
236
+ return { Success: false, Error: message };
237
+ }
238
+ }
239
+ static ɵfac = function EntityFormOverrideService_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || EntityFormOverrideService)(); };
240
+ static ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: EntityFormOverrideService, factory: EntityFormOverrideService.ɵfac, providedIn: 'root' });
241
+ }
242
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(EntityFormOverrideService, [{
243
+ type: Injectable,
244
+ args: [{ providedIn: 'root' }]
245
+ }], null, null); })();
246
+ //# sourceMappingURL=entity-form-override.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entity-form-override.service.js","sourceRoot":"","sources":["../../../src/ComponentStudio/services/entity-form-override.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from '@angular/core';\nimport { Metadata, RunView, IMetadataProvider, UserInfo, LogError } from '@memberjunction/core';\nimport { MJEntityFormOverrideEntity, MJComponentEntity } from '@memberjunction/core-entities';\nimport type { FormOverrideDialogResult } from '../components/form-override-dialog.component';\n\n/** Slim row shape for listing existing overrides — matches FormResolverService. */\nexport interface EntityFormOverrideRow {\n ID: string;\n EntityID: string;\n ComponentID: string;\n Name: string;\n Description: string | null;\n Scope: 'User' | 'Role' | 'Global';\n UserID: string | null;\n RoleID: string | null;\n Priority: number;\n Status: 'Active' | 'Inactive' | 'Pending';\n}\n\n/**\n * Studio-side service for managing `EntityFormOverride` rows from Component\n * Studio (post-save dialog + sub-list of existing overrides).\n *\n * Reads use `RunView` with `ResultType: 'simple'` for the list view —\n * cheaper than loading entity objects when we just want to render rows.\n * Writes (`CreateOverride`, `DeactivateOverride`) load the strongly-typed\n * `MJEntityFormOverrideEntity` and call `Save()`. Per the project\n * \"NO WEAK TYPING\" rule we never use `.Set('FieldName', ...)`.\n *\n * Unlike the Form Builder agent's action (`__CreateInteractiveForm`),\n * which clamps Scope='User' as a security boundary, the Studio service\n * **honors the dialog's Scope/Role/Priority choices** — Studio is the\n * deliberate human-authoring path where promotion to Role / Global is a\n * core feature. The dialog already enforces that Scope='Role' requires a\n * RoleID.\n */\n@Injectable({ providedIn: 'root' })\nexport class EntityFormOverrideService {\n\n /**\n * Fetch existing overrides for an entity, scoped to the calling user's\n * visibility (User, their roles, Global). Used by the Studio sub-list\n * showing \"what overrides already exist for this entity.\"\n */\n public async ListOverridesForEntity(\n entityName: string,\n user: UserInfo,\n provider?: IMetadataProvider,\n ): Promise<EntityFormOverrideRow[]> {\n const p = provider ?? Metadata.Provider;\n if (!p) return [];\n const entityInfo = p.EntityByName(entityName);\n if (!entityInfo) return [];\n\n const userRoleIds = (user.UserRoles ?? []).map(r => r.RoleID).filter(Boolean);\n const roleClause = userRoleIds.length > 0\n ? `(Scope='Role' AND RoleID IN (${userRoleIds.map(id => `'${id}'`).join(',')}))`\n : \"(1=0)\";\n\n const filter = `\n EntityID='${entityInfo.ID}' AND (\n (Scope='User' AND UserID='${user.ID}')\n OR ${roleClause}\n OR Scope='Global'\n )\n `.trim();\n\n const rv = RunView.FromMetadataProvider(p);\n const result = await rv.RunView<EntityFormOverrideRow>({\n EntityName: 'MJ: Entity Form Overrides',\n Fields: ['ID', 'EntityID', 'ComponentID', 'Name', 'Description',\n 'Scope', 'UserID', 'RoleID', 'Priority', 'Status'],\n ExtraFilter: filter,\n OrderBy: `CASE Scope WHEN 'User' THEN 1 WHEN 'Role' THEN 2 ELSE 3 END, Priority DESC`,\n ResultType: 'simple',\n BypassCache: true,\n }, user);\n\n if (!result.Success) {\n LogError(`EntityFormOverrideService.ListOverridesForEntity: ${result.ErrorMessage}`);\n return [];\n }\n return result.Results ?? [];\n }\n\n /**\n * Create an `EntityFormOverride` row pointing the just-saved Component\n * at an entity. Honors the dialog's Scope/Role/Priority/Status choices\n * (unlike the Form Builder action which clamps to User scope).\n */\n public async CreateOverride(\n componentID: string,\n result: FormOverrideDialogResult,\n user: UserInfo,\n provider?: IMetadataProvider,\n ): Promise<{ Success: boolean; ID?: string; Error?: string }> {\n const p = provider ?? Metadata.Provider;\n if (!p) {\n return { Success: false, Error: 'No metadata provider available.' };\n }\n const entityInfo = p.EntityByName(result.EntityName);\n if (!entityInfo) {\n return { Success: false, Error: `Entity '${result.EntityName}' is not registered.` };\n }\n\n try {\n const override = await p.GetEntityObject<MJEntityFormOverrideEntity>(\n 'MJ: Entity Form Overrides', user,\n );\n override.NewRecord();\n override.EntityID = entityInfo.ID;\n override.ComponentID = componentID;\n override.Name = result.Name;\n override.Description = result.Description;\n override.Scope = result.Scope;\n // Mutual exclusion enforced by the DB CHECK constraint\n // (see migrations/v5/V202605161430...Interactive_Forms.sql).\n // We mirror it here so the row is well-shaped before the round\n // trip and the CHECK constraint never has to fire.\n override.UserID = result.Scope === 'User' ? user.ID : null;\n override.RoleID = result.Scope === 'Role' ? result.RoleID : null;\n override.Priority = result.Priority;\n override.Status = result.Status;\n\n const saved = await override.Save();\n if (!saved) {\n return {\n Success: false,\n Error: override.LatestResult?.CompleteMessage ?? 'Save returned false with no diagnostic.',\n };\n }\n return { Success: true, ID: override.ID };\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n LogError(`EntityFormOverrideService.CreateOverride: ${message}`);\n return { Success: false, Error: message };\n }\n }\n\n /**\n * Promote a Pending override to Active. Mirrors the server-side\n * `Activate Interactive Form Version` action's intent without round-\n * tripping through the Action layer — for cockpit-internal usage where\n * the user is explicitly clicking \"Make Active\".\n *\n * Atomically flips the target Override to Active AND demotes any sibling\n * Active override at the same scope target to Inactive. Components\n * mirror the override status (Published / Draft / Deprecated).\n */\n public async activateVersion(\n id: string,\n user?: UserInfo,\n provider?: IMetadataProvider,\n ): Promise<{ Success: boolean; Error?: string }> {\n const p = provider ?? Metadata.Provider;\n const u = user ?? p?.CurrentUser;\n if (!p || !u) return { Success: false, Error: 'No provider/user available.' };\n try {\n const target = await p.GetEntityObject<MJEntityFormOverrideEntity>('MJ: Entity Form Overrides', u);\n const loaded = await target.Load(id);\n if (!loaded) return { Success: false, Error: `Override ${id} not found.` };\n\n // Find sibling Actives at the same scope target.\n const rv = RunView.FromMetadataProvider(p);\n const scopeClause = target.Scope === 'User'\n ? `Scope='User' AND UserID='${target.UserID}'`\n : target.Scope === 'Role'\n ? `Scope='Role' AND RoleID='${target.RoleID}'`\n : `Scope='Global' AND UserID IS NULL AND RoleID IS NULL`;\n const priors = await rv.RunView<{ ID: string; ComponentID: string }>({\n EntityName: 'MJ: Entity Form Overrides',\n ExtraFilter: `EntityID='${target.EntityID}' AND ${scopeClause} AND Status='Active' AND ID <> '${target.ID}'`,\n Fields: ['ID', 'ComponentID'],\n ResultType: 'simple',\n }, u);\n\n // Promote target.\n target.Status = 'Active';\n await target.Save();\n const targetComp = await p.GetEntityObject<MJComponentEntity>('MJ: Components', u);\n if (await targetComp.Load(target.ComponentID)) {\n targetComp.Status = 'Published';\n await targetComp.Save();\n }\n // Demote priors.\n for (const prior of priors.Results ?? []) {\n const priorO = await p.GetEntityObject<MJEntityFormOverrideEntity>('MJ: Entity Form Overrides', u);\n if (await priorO.Load(prior.ID)) {\n priorO.Status = 'Inactive';\n await priorO.Save();\n }\n const priorC = await p.GetEntityObject<MJComponentEntity>('MJ: Components', u);\n if (await priorC.Load(prior.ComponentID)) {\n priorC.Status = 'Deprecated';\n await priorC.Save();\n }\n }\n return { Success: true };\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n LogError(`EntityFormOverrideService.activateVersion: ${message}`);\n return { Success: false, Error: message };\n }\n }\n\n /**\n * Re-point an Active override at an older Component row in the same Name\n * lineage. Pure UPDATE on the override; no new rows created. Mirrors the\n * server-side `Revert Interactive Form` action.\n */\n public async revertToComponent(\n activeOverrideID: string,\n targetComponentID: string,\n user?: UserInfo,\n provider?: IMetadataProvider,\n ): Promise<{ Success: boolean; Error?: string }> {\n const p = provider ?? Metadata.Provider;\n const u = user ?? p?.CurrentUser;\n if (!p || !u) return { Success: false, Error: 'No provider/user available.' };\n try {\n const override = await p.GetEntityObject<MJEntityFormOverrideEntity>('MJ: Entity Form Overrides', u);\n if (!await override.Load(activeOverrideID)) {\n return { Success: false, Error: `Override ${activeOverrideID} not found.` };\n }\n const previousComponentID = override.ComponentID;\n override.ComponentID = targetComponentID;\n const saved = await override.Save();\n if (!saved) {\n return { Success: false, Error: override.LatestResult?.CompleteMessage ?? 'Save returned false.' };\n }\n // Flip Component statuses to keep them coherent.\n const newActive = await p.GetEntityObject<MJComponentEntity>('MJ: Components', u);\n if (await newActive.Load(targetComponentID)) {\n newActive.Status = 'Published';\n await newActive.Save();\n }\n const oldActive = await p.GetEntityObject<MJComponentEntity>('MJ: Components', u);\n if (await oldActive.Load(previousComponentID)) {\n oldActive.Status = 'Deprecated';\n await oldActive.Save();\n }\n return { Success: true };\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n LogError(`EntityFormOverrideService.revertToComponent: ${message}`);\n return { Success: false, Error: message };\n }\n }\n\n /**\n * Flip an override's Status to `Inactive`. Preserves the row so it can\n * be re-activated later (vs. deleting outright, which would lose the\n * Component link and require re-authoring).\n */\n public async DeactivateOverride(\n id: string,\n user: UserInfo,\n provider?: IMetadataProvider,\n ): Promise<{ Success: boolean; Error?: string }> {\n const p = provider ?? Metadata.Provider;\n if (!p) return { Success: false, Error: 'No metadata provider available.' };\n\n try {\n const override = await p.GetEntityObject<MJEntityFormOverrideEntity>(\n 'MJ: Entity Form Overrides', user,\n );\n const loaded = await override.Load(id);\n if (!loaded) {\n return { Success: false, Error: `Override ${id} not found.` };\n }\n override.Status = 'Inactive';\n const saved = await override.Save();\n if (!saved) {\n return {\n Success: false,\n Error: override.LatestResult?.CompleteMessage ?? 'Save returned false.',\n };\n }\n return { Success: true };\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n LogError(`EntityFormOverrideService.DeactivateOverride: ${message}`);\n return { Success: false, Error: message };\n }\n }\n}\n"]}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Scans a component source string for `record.<field>` and
3
+ * `record["<field>"]` references and returns the set of bound field names.
4
+ *
5
+ * Uses the React runtime's already-loaded `@babel/standalone` global if
6
+ * available (it's loaded by the Studio preview pane and most pages that
7
+ * mount an interactive component). Falls back to a regex scan when Babel
8
+ * isn't present — slightly less accurate (misses destructured access and
9
+ * `record[someVar]`) but doesn't block the inspector from rendering.
10
+ *
11
+ * Performance: a typical form component is 200-500 LOC; parsing it takes
12
+ * a few ms. Inspector callers should still debounce on keystroke.
13
+ */
14
+ export interface FieldBindingScanResult {
15
+ /** Field names referenced via `record.X` or `record["X"]` patterns. */
16
+ boundFields: Set<string>;
17
+ /** True iff AST parsing succeeded. Regex fallback sets this to false. */
18
+ usedAst: boolean;
19
+ /** Parse error message if AST parsing failed. Useful in dev. */
20
+ parseError?: string;
21
+ }
22
+ /**
23
+ * Scan code for record-field bindings.
24
+ *
25
+ * @param code The full source of a form-role component.
26
+ * @returns The set of field names referenced. Empty set if `code` is falsy.
27
+ */
28
+ export declare function scanFieldBindings(code: string | null | undefined): FieldBindingScanResult;
29
+ //# sourceMappingURL=field-binding-scanner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"field-binding-scanner.d.ts","sourceRoot":"","sources":["../../../src/ComponentStudio/services/field-binding-scanner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,WAAW,sBAAsB;IACnC,uEAAuE;IACvE,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACzB,yEAAyE;IACzE,OAAO,EAAE,OAAO,CAAC;IACjB,gEAAgE;IAChE,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,sBAAsB,CAoBzF"}
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Scans a component source string for `record.<field>` and
3
+ * `record["<field>"]` references and returns the set of bound field names.
4
+ *
5
+ * Uses the React runtime's already-loaded `@babel/standalone` global if
6
+ * available (it's loaded by the Studio preview pane and most pages that
7
+ * mount an interactive component). Falls back to a regex scan when Babel
8
+ * isn't present — slightly less accurate (misses destructured access and
9
+ * `record[someVar]`) but doesn't block the inspector from rendering.
10
+ *
11
+ * Performance: a typical form component is 200-500 LOC; parsing it takes
12
+ * a few ms. Inspector callers should still debounce on keystroke.
13
+ */
14
+ /**
15
+ * Scan code for record-field bindings.
16
+ *
17
+ * @param code The full source of a form-role component.
18
+ * @returns The set of field names referenced. Empty set if `code` is falsy.
19
+ */
20
+ export function scanFieldBindings(code) {
21
+ if (!code || code.trim().length === 0) {
22
+ return { boundFields: new Set(), usedAst: false };
23
+ }
24
+ const babel = getBabelStandalone();
25
+ if (babel) {
26
+ try {
27
+ return scanViaBabel(code, babel);
28
+ }
29
+ catch (err) {
30
+ // Fall through to regex on any parse failure (incomplete JSX,
31
+ // experimental syntax, etc.). The inspector still works; it
32
+ // just shows fewer bindings than the AST would have detected.
33
+ const parseError = err instanceof Error ? err.message : String(err);
34
+ const regexResult = scanViaRegex(code);
35
+ return { ...regexResult, usedAst: false, parseError };
36
+ }
37
+ }
38
+ return scanViaRegex(code);
39
+ }
40
+ /** Walks the Babel AST for MemberExpression / OptionalMemberExpression nodes. */
41
+ function scanViaBabel(code, babel) {
42
+ const b = babel;
43
+ const parser = b.packages?.parser ?? b.parser;
44
+ const traverse = b.packages?.traverse?.default ?? b.packages?.traverse ?? b.traverse;
45
+ if (!parser?.parse || !traverse) {
46
+ // Babel global exists but the sub-packages aren't on the expected
47
+ // shape (older or trimmed builds). Fall back.
48
+ return scanViaRegex(code);
49
+ }
50
+ const ast = parser.parse(code, {
51
+ sourceType: 'module',
52
+ errorRecovery: true,
53
+ plugins: ['jsx'],
54
+ });
55
+ const bound = new Set();
56
+ traverse(ast, {
57
+ // record.FieldName -> captures FieldName
58
+ // record?.FieldName -> same
59
+ MemberExpression(path) { collectRecordRef(path.node, bound); },
60
+ OptionalMemberExpression(path) { collectRecordRef(path.node, bound); },
61
+ });
62
+ return { boundFields: bound, usedAst: true };
63
+ }
64
+ /** Examines one Member/OptionalMember node, adds to `bound` if it's a `record.X` pattern. */
65
+ function collectRecordRef(node, bound) {
66
+ const obj = node.object;
67
+ if (!obj || obj.type !== 'Identifier' || obj.name !== 'record') {
68
+ return;
69
+ }
70
+ const prop = node.property;
71
+ if (!prop)
72
+ return;
73
+ if (!node.computed && prop.type === 'Identifier' && prop.name) {
74
+ bound.add(prop.name);
75
+ return;
76
+ }
77
+ if (node.computed && prop.type === 'StringLiteral' && typeof prop.value === 'string') {
78
+ bound.add(prop.value);
79
+ }
80
+ // Dynamic computed access (record[someVar]) is unknowable statically — skip.
81
+ }
82
+ /** Regex fallback for when Babel isn't available. */
83
+ function scanViaRegex(code) {
84
+ const bound = new Set();
85
+ // Strip block + line comments and string literals first so we don't
86
+ // pull "fields" out of comments or string contents. Done as a single
87
+ // pass — simple replacement is good enough for the regex tier.
88
+ const stripped = code
89
+ .replace(/\/\*[\s\S]*?\*\//g, '')
90
+ .replace(/\/\/[^\n]*/g, '');
91
+ // record.FieldName (and record?.FieldName)
92
+ const dotRe = /\brecord\??\.([A-Za-z_$][A-Za-z0-9_$]*)/g;
93
+ let m;
94
+ while ((m = dotRe.exec(stripped)) !== null) {
95
+ bound.add(m[1]);
96
+ }
97
+ // record["FieldName"] (and record?.["FieldName"])
98
+ const bracketRe = /\brecord\??\.?\[\s*["']([^"']+)["']\s*\]/g;
99
+ while ((m = bracketRe.exec(stripped)) !== null) {
100
+ bound.add(m[1]);
101
+ }
102
+ return { boundFields: bound, usedAst: false };
103
+ }
104
+ /** Pulls Babel-standalone off `window` if it's been loaded by the React runtime. */
105
+ function getBabelStandalone() {
106
+ if (typeof window === 'undefined')
107
+ return undefined;
108
+ return window.Babel;
109
+ }
110
+ //# sourceMappingURL=field-binding-scanner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"field-binding-scanner.js","sourceRoot":"","sources":["../../../src/ComponentStudio/services/field-binding-scanner.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Scans a component source string for `record.<field>` and\n * `record[\"<field>\"]` references and returns the set of bound field names.\n *\n * Uses the React runtime's already-loaded `@babel/standalone` global if\n * available (it's loaded by the Studio preview pane and most pages that\n * mount an interactive component). Falls back to a regex scan when Babel\n * isn't present — slightly less accurate (misses destructured access and\n * `record[someVar]`) but doesn't block the inspector from rendering.\n *\n * Performance: a typical form component is 200-500 LOC; parsing it takes\n * a few ms. Inspector callers should still debounce on keystroke.\n */\n\nexport interface FieldBindingScanResult {\n /** Field names referenced via `record.X` or `record[\"X\"]` patterns. */\n boundFields: Set<string>;\n /** True iff AST parsing succeeded. Regex fallback sets this to false. */\n usedAst: boolean;\n /** Parse error message if AST parsing failed. Useful in dev. */\n parseError?: string;\n}\n\n/**\n * Scan code for record-field bindings.\n *\n * @param code The full source of a form-role component.\n * @returns The set of field names referenced. Empty set if `code` is falsy.\n */\nexport function scanFieldBindings(code: string | null | undefined): FieldBindingScanResult {\n if (!code || code.trim().length === 0) {\n return { boundFields: new Set(), usedAst: false };\n }\n\n const babel = getBabelStandalone();\n if (babel) {\n try {\n return scanViaBabel(code, babel);\n } catch (err) {\n // Fall through to regex on any parse failure (incomplete JSX,\n // experimental syntax, etc.). The inspector still works; it\n // just shows fewer bindings than the AST would have detected.\n const parseError = err instanceof Error ? err.message : String(err);\n const regexResult = scanViaRegex(code);\n return { ...regexResult, usedAst: false, parseError };\n }\n }\n\n return scanViaRegex(code);\n}\n\n/** Walks the Babel AST for MemberExpression / OptionalMemberExpression nodes. */\nfunction scanViaBabel(code: string, babel: unknown): FieldBindingScanResult {\n const b = babel as BabelStandalone;\n\n const parser = b.packages?.parser ?? b.parser;\n const traverse = b.packages?.traverse?.default ?? b.packages?.traverse ?? b.traverse;\n if (!parser?.parse || !traverse) {\n // Babel global exists but the sub-packages aren't on the expected\n // shape (older or trimmed builds). Fall back.\n return scanViaRegex(code);\n }\n\n const ast = parser.parse(code, {\n sourceType: 'module',\n errorRecovery: true,\n plugins: ['jsx'],\n });\n\n const bound = new Set<string>();\n\n traverse(ast, {\n // record.FieldName -> captures FieldName\n // record?.FieldName -> same\n MemberExpression(path: { node: AstNode }) { collectRecordRef(path.node, bound); },\n OptionalMemberExpression(path: { node: AstNode }) { collectRecordRef(path.node, bound); },\n });\n\n return { boundFields: bound, usedAst: true };\n}\n\n/** Examines one Member/OptionalMember node, adds to `bound` if it's a `record.X` pattern. */\nfunction collectRecordRef(node: AstNode, bound: Set<string>): void {\n const obj = node.object;\n if (!obj || obj.type !== 'Identifier' || obj.name !== 'record') {\n return;\n }\n const prop = node.property;\n if (!prop) return;\n\n if (!node.computed && prop.type === 'Identifier' && prop.name) {\n bound.add(prop.name);\n return;\n }\n if (node.computed && prop.type === 'StringLiteral' && typeof prop.value === 'string') {\n bound.add(prop.value);\n }\n // Dynamic computed access (record[someVar]) is unknowable statically — skip.\n}\n\n/** Regex fallback for when Babel isn't available. */\nfunction scanViaRegex(code: string): FieldBindingScanResult {\n const bound = new Set<string>();\n\n // Strip block + line comments and string literals first so we don't\n // pull \"fields\" out of comments or string contents. Done as a single\n // pass — simple replacement is good enough for the regex tier.\n const stripped = code\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, '')\n .replace(/\\/\\/[^\\n]*/g, '');\n\n // record.FieldName (and record?.FieldName)\n const dotRe = /\\brecord\\??\\.([A-Za-z_$][A-Za-z0-9_$]*)/g;\n let m: RegExpExecArray | null;\n while ((m = dotRe.exec(stripped)) !== null) {\n bound.add(m[1]);\n }\n\n // record[\"FieldName\"] (and record?.[\"FieldName\"])\n const bracketRe = /\\brecord\\??\\.?\\[\\s*[\"']([^\"']+)[\"']\\s*\\]/g;\n while ((m = bracketRe.exec(stripped)) !== null) {\n bound.add(m[1]);\n }\n\n return { boundFields: bound, usedAst: false };\n}\n\n/** Pulls Babel-standalone off `window` if it's been loaded by the React runtime. */\nfunction getBabelStandalone(): unknown {\n if (typeof window === 'undefined') return undefined;\n return (window as unknown as { Babel?: unknown }).Babel;\n}\n\ninterface BabelStandalone {\n packages?: {\n parser?: { parse: (code: string, opts: object) => unknown };\n traverse?: { default?: BabelTraverseFn } & BabelTraverseFn;\n };\n parser?: { parse: (code: string, opts: object) => unknown };\n traverse?: BabelTraverseFn;\n}\n\ntype BabelTraverseFn = (ast: unknown, visitor: Record<string, (path: { node: AstNode }) => void>) => void;\n\ninterface AstNode {\n type: string;\n object?: AstNode;\n property?: AstNode;\n name?: string;\n value?: unknown;\n computed?: boolean;\n}\n"]}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Serializable canvas model for Form Studio.
3
+ *
4
+ * This is the source of truth for the visual builder: sections + elements +
5
+ * layout. Code generation derives JSX from it; the round-trip parser tries
6
+ * to reconstruct it from existing Component code on load.
7
+ *
8
+ * The model is plain JSON — easy to diff, easy to ship over the wire to the
9
+ * agent when "Open in Chat" is invoked, easy to round-trip into a
10
+ * ComponentSpec.code string.
11
+ */
12
+ /** A single field/section/element on the canvas. */
13
+ export interface FormCanvasElement {
14
+ /** Stable id for cdk drag-drop tracking; never persisted to JSX. */
15
+ id: string;
16
+ /** What kind of element is this? */
17
+ type: 'field' | 'static-text' | 'spacer' | 'computed';
18
+ /** Required for `type === 'field'` — the curated-schema field name. */
19
+ fieldName?: string;
20
+ /** Display label override; defaults to schema.displayName. */
21
+ label?: string;
22
+ /** Required override; if absent, schema.required wins. */
23
+ required?: boolean;
24
+ /** Helper text rendered under the input. */
25
+ helper?: string;
26
+ /** Grid span within section: 1 = half-width in 2-column, 2 = full-width. */
27
+ span?: 1 | 2;
28
+ /** Text body for `type === 'static-text'`. */
29
+ text?: string;
30
+ /** Expression body for `type === 'computed'`. */
31
+ expression?: string;
32
+ }
33
+ /** A grouping of elements with an optional heading. */
34
+ export interface FormCanvasSection {
35
+ id: string;
36
+ title: string;
37
+ collapsible: boolean;
38
+ columns: 1 | 2;
39
+ elements: FormCanvasElement[];
40
+ }
41
+ /** Top-level canvas state. */
42
+ export interface FormCanvasModel {
43
+ /** Canonical entity name from the curated schema, e.g. "MJ: Users". */
44
+ entityName: string;
45
+ /** Form title (rendered above the sections). */
46
+ title?: string;
47
+ /** Sections in display order. */
48
+ sections: FormCanvasSection[];
49
+ }
50
+ /** Generate a short stable id for canvas elements. Not cryptographic. */
51
+ export declare function generateCanvasId(prefix: string): string;
52
+ /** Build a default, empty section. */
53
+ export declare function buildEmptySection(title?: string): FormCanvasSection;
54
+ /** Build a default empty canvas for an entity. */
55
+ export declare function buildEmptyCanvas(entityName: string, title?: string): FormCanvasModel;
56
+ //# sourceMappingURL=form-canvas-model.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form-canvas-model.d.ts","sourceRoot":"","sources":["../../../src/ComponentStudio/services/form-canvas-model.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,oDAAoD;AACpD,MAAM,WAAW,iBAAiB;IAC9B,oEAAoE;IACpE,EAAE,EAAE,MAAM,CAAC;IACX,oCAAoC;IACpC,IAAI,EAAE,OAAO,GAAG,aAAa,GAAG,QAAQ,GAAG,UAAU,CAAC;IACtD,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8DAA8D;IAC9D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,4CAA4C;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4EAA4E;IAC5E,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IACb,8CAA8C;IAC9C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,uDAAuD;AACvD,MAAM,WAAW,iBAAiB;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC;IACf,QAAQ,EAAE,iBAAiB,EAAE,CAAC;CACjC;AAED,8BAA8B;AAC9B,MAAM,WAAW,eAAe;IAC5B,uEAAuE;IACvE,UAAU,EAAE,MAAM,CAAC;IACnB,gDAAgD;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iCAAiC;IACjC,QAAQ,EAAE,iBAAiB,EAAE,CAAC;CACjC;AAED,yEAAyE;AACzE,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAGvD;AAED,sCAAsC;AACtC,wBAAgB,iBAAiB,CAAC,KAAK,SAAqB,GAAG,iBAAiB,CAQ/E;AAED,kDAAkD;AAClD,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,eAAe,CAMpF"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Serializable canvas model for Form Studio.
3
+ *
4
+ * This is the source of truth for the visual builder: sections + elements +
5
+ * layout. Code generation derives JSX from it; the round-trip parser tries
6
+ * to reconstruct it from existing Component code on load.
7
+ *
8
+ * The model is plain JSON — easy to diff, easy to ship over the wire to the
9
+ * agent when "Open in Chat" is invoked, easy to round-trip into a
10
+ * ComponentSpec.code string.
11
+ */
12
+ /** Generate a short stable id for canvas elements. Not cryptographic. */
13
+ export function generateCanvasId(prefix) {
14
+ const slug = Math.random().toString(36).slice(2, 10);
15
+ return `${prefix}-${slug}`;
16
+ }
17
+ /** Build a default, empty section. */
18
+ export function buildEmptySection(title = 'Untitled Section') {
19
+ return {
20
+ id: generateCanvasId('section'),
21
+ title,
22
+ collapsible: false,
23
+ columns: 2,
24
+ elements: [],
25
+ };
26
+ }
27
+ /** Build a default empty canvas for an entity. */
28
+ export function buildEmptyCanvas(entityName, title) {
29
+ return {
30
+ entityName,
31
+ title: title ?? '',
32
+ sections: [buildEmptySection('Details')],
33
+ };
34
+ }
35
+ //# sourceMappingURL=form-canvas-model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form-canvas-model.js","sourceRoot":"","sources":["../../../src/ComponentStudio/services/form-canvas-model.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AA2CH,yEAAyE;AACzE,MAAM,UAAU,gBAAgB,CAAC,MAAc;IAC3C,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACrD,OAAO,GAAG,MAAM,IAAI,IAAI,EAAE,CAAC;AAC/B,CAAC;AAED,sCAAsC;AACtC,MAAM,UAAU,iBAAiB,CAAC,KAAK,GAAG,kBAAkB;IACxD,OAAO;QACH,EAAE,EAAE,gBAAgB,CAAC,SAAS,CAAC;QAC/B,KAAK;QACL,WAAW,EAAE,KAAK;QAClB,OAAO,EAAE,CAAC;QACV,QAAQ,EAAE,EAAE;KACf,CAAC;AACN,CAAC;AAED,kDAAkD;AAClD,MAAM,UAAU,gBAAgB,CAAC,UAAkB,EAAE,KAAc;IAC/D,OAAO;QACH,UAAU;QACV,KAAK,EAAE,KAAK,IAAI,EAAE;QAClB,QAAQ,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;KAC3C,CAAC;AACN,CAAC","sourcesContent":["/**\n * Serializable canvas model for Form Studio.\n *\n * This is the source of truth for the visual builder: sections + elements +\n * layout. Code generation derives JSX from it; the round-trip parser tries\n * to reconstruct it from existing Component code on load.\n *\n * The model is plain JSON — easy to diff, easy to ship over the wire to the\n * agent when \"Open in Chat\" is invoked, easy to round-trip into a\n * ComponentSpec.code string.\n */\n\n/** A single field/section/element on the canvas. */\nexport interface FormCanvasElement {\n /** Stable id for cdk drag-drop tracking; never persisted to JSX. */\n id: string;\n /** What kind of element is this? */\n type: 'field' | 'static-text' | 'spacer' | 'computed';\n /** Required for `type === 'field'` — the curated-schema field name. */\n fieldName?: string;\n /** Display label override; defaults to schema.displayName. */\n label?: string;\n /** Required override; if absent, schema.required wins. */\n required?: boolean;\n /** Helper text rendered under the input. */\n helper?: string;\n /** Grid span within section: 1 = half-width in 2-column, 2 = full-width. */\n span?: 1 | 2;\n /** Text body for `type === 'static-text'`. */\n text?: string;\n /** Expression body for `type === 'computed'`. */\n expression?: string;\n}\n\n/** A grouping of elements with an optional heading. */\nexport interface FormCanvasSection {\n id: string;\n title: string;\n collapsible: boolean;\n columns: 1 | 2;\n elements: FormCanvasElement[];\n}\n\n/** Top-level canvas state. */\nexport interface FormCanvasModel {\n /** Canonical entity name from the curated schema, e.g. \"MJ: Users\". */\n entityName: string;\n /** Form title (rendered above the sections). */\n title?: string;\n /** Sections in display order. */\n sections: FormCanvasSection[];\n}\n\n/** Generate a short stable id for canvas elements. Not cryptographic. */\nexport function generateCanvasId(prefix: string): string {\n const slug = Math.random().toString(36).slice(2, 10);\n return `${prefix}-${slug}`;\n}\n\n/** Build a default, empty section. */\nexport function buildEmptySection(title = 'Untitled Section'): FormCanvasSection {\n return {\n id: generateCanvasId('section'),\n title,\n collapsible: false,\n columns: 2,\n elements: [],\n };\n}\n\n/** Build a default empty canvas for an entity. */\nexport function buildEmptyCanvas(entityName: string, title?: string): FormCanvasModel {\n return {\n entityName,\n title: title ?? '',\n sections: [buildEmptySection('Details')],\n };\n}\n"]}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Component Studio's view of the fixture FormHostProps builder.
3
+ *
4
+ * The implementation lives in `@memberjunction/interactive-component-types/forms`
5
+ * so it can be shared with the chat artifact viewer (which doesn't depend on
6
+ * the dashboards package). This file just re-exports the shared symbol so
7
+ * existing Component Studio imports keep working without churn.
8
+ */
9
+ export { buildFixtureFormHostProps } from '@memberjunction/interactive-component-types/forms';
10
+ //# sourceMappingURL=form-host-props-fixture.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form-host-props-fixture.d.ts","sourceRoot":"","sources":["../../../src/ComponentStudio/services/form-host-props-fixture.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,yBAAyB,EAAE,MAAM,mDAAmD,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Component Studio's view of the fixture FormHostProps builder.
3
+ *
4
+ * The implementation lives in `@memberjunction/interactive-component-types/forms`
5
+ * so it can be shared with the chat artifact viewer (which doesn't depend on
6
+ * the dashboards package). This file just re-exports the shared symbol so
7
+ * existing Component Studio imports keep working without churn.
8
+ */
9
+ export { buildFixtureFormHostProps } from '@memberjunction/interactive-component-types/forms';
10
+ //# sourceMappingURL=form-host-props-fixture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form-host-props-fixture.js","sourceRoot":"","sources":["../../../src/ComponentStudio/services/form-host-props-fixture.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,yBAAyB,EAAE,MAAM,mDAAmD,CAAC","sourcesContent":["/**\n * Component Studio's view of the fixture FormHostProps builder.\n *\n * The implementation lives in `@memberjunction/interactive-component-types/forms`\n * so it can be shared with the chat artifact viewer (which doesn't depend on\n * the dashboards package). This file just re-exports the shared symbol so\n * existing Component Studio imports keep working without churn.\n */\nexport { buildFixtureFormHostProps } from '@memberjunction/interactive-component-types/forms';\n"]}