@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 @@
1
+ {"version":3,"file":"health-tab.component.js","sourceRoot":"","sources":["../../../../../src/AI/components/autotagging/tabs/health-tab.component.ts","../../../../../src/AI/components/autotagging/tabs/health-tab.component.html"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Classify · Tag Health tab.\n *\n * Self-contained sub-page that surfaces the REAL taxonomy-quality signals the\n * server-side TagHealthJob produces as `MJ: Tag Suggestions` rows with\n * `Reason ∈ {MergeCandidate, LowUsage, WideNode}`. The Suggestions Inbox tab\n * deliberately EXCLUDES these 3 reasons; the Health tab OWNS them.\n *\n * NOTE: the underlying signals (which tags are merge candidates, which are\n * low-usage, which are wide nodes) are computed SERVER-SIDE by the TagHealthJob\n * — this tab does not recompute them. It triages the resulting suggestion rows:\n * grouping them into the 3 signal buckets and applying human decisions\n * (Merge / Deprecate / Review-in-Taxonomy / Dismiss) as client-side entity\n * mutations on the suggestion (and, for Deprecate, on the subject Tag).\n *\n * Data is TRANSACTIONAL and grows over time — loaded via RunView (NOT cached),\n * grouped into the 3 buckets in memory. Loads lazily on first activation.\n */\nimport { Component, ChangeDetectorRef, EventEmitter, Output, inject } from '@angular/core';\nimport { RunView } from '@memberjunction/core';\nimport { UUIDsEqual } from '@memberjunction/global';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { MJNotificationService } from '@memberjunction/ng-notifications';\nimport { MJTagSuggestionEntity, MJTagEntity } from '@memberjunction/core-entities';\nimport { TagEngineBase } from '@memberjunction/tag-engine-base';\n\n/** The three health-signal reasons this tab owns. */\ntype HealthReason = 'MergeCandidate' | 'LowUsage' | 'WideNode';\n\n/** Confidence floor for the \"merge all high-confidence\" bulk action. */\nconst HIGH_CONFIDENCE_THRESHOLD = 0.9;\n\n/** Static descriptor for one of the 3 signal cards. */\ninterface SignalCardMeta {\n Reason: HealthReason;\n Title: string;\n Icon: string;\n /** Semantic status variant driving the card accent color. */\n Variant: 'info' | 'warning' | 'error';\n /** One-line explanation of what the signal means. */\n Explanation: string;\n /** Noun for the headline count (e.g. \"pairs\", \"tags\", \"nodes\"). */\n CountNoun: string;\n}\n\n/** A signal card's live view-model: its meta + the suggestions in its bucket. */\ninterface SignalCard {\n Meta: SignalCardMeta;\n Items: MJTagSuggestionEntity[];\n}\n\n/** Card descriptors in display order (merge → low-usage → wide-node). */\nconst SIGNAL_CARDS: SignalCardMeta[] = [\n {\n Reason: 'MergeCandidate',\n Title: 'Merge candidates',\n Icon: 'fa-solid fa-code-merge',\n Variant: 'info',\n Explanation: 'Near-duplicate tags with high embedding similarity — likely the same concept under two names.',\n CountNoun: 'pairs',\n },\n {\n Reason: 'LowUsage',\n Title: 'Low usage',\n Icon: 'fa-solid fa-arrow-trend-down',\n Variant: 'warning',\n Explanation: 'Tags applied to very few items recently — candidates to deprecate and keep the taxonomy lean.',\n CountNoun: 'tags',\n },\n {\n Reason: 'WideNode',\n Title: 'Wide nodes',\n Icon: 'fa-solid fa-arrows-left-right-to-line',\n Variant: 'error',\n Explanation: 'Tags with too many direct children — likely need splitting into sub-categories.',\n CountNoun: 'nodes',\n },\n];\n\n/** How many example items to surface per card before \"show all\". */\nconst PREVIEW_LIMIT = 5;\n\n@Component({\n standalone: false,\n selector: 'classify-health-tab',\n templateUrl: './health-tab.component.html',\n styleUrls: ['./health-tab.component.css']\n})\nexport class ClassifyHealthTabComponent extends BaseAngularComponent {\n private cdr = inject(ChangeDetectorRef);\n\n public readonly PreviewLimit = PREVIEW_LIMIT;\n public readonly HighConfidenceThreshold = HIGH_CONFIDENCE_THRESHOLD;\n\n // ── Loaded data (NOT cached — transactional) ──\n private allSuggestions: MJTagSuggestionEntity[] = [];\n public Cards: SignalCard[] = [];\n\n public IsLoading = false;\n private hasLoaded = false;\n /** ID of the suggestion currently being acted on (disables its row controls). */\n public ActingID: string | null = null;\n /** True while a bulk action is in flight. */\n public IsBulkActing = false;\n\n /** Emitted after any action so the host can refresh its pending/health badge. */\n @Output() Resolved = new EventEmitter<void>();\n\n /** Emitted with a tag ID so the host can switch to the Taxonomy tab for review. */\n @Output() OpenInTaxonomyRequested = new EventEmitter<string>();\n\n // ════════════════════════════════════════════\n // ACTIVATION + LOAD\n // ════════════════════════════════════════════\n\n /** Lazy-load on first activation (host calls this when the tab becomes active). */\n public async EnsureLoaded(): Promise<void> {\n if (this.hasLoaded) return;\n this.hasLoaded = true;\n await Promise.all([this.loadSuggestions(), this.ensureTagEngine()]);\n }\n\n /** Public refresh — re-pull the health suggestions and rebuild buckets. */\n public async Refresh(): Promise<void> {\n await this.loadSuggestions();\n }\n\n private async ensureTagEngine(): Promise<void> {\n await TagEngineBase.Instance.Config(false, this.ProviderToUse.CurrentUser, this.ProviderToUse);\n }\n\n private async loadSuggestions(): Promise<void> {\n this.IsLoading = true;\n this.cdr.detectChanges();\n\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView<MJTagSuggestionEntity>({\n EntityName: 'MJ: Tag Suggestions',\n ExtraFilter: `Status='Pending' AND Reason IN ('MergeCandidate','LowUsage','WideNode')`,\n OrderBy: 'BestMatchScore DESC',\n ResultType: 'entity_object',\n }, this.ProviderToUse.CurrentUser);\n\n this.allSuggestions = result.Success ? result.Results : [];\n this.buildCards();\n\n this.IsLoading = false;\n this.cdr.detectChanges();\n }\n\n /** Group the loaded suggestions into the 3 signal buckets, preserving card order. */\n private buildCards(): void {\n this.Cards = SIGNAL_CARDS.map(meta => ({\n Meta: meta,\n Items: this.allSuggestions.filter(s => s.Reason === meta.Reason),\n }));\n }\n\n // ════════════════════════════════════════════\n // DISPLAY HELPERS\n // ════════════════════════════════════════════\n\n public FormatScore(score: number | null): string {\n return score == null ? '—' : score.toFixed(2);\n }\n\n /** Count of high-confidence merge candidates eligible for the bulk merge. */\n public HighConfidenceCount(card: SignalCard): number {\n if (card.Meta.Reason !== 'MergeCandidate') return 0;\n return card.Items.filter(s => (s.BestMatchScore ?? 0) >= HIGH_CONFIDENCE_THRESHOLD).length;\n }\n\n /** Whether a given suggestion's row controls should be disabled. */\n public IsRowBusy(suggestion: MJTagSuggestionEntity): boolean {\n return this.IsBulkActing || (this.ActingID != null && UUIDsEqual(this.ActingID, suggestion.ID));\n }\n\n // ════════════════════════════════════════════\n // ACTIONS — entity-level mutations on the client\n // ════════════════════════════════════════════\n //\n // NOTE: the health signals themselves are computed server-side by the\n // TagHealthJob. These handlers triage the resulting suggestion rows by\n // stamping reviewer fields + resolving status (and, for Deprecate, flipping\n // the subject Tag's Status). Full downstream re-pointing of content-item\n // tags onto the resolved tag is handled by the server-side promotion job.\n\n private stampReviewFields(suggestion: MJTagSuggestionEntity): void {\n suggestion.ReviewedByUserID = this.ProviderToUse.CurrentUser.ID;\n suggestion.ReviewedAt = new Date();\n }\n\n /** Merge candidate → Merge: resolve the suggestion onto its best-match tag. */\n public async Merge(suggestion: MJTagSuggestionEntity): Promise<void> {\n if (this.IsRowBusy(suggestion)) return;\n if (!suggestion.BestMatchTagID) {\n MJNotificationService.Instance.CreateSimpleNotification(\n 'No best-match tag to merge into', 'warning', 3000);\n return;\n }\n this.ActingID = suggestion.ID;\n this.cdr.detectChanges();\n\n try {\n const saved = await this.resolveMerge(suggestion);\n if (saved) {\n MJNotificationService.Instance.CreateSimpleNotification(\n `Merged \"${suggestion.ProposedName}\" into \"${suggestion.BestMatchTag ?? 'best match'}\"`, 'success', 3000);\n this.finishAction(suggestion);\n }\n } catch (error) {\n this.notifyError(error);\n } finally {\n this.ActingID = null;\n this.cdr.detectChanges();\n }\n }\n\n /** Bulk: merge every high-confidence (score ≥ 0.9) merge candidate at once. */\n public async MergeAllHighConfidence(card: SignalCard): Promise<void> {\n if (card.Meta.Reason !== 'MergeCandidate' || this.IsBulkActing) return;\n const targets = card.Items.filter(s =>\n (s.BestMatchScore ?? 0) >= HIGH_CONFIDENCE_THRESHOLD && s.BestMatchTagID);\n if (targets.length === 0) return;\n\n this.IsBulkActing = true;\n this.cdr.detectChanges();\n\n let succeeded = 0;\n try {\n for (const suggestion of targets) {\n const saved = await this.resolveMerge(suggestion);\n if (saved) {\n this.allSuggestions = this.allSuggestions.filter(s => !UUIDsEqual(s.ID, suggestion.ID));\n succeeded++;\n }\n }\n this.buildCards();\n MJNotificationService.Instance.CreateSimpleNotification(\n `Merged ${succeeded} high-confidence candidate${succeeded === 1 ? '' : 's'}`, 'success', 3000);\n if (succeeded > 0) this.Resolved.emit();\n } catch (error) {\n this.notifyError(error);\n } finally {\n this.IsBulkActing = false;\n this.cdr.detectChanges();\n }\n }\n\n /** Stamp + resolve a single merge suggestion. Returns Save() success. */\n private async resolveMerge(suggestion: MJTagSuggestionEntity): Promise<boolean> {\n this.stampReviewFields(suggestion);\n suggestion.Status = 'Merged';\n suggestion.ResolvedTagID = suggestion.BestMatchTagID;\n const saved = await suggestion.Save();\n if (!saved) {\n this.notifyFailure('Failed to merge suggestion', suggestion.LatestResult?.CompleteMessage);\n }\n return saved;\n }\n\n /** Low usage → Deprecate: flip the subject Tag to Deprecated, then resolve. */\n public async Deprecate(suggestion: MJTagSuggestionEntity): Promise<void> {\n if (this.IsRowBusy(suggestion)) return;\n this.ActingID = suggestion.ID;\n this.cdr.detectChanges();\n\n try {\n const tag = await this.resolveSubjectTag(suggestion);\n if (!tag) {\n this.notifyFailure('Could not find the tag to deprecate', 'no matching MJ: Tags record');\n return;\n }\n\n tag.Status = 'Deprecated';\n const tagSaved = await tag.Save();\n if (!tagSaved) {\n this.notifyFailure('Failed to deprecate tag', tag.LatestResult?.CompleteMessage);\n return;\n }\n\n this.stampReviewFields(suggestion);\n suggestion.Status = 'Approved';\n suggestion.ResolvedTagID = tag.ID;\n const sugSaved = await suggestion.Save();\n if (!sugSaved) {\n this.notifyFailure('Tag deprecated but failed to resolve suggestion', suggestion.LatestResult?.CompleteMessage);\n return;\n }\n\n MJNotificationService.Instance.CreateSimpleNotification(\n `Deprecated \"${tag.DisplayName || tag.Name}\"`, 'success', 3000);\n this.finishAction(suggestion);\n } catch (error) {\n this.notifyError(error);\n } finally {\n this.ActingID = null;\n this.cdr.detectChanges();\n }\n }\n\n /**\n * Resolve the subject Tag for a low-usage suggestion: prefer the best-match\n * tag (that IS the low-usage tag here), else fall back to the already-resolved\n * tag, else look up by proposed name via the cached TagEngineBase tags.\n */\n private async resolveSubjectTag(suggestion: MJTagSuggestionEntity): Promise<MJTagEntity | null> {\n const tagID = suggestion.BestMatchTagID ?? suggestion.ResolvedTagID ?? this.lookupTagIDByName(suggestion.ProposedName);\n if (!tagID) return null;\n\n const p = this.ProviderToUse;\n const tag = await p.GetEntityObject<MJTagEntity>('MJ: Tags', p.CurrentUser);\n const loaded = await tag.Load(tagID);\n return loaded ? tag : null;\n }\n\n /** Case-insensitive name → tag ID lookup against the cached tag set. */\n private lookupTagIDByName(name: string): string | null {\n const lower = name.trim().toLowerCase();\n const match = TagEngineBase.Instance.Tags.find(t =>\n (t.DisplayName || t.Name).trim().toLowerCase() === lower ||\n t.Name.trim().toLowerCase() === lower);\n return match?.ID ?? null;\n }\n\n /**\n * Wide node → Review in Taxonomy: bubble the tag ID up so the host can switch\n * to the Taxonomy tab. The suggestion stays Pending — review happens there.\n */\n public ReviewInTaxonomy(suggestion: MJTagSuggestionEntity): void {\n const tagID = suggestion.BestMatchTagID ?? suggestion.ResolvedTagID ?? this.lookupTagIDByName(suggestion.ProposedName);\n if (tagID) {\n this.OpenInTaxonomyRequested.emit(tagID);\n } else {\n // No resolvable tag — still let the host open the taxonomy surface.\n this.OpenInTaxonomyRequested.emit('');\n }\n }\n\n /** Dismiss any signal: mark the suggestion Rejected. */\n public async Dismiss(suggestion: MJTagSuggestionEntity): Promise<void> {\n if (this.IsRowBusy(suggestion)) return;\n this.ActingID = suggestion.ID;\n this.cdr.detectChanges();\n\n try {\n this.stampReviewFields(suggestion);\n suggestion.Status = 'Rejected';\n const saved = await suggestion.Save();\n if (!saved) {\n this.notifyFailure('Failed to dismiss suggestion', suggestion.LatestResult?.CompleteMessage);\n return;\n }\n MJNotificationService.Instance.CreateSimpleNotification(\n `Dismissed \"${suggestion.ProposedName}\"`, 'success', 2500);\n this.finishAction(suggestion);\n } catch (error) {\n this.notifyError(error);\n } finally {\n this.ActingID = null;\n this.cdr.detectChanges();\n }\n }\n\n /** Remove a resolved suggestion, rebuild buckets, notify the host. */\n private finishAction(resolved: MJTagSuggestionEntity): void {\n this.allSuggestions = this.allSuggestions.filter(s => !UUIDsEqual(s.ID, resolved.ID));\n this.buildCards();\n this.Resolved.emit();\n this.cdr.detectChanges();\n }\n\n private notifyFailure(prefix: string, detail: string | undefined): void {\n MJNotificationService.Instance.CreateSimpleNotification(`${prefix}: ${detail ?? 'unknown error'}`, 'error', 5000);\n }\n\n private notifyError(error: unknown): void {\n const msg = error instanceof Error ? error.message : String(error);\n MJNotificationService.Instance.CreateSimpleNotification(`Error: ${msg}`, 'error', 5000);\n }\n}\n","<mj-page-header-interior\n Title=\"Tag Health\"\n Subtitle=\"Automated taxonomy-quality signals from the latest classification runs\">\n <div actions>\n <button mjButton variant=\"secondary\" size=\"sm\" (click)=\"Refresh()\" [disabled]=\"IsLoading\">\n @if (IsLoading) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> <span class=\"mj-action-label\">Refreshing…</span>\n } @else {\n <i class=\"fa-solid fa-arrows-rotate\"></i> <span class=\"mj-action-label\">Refresh</span>\n }\n </button>\n </div>\n</mj-page-header-interior>\n\n<mj-page-body-interior [Padding]=\"false\" [Flex]=\"true\">\n <div class=\"at-main-area\">\n @if (IsLoading) {\n <div class=\"at-page-body\">\n <mj-loading text=\"Loading tag-health signals…\"></mj-loading>\n </div>\n } @else {\n <div class=\"ch-grid\">\n @for (card of Cards; track card.Meta.Reason) {\n <div class=\"ch-card\" [class]=\"'ch-' + card.Meta.Variant\">\n\n <!-- Card head: big count + signal title + explanation -->\n <div class=\"ch-top\">\n <div class=\"ch-big\">\n {{ card.Items.length }} <small>{{ card.Meta.CountNoun }}</small>\n </div>\n <h5 class=\"ch-title\">\n <i [class]=\"card.Meta.Icon\"></i> {{ card.Meta.Title }}\n </h5>\n <p class=\"ch-explain\">{{ card.Meta.Explanation }}</p>\n </div>\n\n @if (card.Items.length === 0) {\n <div class=\"ch-empty\">\n <i class=\"fa-solid fa-circle-check\"></i>\n <span>No {{ card.Meta.Title | lowercase }} right now.</span>\n </div>\n } @else {\n <!-- Top examples (capped at PreviewLimit) -->\n <div class=\"ch-list\">\n @for (s of card.Items.slice(0, PreviewLimit); track s.ID) {\n <div class=\"ch-item\" [class.ch-item-busy]=\"IsRowBusy(s)\">\n <div class=\"ch-item-main\">\n <span class=\"ch-item-name\">{{ s.ProposedName }}</span>\n @if (card.Meta.Reason === 'MergeCandidate' && s.BestMatchTag) {\n <span class=\"ch-item-arrow\"><i class=\"fa-solid fa-arrow-right-long\"></i></span>\n <span class=\"ch-item-target\">{{ s.BestMatchTag }}</span>\n }\n </div>\n <div class=\"ch-item-side\">\n <span class=\"ch-score\">{{ FormatScore(s.BestMatchScore) }}</span>\n\n @switch (card.Meta.Reason) {\n @case ('MergeCandidate') {\n <button mjButton variant=\"primary\" size=\"sm\"\n (click)=\"Merge(s)\" [disabled]=\"IsRowBusy(s) || !s.BestMatchTagID\">\n <i class=\"fa-solid fa-code-merge\"></i> Merge\n </button>\n <button mjButton variant=\"secondary\" size=\"sm\"\n (click)=\"Dismiss(s)\" [disabled]=\"IsRowBusy(s)\">\n Dismiss\n </button>\n }\n @case ('LowUsage') {\n <button mjButton variant=\"warning\" size=\"sm\"\n (click)=\"Deprecate(s)\" [disabled]=\"IsRowBusy(s)\">\n <i class=\"fa-solid fa-arrow-trend-down\"></i> Deprecate\n </button>\n <button mjButton variant=\"secondary\" size=\"sm\"\n (click)=\"Dismiss(s)\" [disabled]=\"IsRowBusy(s)\">\n Dismiss\n </button>\n }\n @case ('WideNode') {\n <button mjButton variant=\"primary\" size=\"sm\"\n (click)=\"ReviewInTaxonomy(s)\" [disabled]=\"IsRowBusy(s)\">\n <i class=\"fa-solid fa-sitemap\"></i> Review\n </button>\n <button mjButton variant=\"secondary\" size=\"sm\"\n (click)=\"Dismiss(s)\" [disabled]=\"IsRowBusy(s)\">\n Dismiss\n </button>\n }\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Card footer: overflow hint + bulk action -->\n <div class=\"ch-foot\">\n @if (card.Items.length > PreviewLimit) {\n <span class=\"ch-more\">+{{ card.Items.length - PreviewLimit }} more</span>\n } @else {\n <span class=\"ch-more\"></span>\n }\n\n @if (card.Meta.Reason === 'MergeCandidate' && HighConfidenceCount(card) > 0) {\n <button mjButton variant=\"primary\" size=\"sm\"\n (click)=\"MergeAllHighConfidence(card)\" [disabled]=\"IsBulkActing\">\n @if (IsBulkActing) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Merging…\n } @else {\n <i class=\"fa-solid fa-layer-group\"></i>\n Merge all high-confidence ({{ HighConfidenceCount(card) }})\n }\n </button>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n</mj-page-body-interior>\n"]}
@@ -0,0 +1,40 @@
1
+ import { BaseAngularComponent } from '@memberjunction/ng-base-types';
2
+ import { FilterFieldConfig } from '@memberjunction/ng-ui-components';
3
+ import { RunHistoryRow, RunDetailRow } from '../shared/classify.types';
4
+ import { formatTokenCount } from '../shared/classify.format';
5
+ import * as i0 from "@angular/core";
6
+ export declare class ClassifyHistoryTabComponent extends BaseAngularComponent {
7
+ private cdr;
8
+ /** Shared raw `MJ: Content Process Runs` rows, supplied by the host orchestrator. */
9
+ private _runs;
10
+ set Runs(value: Record<string, unknown>[]);
11
+ get Runs(): Record<string, unknown>[];
12
+ RunHistoryRows: RunHistoryRow[];
13
+ FilteredRunRows: RunHistoryRow[];
14
+ HistorySourceFilter: string;
15
+ HistoryStatusFilter: string;
16
+ HistorySourceOptions: string[];
17
+ SelectedRunID: string | null;
18
+ RunDetailRows: RunDetailRow[];
19
+ IsLoadingRunDetail: boolean;
20
+ readonly FormatTokenCount: typeof formatTokenCount;
21
+ private buildRunHistoryRows;
22
+ private buildHistorySourceOptions;
23
+ FilterRunHistory(): void;
24
+ /**
25
+ * Filter fields for the Run History section, rendered inside an
26
+ * `<mj-filter-popover>` (many values, single-select → popover with dropdown).
27
+ */
28
+ get historyFilterFields(): FilterFieldConfig[];
29
+ get historyFilterValues(): Record<string, unknown>;
30
+ get historyActiveFilterCount(): number;
31
+ onHistoryFilterChange(values: Record<string, unknown>): void;
32
+ onHistoryFilterReset(): void;
33
+ /** Open (or toggle closed) the detail view for a run, loading its per-source detail rows. */
34
+ OpenRunDetail(runID: string): Promise<void>;
35
+ CloseRunDetail(): void;
36
+ private loadRunDetailRows;
37
+ static ɵfac: i0.ɵɵFactoryDeclaration<ClassifyHistoryTabComponent, never>;
38
+ static ɵcmp: i0.ɵɵComponentDeclaration<ClassifyHistoryTabComponent, "classify-history-tab", never, { "Runs": { "alias": "Runs"; "required": false; }; }, {}, never, never, false, never>;
39
+ }
40
+ //# sourceMappingURL=history-tab.component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history-tab.component.d.ts","sourceRoot":"","sources":["../../../../../src/AI/components/autotagging/tabs/history-tab.component.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACvE,OAAO,EAA4D,gBAAgB,EAAuB,MAAM,2BAA2B,CAAC;;AAE5I,qBAMa,2BAA4B,SAAQ,oBAAoB;IACjE,OAAO,CAAC,GAAG,CAA6B;IAExC,qFAAqF;IACrF,OAAO,CAAC,KAAK,CAAiC;IAC9C,IACI,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAKxC;IACD,IAAI,IAAI,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAEpC;IAEM,cAAc,EAAE,aAAa,EAAE,CAAM;IACrC,eAAe,EAAE,aAAa,EAAE,CAAM;IACtC,mBAAmB,SAAM;IACzB,mBAAmB,SAAM;IACzB,oBAAoB,EAAE,MAAM,EAAE,CAAM;IAGpC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAQ;IACpC,aAAa,EAAE,YAAY,EAAE,CAAM;IACnC,kBAAkB,UAAS;IAGlC,SAAgB,gBAAgB,0BAAoB;IAEpD,OAAO,CAAC,mBAAmB;IA4B3B,OAAO,CAAC,yBAAyB;IAS1B,gBAAgB,IAAI,IAAI;IAS/B;;;OAGG;IACH,IAAW,mBAAmB,IAAI,iBAAiB,EAAE,CA0BpD;IAED,IAAW,mBAAmB,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAExD;IAED,IAAW,wBAAwB,IAAI,MAAM,CAE5C;IAEM,qBAAqB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAM5D,oBAAoB,IAAI,IAAI;IAMnC,6FAA6F;IAChF,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBjD,cAAc,IAAI,IAAI;YAOf,iBAAiB;yCAxJtB,2BAA2B;2CAA3B,2BAA2B;CAoKvC"}
@@ -0,0 +1,402 @@
1
+ /**
2
+ * @fileoverview Classify · Run History tab.
3
+ *
4
+ * Self-contained sub-page: owns its header-interior, the run table, filters,
5
+ * and the per-run detail panel. Receives the shared raw run list from the host
6
+ * via `[Runs]` (the host is the data orchestrator); loads per-run detail rows
7
+ * on demand itself. Cross-tab navigation (none today) would bubble via @Output.
8
+ */
9
+ import { Component, ChangeDetectorRef, Input, inject } from '@angular/core';
10
+ import { RunView } from '@memberjunction/core';
11
+ import { BaseAngularComponent } from '@memberjunction/ng-base-types';
12
+ import { formatNumber, formatDate, computeDuration, displayStatus, formatTokenCount, mapRunDetailRecords } from '../shared/classify.format';
13
+ import * as i0 from "@angular/core";
14
+ import * as i1 from "@memberjunction/ng-shared-generic";
15
+ import * as i2 from "@memberjunction/ng-ui-components";
16
+ const _forTrack0 = ($index, $item) => $item.ID;
17
+ const _forTrack1 = ($index, $item) => $item.SourceName;
18
+ function ClassifyHistoryTabComponent_For_28_Conditional_3_Template(rf, ctx) { if (rf & 1) {
19
+ i0.ɵɵelement(0, "i", 14);
20
+ } }
21
+ function ClassifyHistoryTabComponent_For_28_Template(rf, ctx) { if (rf & 1) {
22
+ const _r1 = i0.ɵɵgetCurrentView();
23
+ i0.ɵɵelementStart(0, "tr", 12);
24
+ i0.ɵɵlistener("click", function ClassifyHistoryTabComponent_For_28_Template_tr_click_0_listener() { const row_r2 = i0.ɵɵrestoreView(_r1).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OpenRunDetail(row_r2.ID)); });
25
+ i0.ɵɵelementStart(1, "td")(2, "span", 13);
26
+ i0.ɵɵconditionalCreate(3, ClassifyHistoryTabComponent_For_28_Conditional_3_Template, 1, 0, "i", 14);
27
+ i0.ɵɵtext(4);
28
+ i0.ɵɵelementEnd()();
29
+ i0.ɵɵelementStart(5, "td", 15);
30
+ i0.ɵɵtext(6);
31
+ i0.ɵɵelementEnd();
32
+ i0.ɵɵelementStart(7, "td");
33
+ i0.ɵɵtext(8);
34
+ i0.ɵɵelementEnd();
35
+ i0.ɵɵelementStart(9, "td", 16);
36
+ i0.ɵɵtext(10);
37
+ i0.ɵɵelementEnd();
38
+ i0.ɵɵelementStart(11, "td");
39
+ i0.ɵɵtext(12);
40
+ i0.ɵɵelementEnd();
41
+ i0.ɵɵelementStart(13, "td");
42
+ i0.ɵɵtext(14);
43
+ i0.ɵɵelementEnd();
44
+ i0.ɵɵelementStart(15, "td");
45
+ i0.ɵɵtext(16);
46
+ i0.ɵɵelementEnd()();
47
+ } if (rf & 2) {
48
+ const row_r2 = ctx.$implicit;
49
+ const ctx_r2 = i0.ɵɵnextContext();
50
+ i0.ɵɵclassProp("at-run-row-selected", ctx_r2.SelectedRunID === row_r2.ID);
51
+ i0.ɵɵadvance(2);
52
+ i0.ɵɵclassMap(row_r2.StatusClass);
53
+ i0.ɵɵadvance();
54
+ i0.ɵɵconditional(row_r2.StatusClass === "running" ? 3 : -1);
55
+ i0.ɵɵadvance();
56
+ i0.ɵɵtextInterpolate1(" ", row_r2.Status, " ");
57
+ i0.ɵɵadvance(2);
58
+ i0.ɵɵtextInterpolate(row_r2.SourceName);
59
+ i0.ɵɵadvance(2);
60
+ i0.ɵɵtextInterpolate(row_r2.StartedDisplay);
61
+ i0.ɵɵadvance(2);
62
+ i0.ɵɵtextInterpolate(row_r2.Duration);
63
+ i0.ɵɵadvance(2);
64
+ i0.ɵɵtextInterpolate(row_r2.Items);
65
+ i0.ɵɵadvance(2);
66
+ i0.ɵɵtextInterpolate(row_r2.Tags);
67
+ i0.ɵɵadvance();
68
+ i0.ɵɵclassMap(row_r2.ErrorClass);
69
+ i0.ɵɵadvance();
70
+ i0.ɵɵtextInterpolate(row_r2.Errors);
71
+ } }
72
+ function ClassifyHistoryTabComponent_Conditional_29_Conditional_9_Template(rf, ctx) { if (rf & 1) {
73
+ i0.ɵɵelement(0, "mj-loading", 23);
74
+ } }
75
+ function ClassifyHistoryTabComponent_Conditional_29_Conditional_10_For_25_Template(rf, ctx) { if (rf & 1) {
76
+ i0.ɵɵelementStart(0, "tr")(1, "td", 15);
77
+ i0.ɵɵtext(2);
78
+ i0.ɵɵelementEnd();
79
+ i0.ɵɵelementStart(3, "td");
80
+ i0.ɵɵtext(4);
81
+ i0.ɵɵelementEnd();
82
+ i0.ɵɵelementStart(5, "td")(6, "span", 13);
83
+ i0.ɵɵtext(7);
84
+ i0.ɵɵelementEnd()();
85
+ i0.ɵɵelementStart(8, "td");
86
+ i0.ɵɵtext(9);
87
+ i0.ɵɵelementEnd();
88
+ i0.ɵɵelementStart(10, "td");
89
+ i0.ɵɵtext(11);
90
+ i0.ɵɵelementEnd();
91
+ i0.ɵɵelementStart(12, "td");
92
+ i0.ɵɵtext(13);
93
+ i0.ɵɵelementEnd();
94
+ i0.ɵɵelementStart(14, "td");
95
+ i0.ɵɵtext(15);
96
+ i0.ɵɵelementEnd();
97
+ i0.ɵɵelementStart(16, "td");
98
+ i0.ɵɵtext(17);
99
+ i0.ɵɵelementEnd();
100
+ i0.ɵɵelementStart(18, "td");
101
+ i0.ɵɵtext(19);
102
+ i0.ɵɵelementEnd();
103
+ i0.ɵɵelementStart(20, "td", 16);
104
+ i0.ɵɵtext(21);
105
+ i0.ɵɵelementEnd()();
106
+ } if (rf & 2) {
107
+ const detail_r5 = ctx.$implicit;
108
+ const ctx_r2 = i0.ɵɵnextContext(3);
109
+ i0.ɵɵadvance(2);
110
+ i0.ɵɵtextInterpolate(detail_r5.SourceName);
111
+ i0.ɵɵadvance(2);
112
+ i0.ɵɵtextInterpolate(detail_r5.SourceType);
113
+ i0.ɵɵadvance(2);
114
+ i0.ɵɵclassMap(detail_r5.StatusClass);
115
+ i0.ɵɵadvance();
116
+ i0.ɵɵtextInterpolate(detail_r5.Status);
117
+ i0.ɵɵadvance(2);
118
+ i0.ɵɵtextInterpolate(detail_r5.ItemsProcessed);
119
+ i0.ɵɵadvance(2);
120
+ i0.ɵɵtextInterpolate(detail_r5.ItemsTagged);
121
+ i0.ɵɵadvance(2);
122
+ i0.ɵɵtextInterpolate(detail_r5.ItemsVectorized);
123
+ i0.ɵɵadvance();
124
+ i0.ɵɵclassProp("run-error-text", detail_r5.ErrorCount > 0);
125
+ i0.ɵɵadvance();
126
+ i0.ɵɵtextInterpolate(detail_r5.ErrorCount);
127
+ i0.ɵɵadvance(2);
128
+ i0.ɵɵtextInterpolate(ctx_r2.FormatTokenCount(detail_r5.TotalTokens));
129
+ i0.ɵɵadvance(2);
130
+ i0.ɵɵtextInterpolate(detail_r5.TotalCost > 0 ? "$" + detail_r5.TotalCost.toFixed(4) : "$0.00");
131
+ i0.ɵɵadvance(2);
132
+ i0.ɵɵtextInterpolate(detail_r5.Duration);
133
+ } }
134
+ function ClassifyHistoryTabComponent_Conditional_29_Conditional_10_Template(rf, ctx) { if (rf & 1) {
135
+ i0.ɵɵelementStart(0, "table", 9)(1, "thead")(2, "tr")(3, "th");
136
+ i0.ɵɵtext(4, "Source");
137
+ i0.ɵɵelementEnd();
138
+ i0.ɵɵelementStart(5, "th");
139
+ i0.ɵɵtext(6, "Source Type");
140
+ i0.ɵɵelementEnd();
141
+ i0.ɵɵelementStart(7, "th");
142
+ i0.ɵɵtext(8, "Status");
143
+ i0.ɵɵelementEnd();
144
+ i0.ɵɵelementStart(9, "th");
145
+ i0.ɵɵtext(10, "Items");
146
+ i0.ɵɵelementEnd();
147
+ i0.ɵɵelementStart(11, "th");
148
+ i0.ɵɵtext(12, "Tagged");
149
+ i0.ɵɵelementEnd();
150
+ i0.ɵɵelementStart(13, "th");
151
+ i0.ɵɵtext(14, "Vectorized");
152
+ i0.ɵɵelementEnd();
153
+ i0.ɵɵelementStart(15, "th");
154
+ i0.ɵɵtext(16, "Errors");
155
+ i0.ɵɵelementEnd();
156
+ i0.ɵɵelementStart(17, "th");
157
+ i0.ɵɵtext(18, "Tokens");
158
+ i0.ɵɵelementEnd();
159
+ i0.ɵɵelementStart(19, "th");
160
+ i0.ɵɵtext(20, "Cost");
161
+ i0.ɵɵelementEnd();
162
+ i0.ɵɵelementStart(21, "th");
163
+ i0.ɵɵtext(22, "Duration");
164
+ i0.ɵɵelementEnd()()();
165
+ i0.ɵɵelementStart(23, "tbody");
166
+ i0.ɵɵrepeaterCreate(24, ClassifyHistoryTabComponent_Conditional_29_Conditional_10_For_25_Template, 22, 14, "tr", null, _forTrack1);
167
+ i0.ɵɵelementEnd()();
168
+ } if (rf & 2) {
169
+ const ctx_r2 = i0.ɵɵnextContext(2);
170
+ i0.ɵɵadvance(24);
171
+ i0.ɵɵrepeater(ctx_r2.RunDetailRows);
172
+ } }
173
+ function ClassifyHistoryTabComponent_Conditional_29_Conditional_11_Template(rf, ctx) { if (rf & 1) {
174
+ i0.ɵɵelementStart(0, "div", 24);
175
+ i0.ɵɵelement(1, "i", 25);
176
+ i0.ɵɵelementStart(2, "p");
177
+ i0.ɵɵtext(3, "No per-source detail records found for this run.");
178
+ i0.ɵɵelementEnd()();
179
+ } }
180
+ function ClassifyHistoryTabComponent_Conditional_29_Template(rf, ctx) { if (rf & 1) {
181
+ const _r4 = i0.ɵɵgetCurrentView();
182
+ i0.ɵɵelementStart(0, "div", 11)(1, "div", 17)(2, "span", 18);
183
+ i0.ɵɵelement(3, "i", 19);
184
+ i0.ɵɵtext(4);
185
+ i0.ɵɵelementEnd();
186
+ i0.ɵɵelementStart(5, "button", 20);
187
+ i0.ɵɵlistener("click", function ClassifyHistoryTabComponent_Conditional_29_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.CloseRunDetail()); });
188
+ i0.ɵɵelement(6, "i", 21);
189
+ i0.ɵɵtext(7, " Close ");
190
+ i0.ɵɵelementEnd()();
191
+ i0.ɵɵelementStart(8, "div", 22);
192
+ i0.ɵɵconditionalCreate(9, ClassifyHistoryTabComponent_Conditional_29_Conditional_9_Template, 1, 0, "mj-loading", 23)(10, ClassifyHistoryTabComponent_Conditional_29_Conditional_10_Template, 26, 0, "table", 9)(11, ClassifyHistoryTabComponent_Conditional_29_Conditional_11_Template, 4, 0, "div", 24);
193
+ i0.ɵɵelementEnd()();
194
+ } if (rf & 2) {
195
+ const ctx_r2 = i0.ɵɵnextContext();
196
+ i0.ɵɵadvance(4);
197
+ i0.ɵɵtextInterpolate1(" Run Detail: ", ctx_r2.SelectedRunID.slice(0, 14), "... ");
198
+ i0.ɵɵadvance(5);
199
+ i0.ɵɵconditional(ctx_r2.IsLoadingRunDetail ? 9 : ctx_r2.RunDetailRows.length > 0 ? 10 : 11);
200
+ } }
201
+ export class ClassifyHistoryTabComponent extends BaseAngularComponent {
202
+ cdr = inject(ChangeDetectorRef);
203
+ /** Shared raw `MJ: Content Process Runs` rows, supplied by the host orchestrator. */
204
+ _runs = [];
205
+ set Runs(value) {
206
+ this._runs = value ?? [];
207
+ this.buildRunHistoryRows();
208
+ this.buildHistorySourceOptions();
209
+ this.FilterRunHistory();
210
+ }
211
+ get Runs() {
212
+ return this._runs;
213
+ }
214
+ RunHistoryRows = [];
215
+ FilteredRunRows = [];
216
+ HistorySourceFilter = '';
217
+ HistoryStatusFilter = '';
218
+ HistorySourceOptions = [];
219
+ // Per-run detail panel
220
+ SelectedRunID = null;
221
+ RunDetailRows = [];
222
+ IsLoadingRunDetail = false;
223
+ // Template-facing formatters
224
+ FormatTokenCount = formatTokenCount;
225
+ buildRunHistoryRows() {
226
+ this.RunHistoryRows = this._runs.map(run => {
227
+ const status = run['Status'] ?? 'Unknown';
228
+ const startTime = run['StartTime'];
229
+ const endTime = run['EndTime'];
230
+ const duration = computeDuration(startTime, endTime);
231
+ const processedItems = run['ProcessedItems'];
232
+ const errorCount = run['ErrorCount'];
233
+ const statusLower = status.toLowerCase();
234
+ const isFailed = statusLower === 'error' || statusLower === 'failed';
235
+ const isRunning = statusLower === 'running' || statusLower === 'processing';
236
+ const hasErrors = (errorCount ?? 0) > 0;
237
+ return {
238
+ ID: run['ID'],
239
+ Status: displayStatus(status),
240
+ StatusClass: isFailed ? 'failed' : isRunning ? 'running' : 'complete',
241
+ SourceName: run['Source'] ?? 'Unknown',
242
+ StartedDisplay: startTime ? formatDate(startTime) : '—',
243
+ Duration: duration,
244
+ Items: processedItems != null ? formatNumber(processedItems) : '—',
245
+ Tags: '—',
246
+ Errors: hasErrors ? formatNumber(errorCount) : (isFailed ? status : '0'),
247
+ ErrorClass: isFailed || hasErrors ? 'run-error-text' : ''
248
+ };
249
+ });
250
+ }
251
+ buildHistorySourceOptions() {
252
+ const sources = new Set();
253
+ for (const run of this._runs) {
254
+ const s = run['Source'];
255
+ if (s)
256
+ sources.add(s);
257
+ }
258
+ this.HistorySourceOptions = Array.from(sources).sort();
259
+ }
260
+ FilterRunHistory() {
261
+ this.FilteredRunRows = this.RunHistoryRows.filter(row => {
262
+ if (this.HistorySourceFilter && row.SourceName !== this.HistorySourceFilter)
263
+ return false;
264
+ if (this.HistoryStatusFilter && row.StatusClass !== this.HistoryStatusFilter)
265
+ return false;
266
+ return true;
267
+ });
268
+ this.cdr.detectChanges();
269
+ }
270
+ /**
271
+ * Filter fields for the Run History section, rendered inside an
272
+ * `<mj-filter-popover>` (many values, single-select → popover with dropdown).
273
+ */
274
+ get historyFilterFields() {
275
+ return [
276
+ {
277
+ key: 'source',
278
+ type: 'dropdown',
279
+ label: 'Source',
280
+ placeholder: 'All Sources',
281
+ filterable: this.HistorySourceOptions.length > 10,
282
+ options: [
283
+ { text: 'All Sources', value: '' },
284
+ ...this.HistorySourceOptions.map(s => ({ text: s, value: s }))
285
+ ]
286
+ },
287
+ {
288
+ key: 'status',
289
+ type: 'dropdown',
290
+ label: 'Status',
291
+ placeholder: 'All Status',
292
+ options: [
293
+ { text: 'All Status', value: '' },
294
+ { text: 'Complete', value: 'complete' },
295
+ { text: 'Failed', value: 'failed' },
296
+ { text: 'Running', value: 'running' }
297
+ ]
298
+ }
299
+ ];
300
+ }
301
+ get historyFilterValues() {
302
+ return { source: this.HistorySourceFilter, status: this.HistoryStatusFilter };
303
+ }
304
+ get historyActiveFilterCount() {
305
+ return (this.HistorySourceFilter ? 1 : 0) + (this.HistoryStatusFilter ? 1 : 0);
306
+ }
307
+ onHistoryFilterChange(values) {
308
+ this.HistorySourceFilter = values['source'] ?? '';
309
+ this.HistoryStatusFilter = values['status'] ?? '';
310
+ this.FilterRunHistory();
311
+ }
312
+ onHistoryFilterReset() {
313
+ this.HistorySourceFilter = '';
314
+ this.HistoryStatusFilter = '';
315
+ this.FilterRunHistory();
316
+ }
317
+ /** Open (or toggle closed) the detail view for a run, loading its per-source detail rows. */
318
+ async OpenRunDetail(runID) {
319
+ if (this.SelectedRunID === runID) {
320
+ this.CloseRunDetail();
321
+ return;
322
+ }
323
+ this.SelectedRunID = runID;
324
+ this.IsLoadingRunDetail = true;
325
+ this.RunDetailRows = [];
326
+ this.cdr.detectChanges();
327
+ await this.loadRunDetailRows(runID);
328
+ this.IsLoadingRunDetail = false;
329
+ this.cdr.detectChanges();
330
+ }
331
+ CloseRunDetail() {
332
+ this.SelectedRunID = null;
333
+ this.RunDetailRows = [];
334
+ this.IsLoadingRunDetail = false;
335
+ this.cdr.detectChanges();
336
+ }
337
+ async loadRunDetailRows(runID) {
338
+ const rv = RunView.FromMetadataProvider(this.ProviderToUse);
339
+ const result = await rv.RunView({
340
+ EntityName: 'MJ: Content Process Run Details',
341
+ ExtraFilter: `ContentProcessRunID='${runID}'`,
342
+ OrderBy: 'ContentSource',
343
+ ResultType: 'simple',
344
+ });
345
+ if (result.Success) {
346
+ this.RunDetailRows = mapRunDetailRecords(result.Results);
347
+ }
348
+ }
349
+ static ɵfac = /*@__PURE__*/ (() => { let ɵClassifyHistoryTabComponent_BaseFactory; return function ClassifyHistoryTabComponent_Factory(__ngFactoryType__) { return (ɵClassifyHistoryTabComponent_BaseFactory || (ɵClassifyHistoryTabComponent_BaseFactory = i0.ɵɵgetInheritedFactory(ClassifyHistoryTabComponent)))(__ngFactoryType__ || ClassifyHistoryTabComponent); }; })();
350
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ClassifyHistoryTabComponent, selectors: [["classify-history-tab"]], inputs: { Runs: "Runs" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 30, vars: 7, consts: [["Title", "Run History", "Subtitle", "Pipeline execution history and per-source run detail"], ["toolbar", ""], [3, "ClearAllRequested", "ActiveCount", "ShowClearAll"], [3, "ValuesChange", "Reset", "Fields", "Values"], [3, "Padding", "Flex"], [1, "at-main-area"], [1, "at-page-body"], [1, "at-card"], [1, "at-card-body", 2, "max-height", "600px", "overflow-y", "auto"], [1, "at-run-table"], [1, "at-run-row-clickable", 3, "at-run-row-selected"], [1, "at-card", 2, "margin-top", "12px"], [1, "at-run-row-clickable", 3, "click"], [1, "at-run-status-badge"], [1, "fa-solid", "fa-spinner", "fa-spin", 2, "font-size", "0.55rem"], [1, "at-run-source-name"], [1, "at-run-duration"], [1, "at-card-header"], [1, "at-card-title"], [1, "fa-solid", "fa-magnifying-glass-chart"], [1, "at-action-btn", "at-secondary-btn", 2, "font-size", "11px", "padding", "3px 8px", 3, "click"], [1, "fa-solid", "fa-times"], [1, "at-card-body"], ["text", "Loading run details...", "size", "small"], [1, "at-empty-state"], [1, "fa-solid", "fa-info-circle"]], template: function ClassifyHistoryTabComponent_Template(rf, ctx) { if (rf & 1) {
351
+ i0.ɵɵelementStart(0, "mj-page-header-interior", 0)(1, "div", 1)(2, "mj-filter-popover", 2);
352
+ i0.ɵɵlistener("ClearAllRequested", function ClassifyHistoryTabComponent_Template_mj_filter_popover_ClearAllRequested_2_listener() { return ctx.onHistoryFilterReset(); });
353
+ i0.ɵɵelementStart(3, "mj-filter-panel", 3);
354
+ i0.ɵɵlistener("ValuesChange", function ClassifyHistoryTabComponent_Template_mj_filter_panel_ValuesChange_3_listener($event) { return ctx.onHistoryFilterChange($event); })("Reset", function ClassifyHistoryTabComponent_Template_mj_filter_panel_Reset_3_listener() { return ctx.onHistoryFilterReset(); });
355
+ i0.ɵɵelementEnd()()()();
356
+ i0.ɵɵelementStart(4, "mj-page-body-interior", 4)(5, "div", 5)(6, "div", 6)(7, "div", 7)(8, "div", 8)(9, "table", 9)(10, "thead")(11, "tr")(12, "th");
357
+ i0.ɵɵtext(13, "Status");
358
+ i0.ɵɵelementEnd();
359
+ i0.ɵɵelementStart(14, "th");
360
+ i0.ɵɵtext(15, "Source");
361
+ i0.ɵɵelementEnd();
362
+ i0.ɵɵelementStart(16, "th");
363
+ i0.ɵɵtext(17, "Started");
364
+ i0.ɵɵelementEnd();
365
+ i0.ɵɵelementStart(18, "th");
366
+ i0.ɵɵtext(19, "Duration");
367
+ i0.ɵɵelementEnd();
368
+ i0.ɵɵelementStart(20, "th");
369
+ i0.ɵɵtext(21, "Items");
370
+ i0.ɵɵelementEnd();
371
+ i0.ɵɵelementStart(22, "th");
372
+ i0.ɵɵtext(23, "Tags");
373
+ i0.ɵɵelementEnd();
374
+ i0.ɵɵelementStart(24, "th");
375
+ i0.ɵɵtext(25, "Errors");
376
+ i0.ɵɵelementEnd()()();
377
+ i0.ɵɵelementStart(26, "tbody");
378
+ i0.ɵɵrepeaterCreate(27, ClassifyHistoryTabComponent_For_28_Template, 17, 14, "tr", 10, _forTrack0);
379
+ i0.ɵɵelementEnd()()()();
380
+ i0.ɵɵconditionalCreate(29, ClassifyHistoryTabComponent_Conditional_29_Template, 12, 2, "div", 11);
381
+ i0.ɵɵelementEnd()()();
382
+ } if (rf & 2) {
383
+ i0.ɵɵadvance(2);
384
+ i0.ɵɵproperty("ActiveCount", ctx.historyActiveFilterCount)("ShowClearAll", ctx.historyActiveFilterCount > 0);
385
+ i0.ɵɵadvance();
386
+ i0.ɵɵproperty("Fields", ctx.historyFilterFields)("Values", ctx.historyFilterValues);
387
+ i0.ɵɵadvance();
388
+ i0.ɵɵproperty("Padding", false)("Flex", true);
389
+ i0.ɵɵadvance(23);
390
+ i0.ɵɵrepeater(ctx.FilteredRunRows);
391
+ i0.ɵɵadvance(2);
392
+ i0.ɵɵconditional(ctx.SelectedRunID ? 29 : -1);
393
+ } }, dependencies: [i1.LoadingComponent, i2.MJPageHeaderInteriorComponent, i2.MJPageBodyInteriorComponent, i2.MJFilterPopoverComponent, i2.MJFilterPanelComponent], encapsulation: 2 });
394
+ }
395
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ClassifyHistoryTabComponent, [{
396
+ type: Component,
397
+ args: [{ standalone: false, selector: 'classify-history-tab', template: "<mj-page-header-interior\n Title=\"Run History\"\n Subtitle=\"Pipeline execution history and per-source run detail\">\n <div toolbar>\n <mj-filter-popover\n [ActiveCount]=\"historyActiveFilterCount\"\n [ShowClearAll]=\"historyActiveFilterCount > 0\"\n (ClearAllRequested)=\"onHistoryFilterReset()\">\n <mj-filter-panel\n [Fields]=\"historyFilterFields\"\n [Values]=\"historyFilterValues\"\n (ValuesChange)=\"onHistoryFilterChange($event)\"\n (Reset)=\"onHistoryFilterReset()\">\n </mj-filter-panel>\n </mj-filter-popover>\n </div>\n</mj-page-header-interior>\n\n<mj-page-body-interior [Padding]=\"false\" [Flex]=\"true\">\n <div class=\"at-main-area\">\n <div class=\"at-page-body\">\n <div class=\"at-card\">\n <div class=\"at-card-body\" style=\"max-height: 600px; overflow-y: auto;\">\n <table class=\"at-run-table\">\n <thead>\n <tr>\n <th>Status</th>\n <th>Source</th>\n <th>Started</th>\n <th>Duration</th>\n <th>Items</th>\n <th>Tags</th>\n <th>Errors</th>\n </tr>\n </thead>\n <tbody>\n @for (row of FilteredRunRows; track row.ID) {\n <tr class=\"at-run-row-clickable\"\n [class.at-run-row-selected]=\"SelectedRunID === row.ID\"\n (click)=\"OpenRunDetail(row.ID)\">\n <td>\n <span class=\"at-run-status-badge\" [class]=\"row.StatusClass\">\n @if (row.StatusClass === 'running') {\n <i class=\"fa-solid fa-spinner fa-spin\" style=\"font-size: 0.55rem\"></i>\n }\n {{ row.Status }}\n </span>\n </td>\n <td class=\"at-run-source-name\">{{ row.SourceName }}</td>\n <td>{{ row.StartedDisplay }}</td>\n <td class=\"at-run-duration\">{{ row.Duration }}</td>\n <td>{{ row.Items }}</td>\n <td>{{ row.Tags }}</td>\n <td [class]=\"row.ErrorClass\">{{ row.Errors }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </div>\n\n <!-- Per-run detail panel -->\n @if (SelectedRunID) {\n <div class=\"at-card\" style=\"margin-top: 12px;\">\n <div class=\"at-card-header\">\n <span class=\"at-card-title\">\n <i class=\"fa-solid fa-magnifying-glass-chart\"></i>\n Run Detail: {{ SelectedRunID.slice(0, 14) }}...\n </span>\n <button class=\"at-action-btn at-secondary-btn\" style=\"font-size: 11px; padding: 3px 8px;\" (click)=\"CloseRunDetail()\">\n <i class=\"fa-solid fa-times\"></i> Close\n </button>\n </div>\n <div class=\"at-card-body\">\n @if (IsLoadingRunDetail) {\n <mj-loading text=\"Loading run details...\" size=\"small\"></mj-loading>\n } @else if (RunDetailRows.length > 0) {\n <table class=\"at-run-table\">\n <thead>\n <tr>\n <th>Source</th>\n <th>Source Type</th>\n <th>Status</th>\n <th>Items</th>\n <th>Tagged</th>\n <th>Vectorized</th>\n <th>Errors</th>\n <th>Tokens</th>\n <th>Cost</th>\n <th>Duration</th>\n </tr>\n </thead>\n <tbody>\n @for (detail of RunDetailRows; track detail.SourceName) {\n <tr>\n <td class=\"at-run-source-name\">{{ detail.SourceName }}</td>\n <td>{{ detail.SourceType }}</td>\n <td>\n <span class=\"at-run-status-badge\" [class]=\"detail.StatusClass\">{{ detail.Status }}</span>\n </td>\n <td>{{ detail.ItemsProcessed }}</td>\n <td>{{ detail.ItemsTagged }}</td>\n <td>{{ detail.ItemsVectorized }}</td>\n <td [class.run-error-text]=\"detail.ErrorCount > 0\">{{ detail.ErrorCount }}</td>\n <td>{{ FormatTokenCount(detail.TotalTokens) }}</td>\n <td>{{ detail.TotalCost > 0 ? '$' + detail.TotalCost.toFixed(4) : '$0.00' }}</td>\n <td class=\"at-run-duration\">{{ detail.Duration }}</td>\n </tr>\n }\n </tbody>\n </table>\n } @else {\n <div class=\"at-empty-state\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <p>No per-source detail records found for this run.</p>\n </div>\n }\n </div>\n </div>\n }\n </div>\n </div>\n</mj-page-body-interior>\n", styles: ["/*\n * Run History tab styles.\n *\n * The host (AutotaggingPipelineResourceComponent) uses ViewEncapsulation.None,\n * so its `.at-*` rules are global and already style this tab's markup while it\n * renders inside the host shell. Tab-specific rules live here as the shared CSS\n * is partitioned during the host-slim step.\n */\n"] }]
398
+ }], null, { Runs: [{
399
+ type: Input
400
+ }] }); })();
401
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ClassifyHistoryTabComponent, { className: "ClassifyHistoryTabComponent", filePath: "src/AI/components/autotagging/tabs/history-tab.component.ts", lineNumber: 22 }); })();
402
+ //# sourceMappingURL=history-tab.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history-tab.component.js","sourceRoot":"","sources":["../../../../../src/AI/components/autotagging/tabs/history-tab.component.ts","../../../../../src/AI/components/autotagging/tabs/history-tab.component.html"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Classify · Run History tab.\n *\n * Self-contained sub-page: owns its header-interior, the run table, filters,\n * and the per-run detail panel. Receives the shared raw run list from the host\n * via `[Runs]` (the host is the data orchestrator); loads per-run detail rows\n * on demand itself. Cross-tab navigation (none today) would bubble via @Output.\n */\nimport { Component, ChangeDetectorRef, Input, inject } from '@angular/core';\nimport { RunView } from '@memberjunction/core';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { FilterFieldConfig } from '@memberjunction/ng-ui-components';\nimport { RunHistoryRow, RunDetailRow } from '../shared/classify.types';\nimport { formatNumber, formatDate, computeDuration, displayStatus, formatTokenCount, mapRunDetailRecords } from '../shared/classify.format';\n\n@Component({\n standalone: false,\n selector: 'classify-history-tab',\n templateUrl: './history-tab.component.html',\n styleUrls: ['./history-tab.component.css']\n})\nexport class ClassifyHistoryTabComponent extends BaseAngularComponent {\n private cdr = inject(ChangeDetectorRef);\n\n /** Shared raw `MJ: Content Process Runs` rows, supplied by the host orchestrator. */\n private _runs: Record<string, unknown>[] = [];\n @Input()\n set Runs(value: Record<string, unknown>[]) {\n this._runs = value ?? [];\n this.buildRunHistoryRows();\n this.buildHistorySourceOptions();\n this.FilterRunHistory();\n }\n get Runs(): Record<string, unknown>[] {\n return this._runs;\n }\n\n public RunHistoryRows: RunHistoryRow[] = [];\n public FilteredRunRows: RunHistoryRow[] = [];\n public HistorySourceFilter = '';\n public HistoryStatusFilter = '';\n public HistorySourceOptions: string[] = [];\n\n // Per-run detail panel\n public SelectedRunID: string | null = null;\n public RunDetailRows: RunDetailRow[] = [];\n public IsLoadingRunDetail = false;\n\n // Template-facing formatters\n public readonly FormatTokenCount = formatTokenCount;\n\n private buildRunHistoryRows(): void {\n this.RunHistoryRows = this._runs.map(run => {\n const status = (run['Status'] as string) ?? 'Unknown';\n const startTime = run['StartTime'] as string | null;\n const endTime = run['EndTime'] as string | null;\n const duration = computeDuration(startTime, endTime);\n const processedItems = run['ProcessedItems'] as number | null;\n const errorCount = run['ErrorCount'] as number | null;\n const statusLower = status.toLowerCase();\n const isFailed = statusLower === 'error' || statusLower === 'failed';\n const isRunning = statusLower === 'running' || statusLower === 'processing';\n const hasErrors = (errorCount ?? 0) > 0;\n\n return {\n ID: run['ID'] as string,\n Status: displayStatus(status),\n StatusClass: isFailed ? 'failed' : isRunning ? 'running' : 'complete',\n SourceName: (run['Source'] as string) ?? 'Unknown',\n StartedDisplay: startTime ? formatDate(startTime) : '—',\n Duration: duration,\n Items: processedItems != null ? formatNumber(processedItems) : '—',\n Tags: '—',\n Errors: hasErrors ? formatNumber(errorCount!) : (isFailed ? status : '0'),\n ErrorClass: isFailed || hasErrors ? 'run-error-text' : ''\n };\n });\n }\n\n private buildHistorySourceOptions(): void {\n const sources = new Set<string>();\n for (const run of this._runs) {\n const s = run['Source'] as string;\n if (s) sources.add(s);\n }\n this.HistorySourceOptions = Array.from(sources).sort();\n }\n\n public FilterRunHistory(): void {\n this.FilteredRunRows = this.RunHistoryRows.filter(row => {\n if (this.HistorySourceFilter && row.SourceName !== this.HistorySourceFilter) return false;\n if (this.HistoryStatusFilter && row.StatusClass !== this.HistoryStatusFilter) return false;\n return true;\n });\n this.cdr.detectChanges();\n }\n\n /**\n * Filter fields for the Run History section, rendered inside an\n * `<mj-filter-popover>` (many values, single-select → popover with dropdown).\n */\n public get historyFilterFields(): FilterFieldConfig[] {\n return [\n {\n key: 'source',\n type: 'dropdown',\n label: 'Source',\n placeholder: 'All Sources',\n filterable: this.HistorySourceOptions.length > 10,\n options: [\n { text: 'All Sources', value: '' },\n ...this.HistorySourceOptions.map(s => ({ text: s, value: s }))\n ]\n },\n {\n key: 'status',\n type: 'dropdown',\n label: 'Status',\n placeholder: 'All Status',\n options: [\n { text: 'All Status', value: '' },\n { text: 'Complete', value: 'complete' },\n { text: 'Failed', value: 'failed' },\n { text: 'Running', value: 'running' }\n ]\n }\n ];\n }\n\n public get historyFilterValues(): Record<string, unknown> {\n return { source: this.HistorySourceFilter, status: this.HistoryStatusFilter };\n }\n\n public get historyActiveFilterCount(): number {\n return (this.HistorySourceFilter ? 1 : 0) + (this.HistoryStatusFilter ? 1 : 0);\n }\n\n public onHistoryFilterChange(values: Record<string, unknown>): void {\n this.HistorySourceFilter = (values['source'] as string) ?? '';\n this.HistoryStatusFilter = (values['status'] as string) ?? '';\n this.FilterRunHistory();\n }\n\n public onHistoryFilterReset(): void {\n this.HistorySourceFilter = '';\n this.HistoryStatusFilter = '';\n this.FilterRunHistory();\n }\n\n /** Open (or toggle closed) the detail view for a run, loading its per-source detail rows. */\n public async OpenRunDetail(runID: string): Promise<void> {\n if (this.SelectedRunID === runID) {\n this.CloseRunDetail();\n return;\n }\n this.SelectedRunID = runID;\n this.IsLoadingRunDetail = true;\n this.RunDetailRows = [];\n this.cdr.detectChanges();\n\n await this.loadRunDetailRows(runID);\n\n this.IsLoadingRunDetail = false;\n this.cdr.detectChanges();\n }\n\n public CloseRunDetail(): void {\n this.SelectedRunID = null;\n this.RunDetailRows = [];\n this.IsLoadingRunDetail = false;\n this.cdr.detectChanges();\n }\n\n private async loadRunDetailRows(runID: string): Promise<void> {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView({\n EntityName: 'MJ: Content Process Run Details',\n ExtraFilter: `ContentProcessRunID='${runID}'`,\n OrderBy: 'ContentSource',\n ResultType: 'simple',\n });\n if (result.Success) {\n this.RunDetailRows = mapRunDetailRecords(result.Results);\n }\n }\n}\n","<mj-page-header-interior\n Title=\"Run History\"\n Subtitle=\"Pipeline execution history and per-source run detail\">\n <div toolbar>\n <mj-filter-popover\n [ActiveCount]=\"historyActiveFilterCount\"\n [ShowClearAll]=\"historyActiveFilterCount > 0\"\n (ClearAllRequested)=\"onHistoryFilterReset()\">\n <mj-filter-panel\n [Fields]=\"historyFilterFields\"\n [Values]=\"historyFilterValues\"\n (ValuesChange)=\"onHistoryFilterChange($event)\"\n (Reset)=\"onHistoryFilterReset()\">\n </mj-filter-panel>\n </mj-filter-popover>\n </div>\n</mj-page-header-interior>\n\n<mj-page-body-interior [Padding]=\"false\" [Flex]=\"true\">\n <div class=\"at-main-area\">\n <div class=\"at-page-body\">\n <div class=\"at-card\">\n <div class=\"at-card-body\" style=\"max-height: 600px; overflow-y: auto;\">\n <table class=\"at-run-table\">\n <thead>\n <tr>\n <th>Status</th>\n <th>Source</th>\n <th>Started</th>\n <th>Duration</th>\n <th>Items</th>\n <th>Tags</th>\n <th>Errors</th>\n </tr>\n </thead>\n <tbody>\n @for (row of FilteredRunRows; track row.ID) {\n <tr class=\"at-run-row-clickable\"\n [class.at-run-row-selected]=\"SelectedRunID === row.ID\"\n (click)=\"OpenRunDetail(row.ID)\">\n <td>\n <span class=\"at-run-status-badge\" [class]=\"row.StatusClass\">\n @if (row.StatusClass === 'running') {\n <i class=\"fa-solid fa-spinner fa-spin\" style=\"font-size: 0.55rem\"></i>\n }\n {{ row.Status }}\n </span>\n </td>\n <td class=\"at-run-source-name\">{{ row.SourceName }}</td>\n <td>{{ row.StartedDisplay }}</td>\n <td class=\"at-run-duration\">{{ row.Duration }}</td>\n <td>{{ row.Items }}</td>\n <td>{{ row.Tags }}</td>\n <td [class]=\"row.ErrorClass\">{{ row.Errors }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </div>\n\n <!-- Per-run detail panel -->\n @if (SelectedRunID) {\n <div class=\"at-card\" style=\"margin-top: 12px;\">\n <div class=\"at-card-header\">\n <span class=\"at-card-title\">\n <i class=\"fa-solid fa-magnifying-glass-chart\"></i>\n Run Detail: {{ SelectedRunID.slice(0, 14) }}...\n </span>\n <button class=\"at-action-btn at-secondary-btn\" style=\"font-size: 11px; padding: 3px 8px;\" (click)=\"CloseRunDetail()\">\n <i class=\"fa-solid fa-times\"></i> Close\n </button>\n </div>\n <div class=\"at-card-body\">\n @if (IsLoadingRunDetail) {\n <mj-loading text=\"Loading run details...\" size=\"small\"></mj-loading>\n } @else if (RunDetailRows.length > 0) {\n <table class=\"at-run-table\">\n <thead>\n <tr>\n <th>Source</th>\n <th>Source Type</th>\n <th>Status</th>\n <th>Items</th>\n <th>Tagged</th>\n <th>Vectorized</th>\n <th>Errors</th>\n <th>Tokens</th>\n <th>Cost</th>\n <th>Duration</th>\n </tr>\n </thead>\n <tbody>\n @for (detail of RunDetailRows; track detail.SourceName) {\n <tr>\n <td class=\"at-run-source-name\">{{ detail.SourceName }}</td>\n <td>{{ detail.SourceType }}</td>\n <td>\n <span class=\"at-run-status-badge\" [class]=\"detail.StatusClass\">{{ detail.Status }}</span>\n </td>\n <td>{{ detail.ItemsProcessed }}</td>\n <td>{{ detail.ItemsTagged }}</td>\n <td>{{ detail.ItemsVectorized }}</td>\n <td [class.run-error-text]=\"detail.ErrorCount > 0\">{{ detail.ErrorCount }}</td>\n <td>{{ FormatTokenCount(detail.TotalTokens) }}</td>\n <td>{{ detail.TotalCost > 0 ? '$' + detail.TotalCost.toFixed(4) : '$0.00' }}</td>\n <td class=\"at-run-duration\">{{ detail.Duration }}</td>\n </tr>\n }\n </tbody>\n </table>\n } @else {\n <div class=\"at-empty-state\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <p>No per-source detail records found for this run.</p>\n </div>\n }\n </div>\n </div>\n }\n </div>\n </div>\n</mj-page-body-interior>\n"]}