@memberjunction/ng-dashboards 5.38.0 → 5.40.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 (321) hide show
  1. package/README.md +14 -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 +217 -860
  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 +1717 -7802
  29. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js.map +1 -1
  30. package/dist/AI/components/autotagging/components/classify-item-drilldown.component.d.ts +56 -0
  31. package/dist/AI/components/autotagging/components/classify-item-drilldown.component.d.ts.map +1 -0
  32. package/dist/AI/components/autotagging/components/classify-item-drilldown.component.js +423 -0
  33. package/dist/AI/components/autotagging/components/classify-item-drilldown.component.js.map +1 -0
  34. package/dist/AI/components/autotagging/components/classify-item-grid.component.d.ts +70 -0
  35. package/dist/AI/components/autotagging/components/classify-item-grid.component.d.ts.map +1 -0
  36. package/dist/AI/components/autotagging/components/classify-item-grid.component.js +308 -0
  37. package/dist/AI/components/autotagging/components/classify-item-grid.component.js.map +1 -0
  38. package/dist/AI/components/autotagging/components/classify-org-context-editor.component.d.ts +29 -0
  39. package/dist/AI/components/autotagging/components/classify-org-context-editor.component.d.ts.map +1 -0
  40. package/dist/AI/components/autotagging/components/classify-org-context-editor.component.js +186 -0
  41. package/dist/AI/components/autotagging/components/classify-org-context-editor.component.js.map +1 -0
  42. package/dist/AI/components/autotagging/components/classify-overview-analytics.component.d.ts +69 -0
  43. package/dist/AI/components/autotagging/components/classify-overview-analytics.component.d.ts.map +1 -0
  44. package/dist/AI/components/autotagging/components/classify-overview-analytics.component.js +278 -0
  45. package/dist/AI/components/autotagging/components/classify-overview-analytics.component.js.map +1 -0
  46. package/dist/AI/components/autotagging/components/classify-seed-taxonomy.component.d.ts +73 -0
  47. package/dist/AI/components/autotagging/components/classify-seed-taxonomy.component.d.ts.map +1 -0
  48. package/dist/AI/components/autotagging/components/classify-seed-taxonomy.component.js +393 -0
  49. package/dist/AI/components/autotagging/components/classify-seed-taxonomy.component.js.map +1 -0
  50. package/dist/AI/components/autotagging/dialogs/classify-setup-wizard.component.d.ts +122 -0
  51. package/dist/AI/components/autotagging/dialogs/classify-setup-wizard.component.d.ts.map +1 -0
  52. package/dist/AI/components/autotagging/dialogs/classify-setup-wizard.component.js +908 -0
  53. package/dist/AI/components/autotagging/dialogs/classify-setup-wizard.component.js.map +1 -0
  54. package/dist/AI/components/autotagging/dialogs/dry-run-preview.dialog.component.d.ts +87 -0
  55. package/dist/AI/components/autotagging/dialogs/dry-run-preview.dialog.component.d.ts.map +1 -0
  56. package/dist/AI/components/autotagging/dialogs/dry-run-preview.dialog.component.js +475 -0
  57. package/dist/AI/components/autotagging/dialogs/dry-run-preview.dialog.component.js.map +1 -0
  58. package/dist/AI/components/autotagging/dialogs/item-detail.dialog.component.d.ts +29 -0
  59. package/dist/AI/components/autotagging/dialogs/item-detail.dialog.component.d.ts.map +1 -0
  60. package/dist/AI/components/autotagging/dialogs/item-detail.dialog.component.js +208 -0
  61. package/dist/AI/components/autotagging/dialogs/item-detail.dialog.component.js.map +1 -0
  62. package/dist/AI/components/autotagging/dialogs/no-content-type-warning.dialog.component.d.ts +21 -0
  63. package/dist/AI/components/autotagging/dialogs/no-content-type-warning.dialog.component.d.ts.map +1 -0
  64. package/dist/AI/components/autotagging/dialogs/no-content-type-warning.dialog.component.js +70 -0
  65. package/dist/AI/components/autotagging/dialogs/no-content-type-warning.dialog.component.js.map +1 -0
  66. package/dist/AI/components/autotagging/dialogs/source-type-form.dialog.component.d.ts +333 -0
  67. package/dist/AI/components/autotagging/dialogs/source-type-form.dialog.component.d.ts.map +1 -0
  68. package/dist/AI/components/autotagging/dialogs/source-type-form.dialog.component.js +2125 -0
  69. package/dist/AI/components/autotagging/dialogs/source-type-form.dialog.component.js.map +1 -0
  70. package/dist/AI/components/autotagging/shared/classify.dryrun.d.ts +61 -0
  71. package/dist/AI/components/autotagging/shared/classify.dryrun.d.ts.map +1 -0
  72. package/dist/AI/components/autotagging/shared/classify.dryrun.js +78 -0
  73. package/dist/AI/components/autotagging/shared/classify.dryrun.js.map +1 -0
  74. package/dist/AI/components/autotagging/shared/classify.format.d.ts +58 -0
  75. package/dist/AI/components/autotagging/shared/classify.format.d.ts.map +1 -0
  76. package/dist/AI/components/autotagging/shared/classify.format.js +260 -0
  77. package/dist/AI/components/autotagging/shared/classify.format.js.map +1 -0
  78. package/dist/AI/components/autotagging/shared/classify.types.d.ts +319 -0
  79. package/dist/AI/components/autotagging/shared/classify.types.d.ts.map +1 -0
  80. package/dist/AI/components/autotagging/shared/classify.types.js +6 -0
  81. package/dist/AI/components/autotagging/shared/classify.types.js.map +1 -0
  82. package/dist/AI/components/autotagging/tabs/health-tab.component.d.ts +103 -0
  83. package/dist/AI/components/autotagging/tabs/health-tab.component.d.ts.map +1 -0
  84. package/dist/AI/components/autotagging/tabs/health-tab.component.js +571 -0
  85. package/dist/AI/components/autotagging/tabs/health-tab.component.js.map +1 -0
  86. package/dist/AI/components/autotagging/tabs/history-tab.component.d.ts +77 -0
  87. package/dist/AI/components/autotagging/tabs/history-tab.component.d.ts.map +1 -0
  88. package/dist/AI/components/autotagging/tabs/history-tab.component.js +519 -0
  89. package/dist/AI/components/autotagging/tabs/history-tab.component.js.map +1 -0
  90. package/dist/AI/components/autotagging/tabs/inbox-tab.component.d.ts +107 -0
  91. package/dist/AI/components/autotagging/tabs/inbox-tab.component.d.ts.map +1 -0
  92. package/dist/AI/components/autotagging/tabs/inbox-tab.component.js +719 -0
  93. package/dist/AI/components/autotagging/tabs/inbox-tab.component.js.map +1 -0
  94. package/dist/AI/components/autotagging/tabs/pipeline-tab.component.d.ts +131 -0
  95. package/dist/AI/components/autotagging/tabs/pipeline-tab.component.d.ts.map +1 -0
  96. package/dist/AI/components/autotagging/tabs/pipeline-tab.component.js +813 -0
  97. package/dist/AI/components/autotagging/tabs/pipeline-tab.component.js.map +1 -0
  98. package/dist/AI/components/autotagging/tabs/sources-tab.component.d.ts +177 -0
  99. package/dist/AI/components/autotagging/tabs/sources-tab.component.d.ts.map +1 -0
  100. package/dist/AI/components/autotagging/tabs/sources-tab.component.js +1465 -0
  101. package/dist/AI/components/autotagging/tabs/sources-tab.component.js.map +1 -0
  102. package/dist/AI/components/autotagging/tabs/tags-tab.component.d.ts +78 -0
  103. package/dist/AI/components/autotagging/tabs/tags-tab.component.d.ts.map +1 -0
  104. package/dist/AI/components/autotagging/tabs/tags-tab.component.js +492 -0
  105. package/dist/AI/components/autotagging/tabs/tags-tab.component.js.map +1 -0
  106. package/dist/AI/components/autotagging/tabs/taxonomy-tab.component.d.ts +397 -0
  107. package/dist/AI/components/autotagging/tabs/taxonomy-tab.component.d.ts.map +1 -0
  108. package/dist/AI/components/autotagging/tabs/taxonomy-tab.component.js +3490 -0
  109. package/dist/AI/components/autotagging/tabs/taxonomy-tab.component.js.map +1 -0
  110. package/dist/AI/components/autotagging/tabs/types-tab.component.d.ts +56 -0
  111. package/dist/AI/components/autotagging/tabs/types-tab.component.d.ts.map +1 -0
  112. package/dist/AI/components/autotagging/tabs/types-tab.component.js +271 -0
  113. package/dist/AI/components/autotagging/tabs/types-tab.component.js.map +1 -0
  114. package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts +3 -0
  115. package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts.map +1 -1
  116. package/dist/AI/components/duplicates/duplicate-detection-resource.component.js +306 -290
  117. package/dist/AI/components/duplicates/duplicate-detection-resource.component.js.map +1 -1
  118. package/dist/AI/components/execution-monitoring.component.js +1 -1
  119. package/dist/AI/components/execution-monitoring.component.js.map +1 -1
  120. package/dist/AI/components/models/model-management.component.js +209 -208
  121. package/dist/AI/components/models/model-management.component.js.map +1 -1
  122. package/dist/AI/components/prompts/prompt-management.component.js +130 -128
  123. package/dist/AI/components/prompts/prompt-management.component.js.map +1 -1
  124. package/dist/AI/components/requests/agent-requests-resource.component.js +61 -61
  125. package/dist/AI/components/requests/agent-requests-resource.component.js.map +1 -1
  126. package/dist/AI/components/system/system-configuration.component.js +17 -17
  127. package/dist/AI/components/system/system-configuration.component.js.map +1 -1
  128. package/dist/AI/components/tags/tags-resource.component.d.ts +1 -0
  129. package/dist/AI/components/tags/tags-resource.component.d.ts.map +1 -1
  130. package/dist/AI/components/tags/tags-resource.component.js +578 -538
  131. package/dist/AI/components/tags/tags-resource.component.js.map +1 -1
  132. package/dist/AI/components/vectors/vector-management-resource.component.d.ts +3 -0
  133. package/dist/AI/components/vectors/vector-management-resource.component.d.ts.map +1 -1
  134. package/dist/AI/components/vectors/vector-management-resource.component.js +331 -303
  135. package/dist/AI/components/vectors/vector-management-resource.component.js.map +1 -1
  136. package/dist/AI/services/ai-instrumentation.service.d.ts +5 -0
  137. package/dist/AI/services/ai-instrumentation.service.d.ts.map +1 -1
  138. package/dist/AI/services/ai-instrumentation.service.js +14 -2
  139. package/dist/AI/services/ai-instrumentation.service.js.map +1 -1
  140. package/dist/AI/services/cache-metrics.d.ts +50 -0
  141. package/dist/AI/services/cache-metrics.d.ts.map +1 -0
  142. package/dist/AI/services/cache-metrics.js +43 -0
  143. package/dist/AI/services/cache-metrics.js.map +1 -0
  144. package/dist/APIKeys/api-applications-panel.component.js +2 -2
  145. package/dist/APIKeys/api-key-create-dialog.component.js +2 -2
  146. package/dist/APIKeys/api-key-edit-panel.component.js +2 -2
  147. package/dist/APIKeys/api-keys-resource.component.js +132 -131
  148. package/dist/APIKeys/api-keys-resource.component.js.map +1 -1
  149. package/dist/Actions/components/actions-overview.component.js +141 -141
  150. package/dist/Actions/components/actions-overview.component.js.map +1 -1
  151. package/dist/Actions/components/execution-monitoring.component.js +15 -15
  152. package/dist/Actions/components/execution-monitoring.component.js.map +1 -1
  153. package/dist/Actions/components/explorer/action-explorer.component.d.ts +0 -5
  154. package/dist/Actions/components/explorer/action-explorer.component.d.ts.map +1 -1
  155. package/dist/Actions/components/explorer/action-explorer.component.js +139 -212
  156. package/dist/Actions/components/explorer/action-explorer.component.js.map +1 -1
  157. package/dist/Admin/admin-data-schema.component.js +2 -2
  158. package/dist/Admin/admin-data-schema.component.js.map +1 -1
  159. package/dist/Admin/admin-dev-tools-resource.component.js +2 -2
  160. package/dist/Admin/admin-dev-tools-resource.component.js.map +1 -1
  161. package/dist/Admin/admin-identity-access.component.js +2 -2
  162. package/dist/Admin/admin-identity-access.component.js.map +1 -1
  163. package/dist/Admin/admin-monitoring.component.js +2 -2
  164. package/dist/Admin/admin-monitoring.component.js.map +1 -1
  165. package/dist/ApplicationRoles/application-roles-resource.component.js +54 -49
  166. package/dist/ApplicationRoles/application-roles-resource.component.js.map +1 -1
  167. package/dist/Communication/communication-logs-resource.component.d.ts +6 -0
  168. package/dist/Communication/communication-logs-resource.component.d.ts.map +1 -1
  169. package/dist/Communication/communication-logs-resource.component.js +72 -50
  170. package/dist/Communication/communication-logs-resource.component.js.map +1 -1
  171. package/dist/Communication/communication-monitor-resource.component.js +103 -102
  172. package/dist/Communication/communication-monitor-resource.component.js.map +1 -1
  173. package/dist/Communication/communication-providers-resource.component.js +52 -51
  174. package/dist/Communication/communication-providers-resource.component.js.map +1 -1
  175. package/dist/Communication/communication-runs-resource.component.js +39 -38
  176. package/dist/Communication/communication-runs-resource.component.js.map +1 -1
  177. package/dist/Communication/communication-templates-resource.component.d.ts +6 -0
  178. package/dist/Communication/communication-templates-resource.component.d.ts.map +1 -1
  179. package/dist/Communication/communication-templates-resource.component.js +92 -89
  180. package/dist/Communication/communication-templates-resource.component.js.map +1 -1
  181. package/dist/Credentials/components/credentials-audit-resource.component.js +136 -135
  182. package/dist/Credentials/components/credentials-audit-resource.component.js.map +1 -1
  183. package/dist/Credentials/components/credentials-categories-resource.component.js +155 -152
  184. package/dist/Credentials/components/credentials-categories-resource.component.js.map +1 -1
  185. package/dist/Credentials/components/credentials-list-resource.component.js +119 -118
  186. package/dist/Credentials/components/credentials-list-resource.component.js.map +1 -1
  187. package/dist/Credentials/components/credentials-overview-resource.component.js +129 -128
  188. package/dist/Credentials/components/credentials-overview-resource.component.js.map +1 -1
  189. package/dist/Credentials/components/credentials-types-resource.component.js +107 -106
  190. package/dist/Credentials/components/credentials-types-resource.component.js.map +1 -1
  191. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +31 -340
  192. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
  193. package/dist/DataExplorer/data-explorer-dashboard.component.js +468 -1958
  194. package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
  195. package/dist/DataExplorer/data-explorer-resource.component.d.ts.map +1 -1
  196. package/dist/DataExplorer/data-explorer-resource.component.js +10 -0
  197. package/dist/DataExplorer/data-explorer-resource.component.js.map +1 -1
  198. package/dist/DatabaseDesigner/components/database-designer-dashboard.component.js +1 -1
  199. package/dist/DatabaseDesigner/components/entity-list.component.js +115 -114
  200. package/dist/DatabaseDesigner/components/entity-list.component.js.map +1 -1
  201. package/dist/DatabaseDesigner/database-designer-dashboards.module.d.ts +5 -6
  202. package/dist/DatabaseDesigner/database-designer-dashboards.module.d.ts.map +1 -1
  203. package/dist/DatabaseDesigner/database-designer-dashboards.module.js +4 -5
  204. package/dist/DatabaseDesigner/database-designer-dashboards.module.js.map +1 -1
  205. package/dist/DevTools/app-state-inspector.component.js +18 -17
  206. package/dist/DevTools/app-state-inspector.component.js.map +1 -1
  207. package/dist/DevTools/class-registry.component.js +88 -85
  208. package/dist/DevTools/class-registry.component.js.map +1 -1
  209. package/dist/DevTools/event-monitor.component.js +155 -150
  210. package/dist/DevTools/event-monitor.component.js.map +1 -1
  211. package/dist/DevTools/graphql-console.component.js +245 -243
  212. package/dist/DevTools/graphql-console.component.js.map +1 -1
  213. package/dist/DevTools/layout-inspector.component.js +18 -17
  214. package/dist/DevTools/layout-inspector.component.js.map +1 -1
  215. package/dist/EntityAdmin/entity-admin-dashboard.component.js +20 -19
  216. package/dist/EntityAdmin/entity-admin-dashboard.component.js.map +1 -1
  217. package/dist/Home/home-dashboard.component.js +2 -2
  218. package/dist/Integration/components/activity/activity.component.d.ts.map +1 -1
  219. package/dist/Integration/components/activity/activity.component.js +236 -229
  220. package/dist/Integration/components/activity/activity.component.js.map +1 -1
  221. package/dist/Integration/components/connections/connections.component.js +390 -389
  222. package/dist/Integration/components/connections/connections.component.js.map +1 -1
  223. package/dist/Integration/components/overview/overview.component.js +2 -2
  224. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.d.ts.map +1 -1
  225. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js +14 -11
  226. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js.map +1 -1
  227. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.d.ts +27 -2
  228. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.d.ts.map +1 -1
  229. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js +244 -119
  230. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js.map +1 -1
  231. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js +293 -291
  232. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js.map +1 -1
  233. package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.js +62 -61
  234. package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.js.map +1 -1
  235. package/dist/KnowledgeHub/components/visualize/record-drilldown/record-drilldown.component.d.ts +65 -0
  236. package/dist/KnowledgeHub/components/visualize/record-drilldown/record-drilldown.component.d.ts.map +1 -0
  237. package/dist/KnowledgeHub/components/visualize/record-drilldown/record-drilldown.component.js +176 -0
  238. package/dist/KnowledgeHub/components/visualize/record-drilldown/record-drilldown.component.js.map +1 -0
  239. package/dist/KnowledgeHub/components/visualize/tag-cloud/tag-cloud.component.d.ts +81 -0
  240. package/dist/KnowledgeHub/components/visualize/tag-cloud/tag-cloud.component.d.ts.map +1 -0
  241. package/dist/KnowledgeHub/components/visualize/tag-cloud/tag-cloud.component.js +308 -0
  242. package/dist/KnowledgeHub/components/visualize/tag-cloud/tag-cloud.component.js.map +1 -0
  243. package/dist/KnowledgeHub/components/visualize/visualize-resource.component.d.ts +85 -0
  244. package/dist/KnowledgeHub/components/visualize/visualize-resource.component.d.ts.map +1 -0
  245. package/dist/KnowledgeHub/components/visualize/visualize-resource.component.js +362 -0
  246. package/dist/KnowledgeHub/components/visualize/visualize-resource.component.js.map +1 -0
  247. package/dist/KnowledgeHub/index.d.ts +3 -0
  248. package/dist/KnowledgeHub/index.d.ts.map +1 -1
  249. package/dist/KnowledgeHub/index.js +3 -0
  250. package/dist/KnowledgeHub/index.js.map +1 -1
  251. package/dist/Lists/components/lists-browse-resource.component.d.ts +6 -2
  252. package/dist/Lists/components/lists-browse-resource.component.d.ts.map +1 -1
  253. package/dist/Lists/components/lists-browse-resource.component.js +525 -566
  254. package/dist/Lists/components/lists-browse-resource.component.js.map +1 -1
  255. package/dist/Lists/components/lists-categories-resource.component.js +135 -134
  256. package/dist/Lists/components/lists-categories-resource.component.js.map +1 -1
  257. package/dist/Lists/components/lists-my-lists-resource.component.js +199 -198
  258. package/dist/Lists/components/lists-my-lists-resource.component.js.map +1 -1
  259. package/dist/MCP/components/mcp-server-dialog.component.js +2 -2
  260. package/dist/MCP/mcp-dashboard.component.js +443 -438
  261. package/dist/MCP/mcp-dashboard.component.js.map +1 -1
  262. package/dist/QueryBrowser/query-browser-resource.component.js +1 -1
  263. package/dist/QueryBrowser/query-browser-resource.component.js.map +1 -1
  264. package/dist/Scheduling/components/scheduling-activity.component.d.ts.map +1 -1
  265. package/dist/Scheduling/components/scheduling-activity.component.js +146 -147
  266. package/dist/Scheduling/components/scheduling-activity.component.js.map +1 -1
  267. package/dist/Scheduling/components/scheduling-jobs.component.js +76 -75
  268. package/dist/Scheduling/components/scheduling-jobs.component.js.map +1 -1
  269. package/dist/Scheduling/components/scheduling-overview.component.js +97 -96
  270. package/dist/Scheduling/components/scheduling-overview.component.js.map +1 -1
  271. package/dist/Scheduling/scheduling-dashboard.component.js +24 -22
  272. package/dist/Scheduling/scheduling-dashboard.component.js.map +1 -1
  273. package/dist/Scheduling/services/scheduling-instrumentation.service.d.ts +2 -0
  274. package/dist/Scheduling/services/scheduling-instrumentation.service.d.ts.map +1 -1
  275. package/dist/Scheduling/services/scheduling-instrumentation.service.js +1 -0
  276. package/dist/Scheduling/services/scheduling-instrumentation.service.js.map +1 -1
  277. package/dist/Testing/components/testing-dashboard-tab-resource.component.js +1 -1
  278. package/dist/Testing/components/testing-explorer.component.d.ts +14 -4
  279. package/dist/Testing/components/testing-explorer.component.d.ts.map +1 -1
  280. package/dist/Testing/components/testing-explorer.component.js +436 -427
  281. package/dist/Testing/components/testing-explorer.component.js.map +1 -1
  282. package/dist/Testing/components/testing-runs-resource.component.js +1 -1
  283. package/dist/Testing/components/testing-runs.component.js +116 -115
  284. package/dist/Testing/components/testing-runs.component.js.map +1 -1
  285. package/dist/Testing/testing-dashboard.component.js +6 -7
  286. package/dist/Testing/testing-dashboard.component.js.map +1 -1
  287. package/dist/VersionHistory/components/labels-resource.component.js +173 -172
  288. package/dist/VersionHistory/components/labels-resource.component.js.map +1 -1
  289. package/dist/VersionHistory/components/restore-resource.component.d.ts +6 -0
  290. package/dist/VersionHistory/components/restore-resource.component.d.ts.map +1 -1
  291. package/dist/VersionHistory/components/restore-resource.component.js +116 -92
  292. package/dist/VersionHistory/components/restore-resource.component.js.map +1 -1
  293. package/dist/ai-dashboards.module.d.ts +57 -35
  294. package/dist/ai-dashboards.module.d.ts.map +1 -1
  295. package/dist/ai-dashboards.module.js +80 -1
  296. package/dist/ai-dashboards.module.js.map +1 -1
  297. package/dist/communication-dashboards.module.d.ts +1 -1
  298. package/dist/communication-dashboards.module.d.ts.map +1 -1
  299. package/dist/communication-dashboards.module.js +7 -1
  300. package/dist/communication-dashboards.module.js.map +1 -1
  301. package/dist/data-explorer-dashboards.module.d.ts +12 -14
  302. package/dist/data-explorer-dashboards.module.d.ts.map +1 -1
  303. package/dist/data-explorer-dashboards.module.js +5 -14
  304. package/dist/data-explorer-dashboards.module.js.map +1 -1
  305. package/dist/public-api.d.ts +3 -0
  306. package/dist/public-api.d.ts.map +1 -1
  307. package/dist/public-api.js +3 -0
  308. package/dist/public-api.js.map +1 -1
  309. package/dist/testing-dashboards.module.d.ts +4 -5
  310. package/dist/testing-dashboards.module.d.ts.map +1 -1
  311. package/dist/testing-dashboards.module.js +7 -5
  312. package/dist/testing-dashboards.module.js.map +1 -1
  313. package/package.json +57 -54
  314. package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.d.ts +0 -79
  315. package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.d.ts.map +0 -1
  316. package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.js +0 -195
  317. package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.js.map +0 -1
  318. package/dist/DataExplorer/components/view-selector/view-selector.component.d.ts +0 -226
  319. package/dist/DataExplorer/components/view-selector/view-selector.component.d.ts.map +0 -1
  320. package/dist/DataExplorer/components/view-selector/view-selector.component.js +0 -861
  321. package/dist/DataExplorer/components/view-selector/view-selector.component.js.map +0 -1
@@ -0,0 +1,519 @@
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, EventEmitter, Input, Output, 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
+ import * as i3 from "../components/classify-item-grid.component";
17
+ const _forTrack0 = ($index, $item) => $item.ID;
18
+ const _forTrack1 = ($index, $item) => $item.SourceName;
19
+ function ClassifyHistoryTabComponent_Conditional_3_Template(rf, ctx) { if (rf & 1) {
20
+ i0.ɵɵelement(0, "i", 15);
21
+ i0.ɵɵelementStart(1, "span", 16);
22
+ i0.ɵɵtext(2, "Refreshing\u2026");
23
+ i0.ɵɵelementEnd();
24
+ } }
25
+ function ClassifyHistoryTabComponent_Conditional_4_Template(rf, ctx) { if (rf & 1) {
26
+ i0.ɵɵelement(0, "i", 17);
27
+ i0.ɵɵelementStart(1, "span", 16);
28
+ i0.ɵɵtext(2, "Refresh");
29
+ i0.ɵɵelementEnd();
30
+ } }
31
+ function ClassifyHistoryTabComponent_For_32_Conditional_3_Template(rf, ctx) { if (rf & 1) {
32
+ i0.ɵɵelement(0, "i", 20);
33
+ } }
34
+ function ClassifyHistoryTabComponent_For_32_Template(rf, ctx) { if (rf & 1) {
35
+ const _r1 = i0.ɵɵgetCurrentView();
36
+ i0.ɵɵelementStart(0, "tr", 18);
37
+ i0.ɵɵlistener("click", function ClassifyHistoryTabComponent_For_32_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)); });
38
+ i0.ɵɵelementStart(1, "td")(2, "span", 19);
39
+ i0.ɵɵconditionalCreate(3, ClassifyHistoryTabComponent_For_32_Conditional_3_Template, 1, 0, "i", 20);
40
+ i0.ɵɵtext(4);
41
+ i0.ɵɵelementEnd()();
42
+ i0.ɵɵelementStart(5, "td", 21);
43
+ i0.ɵɵtext(6);
44
+ i0.ɵɵelementEnd();
45
+ i0.ɵɵelementStart(7, "td");
46
+ i0.ɵɵtext(8);
47
+ i0.ɵɵelementEnd();
48
+ i0.ɵɵelementStart(9, "td", 22);
49
+ i0.ɵɵtext(10);
50
+ i0.ɵɵelementEnd();
51
+ i0.ɵɵelementStart(11, "td");
52
+ i0.ɵɵtext(12);
53
+ i0.ɵɵelementEnd();
54
+ i0.ɵɵelementStart(13, "td");
55
+ i0.ɵɵtext(14);
56
+ i0.ɵɵelementEnd();
57
+ i0.ɵɵelementStart(15, "td");
58
+ i0.ɵɵtext(16);
59
+ i0.ɵɵelementEnd()();
60
+ } if (rf & 2) {
61
+ const row_r2 = ctx.$implicit;
62
+ const ctx_r2 = i0.ɵɵnextContext();
63
+ i0.ɵɵclassProp("at-run-row-selected", ctx_r2.SelectedRunID === row_r2.ID);
64
+ i0.ɵɵadvance(2);
65
+ i0.ɵɵclassMap(row_r2.StatusClass);
66
+ i0.ɵɵadvance();
67
+ i0.ɵɵconditional(row_r2.StatusClass === "running" ? 3 : -1);
68
+ i0.ɵɵadvance();
69
+ i0.ɵɵtextInterpolate1(" ", row_r2.Status, " ");
70
+ i0.ɵɵadvance(2);
71
+ i0.ɵɵtextInterpolate(row_r2.SourceName);
72
+ i0.ɵɵadvance(2);
73
+ i0.ɵɵtextInterpolate(row_r2.StartedDisplay);
74
+ i0.ɵɵadvance(2);
75
+ i0.ɵɵtextInterpolate(row_r2.Duration);
76
+ i0.ɵɵadvance(2);
77
+ i0.ɵɵtextInterpolate(row_r2.Items);
78
+ i0.ɵɵadvance(2);
79
+ i0.ɵɵtextInterpolate(row_r2.Tags);
80
+ i0.ɵɵadvance();
81
+ i0.ɵɵclassMap(row_r2.ErrorClass);
82
+ i0.ɵɵadvance();
83
+ i0.ɵɵtextInterpolate(row_r2.Errors);
84
+ } }
85
+ function ClassifyHistoryTabComponent_Conditional_33_Conditional_3_Conditional_1_Template(rf, ctx) { if (rf & 1) {
86
+ i0.ɵɵelement(0, "i", 15);
87
+ i0.ɵɵtext(1, " Loading\u2026 ");
88
+ } }
89
+ function ClassifyHistoryTabComponent_Conditional_33_Conditional_3_Conditional_2_Template(rf, ctx) { if (rf & 1) {
90
+ i0.ɵɵelement(0, "i", 25);
91
+ i0.ɵɵtext(1, " Load more ");
92
+ } }
93
+ function ClassifyHistoryTabComponent_Conditional_33_Conditional_3_Template(rf, ctx) { if (rf & 1) {
94
+ const _r4 = i0.ɵɵgetCurrentView();
95
+ i0.ɵɵelementStart(0, "button", 2);
96
+ i0.ɵɵlistener("click", function ClassifyHistoryTabComponent_Conditional_33_Conditional_3_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onLoadMore()); });
97
+ i0.ɵɵconditionalCreate(1, ClassifyHistoryTabComponent_Conditional_33_Conditional_3_Conditional_1_Template, 2, 0)(2, ClassifyHistoryTabComponent_Conditional_33_Conditional_3_Conditional_2_Template, 2, 0);
98
+ i0.ɵɵelementEnd();
99
+ } if (rf & 2) {
100
+ const ctx_r2 = i0.ɵɵnextContext(2);
101
+ i0.ɵɵproperty("disabled", ctx_r2.IsLoadingMore);
102
+ i0.ɵɵadvance();
103
+ i0.ɵɵconditional(ctx_r2.IsLoadingMore ? 1 : 2);
104
+ } }
105
+ function ClassifyHistoryTabComponent_Conditional_33_Template(rf, ctx) { if (rf & 1) {
106
+ i0.ɵɵelementStart(0, "div", 13)(1, "span", 23);
107
+ i0.ɵɵtext(2);
108
+ i0.ɵɵelementEnd();
109
+ i0.ɵɵconditionalCreate(3, ClassifyHistoryTabComponent_Conditional_33_Conditional_3_Template, 3, 2, "button", 24);
110
+ i0.ɵɵelementEnd();
111
+ } if (rf & 2) {
112
+ const ctx_r2 = i0.ɵɵnextContext();
113
+ i0.ɵɵadvance(2);
114
+ i0.ɵɵtextInterpolate2("Showing ", ctx_r2.FilteredRunRows.length, " of ", ctx_r2.TotalRunCount, " runs");
115
+ i0.ɵɵadvance();
116
+ i0.ɵɵconditional(ctx_r2.HasMoreRuns ? 3 : -1);
117
+ } }
118
+ function ClassifyHistoryTabComponent_Conditional_34_Conditional_9_Template(rf, ctx) { if (rf & 1) {
119
+ i0.ɵɵelement(0, "mj-loading", 32);
120
+ } }
121
+ function ClassifyHistoryTabComponent_Conditional_34_Conditional_10_For_25_Template(rf, ctx) { if (rf & 1) {
122
+ i0.ɵɵelementStart(0, "tr")(1, "td", 21);
123
+ i0.ɵɵtext(2);
124
+ i0.ɵɵelementEnd();
125
+ i0.ɵɵelementStart(3, "td");
126
+ i0.ɵɵtext(4);
127
+ i0.ɵɵelementEnd();
128
+ i0.ɵɵelementStart(5, "td")(6, "span", 19);
129
+ i0.ɵɵtext(7);
130
+ i0.ɵɵelementEnd()();
131
+ i0.ɵɵelementStart(8, "td");
132
+ i0.ɵɵtext(9);
133
+ i0.ɵɵelementEnd();
134
+ i0.ɵɵelementStart(10, "td");
135
+ i0.ɵɵtext(11);
136
+ i0.ɵɵelementEnd();
137
+ i0.ɵɵelementStart(12, "td");
138
+ i0.ɵɵtext(13);
139
+ i0.ɵɵelementEnd();
140
+ i0.ɵɵelementStart(14, "td");
141
+ i0.ɵɵtext(15);
142
+ i0.ɵɵelementEnd();
143
+ i0.ɵɵelementStart(16, "td");
144
+ i0.ɵɵtext(17);
145
+ i0.ɵɵelementEnd();
146
+ i0.ɵɵelementStart(18, "td");
147
+ i0.ɵɵtext(19);
148
+ i0.ɵɵelementEnd();
149
+ i0.ɵɵelementStart(20, "td", 22);
150
+ i0.ɵɵtext(21);
151
+ i0.ɵɵelementEnd()();
152
+ } if (rf & 2) {
153
+ const detail_r6 = ctx.$implicit;
154
+ const ctx_r2 = i0.ɵɵnextContext(3);
155
+ i0.ɵɵadvance(2);
156
+ i0.ɵɵtextInterpolate(detail_r6.SourceName);
157
+ i0.ɵɵadvance(2);
158
+ i0.ɵɵtextInterpolate(detail_r6.SourceType);
159
+ i0.ɵɵadvance(2);
160
+ i0.ɵɵclassMap(detail_r6.StatusClass);
161
+ i0.ɵɵadvance();
162
+ i0.ɵɵtextInterpolate(detail_r6.Status);
163
+ i0.ɵɵadvance(2);
164
+ i0.ɵɵtextInterpolate(detail_r6.ItemsProcessed);
165
+ i0.ɵɵadvance(2);
166
+ i0.ɵɵtextInterpolate(detail_r6.ItemsTagged);
167
+ i0.ɵɵadvance(2);
168
+ i0.ɵɵtextInterpolate(detail_r6.ItemsVectorized);
169
+ i0.ɵɵadvance();
170
+ i0.ɵɵclassProp("run-error-text", detail_r6.ErrorCount > 0);
171
+ i0.ɵɵadvance();
172
+ i0.ɵɵtextInterpolate(detail_r6.ErrorCount);
173
+ i0.ɵɵadvance(2);
174
+ i0.ɵɵtextInterpolate(ctx_r2.FormatTokenCount(detail_r6.TotalTokens));
175
+ i0.ɵɵadvance(2);
176
+ i0.ɵɵtextInterpolate(detail_r6.TotalCost > 0 ? "$" + detail_r6.TotalCost.toFixed(4) : "$0.00");
177
+ i0.ɵɵadvance(2);
178
+ i0.ɵɵtextInterpolate(detail_r6.Duration);
179
+ } }
180
+ function ClassifyHistoryTabComponent_Conditional_34_Conditional_10_Template(rf, ctx) { if (rf & 1) {
181
+ i0.ɵɵelementStart(0, "table", 11)(1, "thead")(2, "tr")(3, "th");
182
+ i0.ɵɵtext(4, "Source");
183
+ i0.ɵɵelementEnd();
184
+ i0.ɵɵelementStart(5, "th");
185
+ i0.ɵɵtext(6, "Source Type");
186
+ i0.ɵɵelementEnd();
187
+ i0.ɵɵelementStart(7, "th");
188
+ i0.ɵɵtext(8, "Status");
189
+ i0.ɵɵelementEnd();
190
+ i0.ɵɵelementStart(9, "th");
191
+ i0.ɵɵtext(10, "Items");
192
+ i0.ɵɵelementEnd();
193
+ i0.ɵɵelementStart(11, "th");
194
+ i0.ɵɵtext(12, "Tagged");
195
+ i0.ɵɵelementEnd();
196
+ i0.ɵɵelementStart(13, "th");
197
+ i0.ɵɵtext(14, "Vectorized");
198
+ i0.ɵɵelementEnd();
199
+ i0.ɵɵelementStart(15, "th");
200
+ i0.ɵɵtext(16, "Errors");
201
+ i0.ɵɵelementEnd();
202
+ i0.ɵɵelementStart(17, "th");
203
+ i0.ɵɵtext(18, "Tokens");
204
+ i0.ɵɵelementEnd();
205
+ i0.ɵɵelementStart(19, "th");
206
+ i0.ɵɵtext(20, "Cost");
207
+ i0.ɵɵelementEnd();
208
+ i0.ɵɵelementStart(21, "th");
209
+ i0.ɵɵtext(22, "Duration");
210
+ i0.ɵɵelementEnd()()();
211
+ i0.ɵɵelementStart(23, "tbody");
212
+ i0.ɵɵrepeaterCreate(24, ClassifyHistoryTabComponent_Conditional_34_Conditional_10_For_25_Template, 22, 14, "tr", null, _forTrack1);
213
+ i0.ɵɵelementEnd()();
214
+ } if (rf & 2) {
215
+ const ctx_r2 = i0.ɵɵnextContext(2);
216
+ i0.ɵɵadvance(24);
217
+ i0.ɵɵrepeater(ctx_r2.RunDetailRows);
218
+ } }
219
+ function ClassifyHistoryTabComponent_Conditional_34_Conditional_11_Template(rf, ctx) { if (rf & 1) {
220
+ i0.ɵɵelementStart(0, "div", 33);
221
+ i0.ɵɵelement(1, "i", 38);
222
+ i0.ɵɵelementStart(2, "p");
223
+ i0.ɵɵtext(3, "No per-source detail records found for this run.");
224
+ i0.ɵɵelementEnd()();
225
+ } }
226
+ function ClassifyHistoryTabComponent_Conditional_34_Template(rf, ctx) { if (rf & 1) {
227
+ const _r5 = i0.ɵɵgetCurrentView();
228
+ i0.ɵɵelementStart(0, "div", 14)(1, "div", 26)(2, "span", 27);
229
+ i0.ɵɵelement(3, "i", 28);
230
+ i0.ɵɵtext(4);
231
+ i0.ɵɵelementEnd();
232
+ i0.ɵɵelementStart(5, "button", 29);
233
+ i0.ɵɵlistener("click", function ClassifyHistoryTabComponent_Conditional_34_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r5); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.CloseRunDetail()); });
234
+ i0.ɵɵelement(6, "i", 30);
235
+ i0.ɵɵtext(7, " Close ");
236
+ i0.ɵɵelementEnd()();
237
+ i0.ɵɵelementStart(8, "div", 31);
238
+ i0.ɵɵconditionalCreate(9, ClassifyHistoryTabComponent_Conditional_34_Conditional_9_Template, 1, 0, "mj-loading", 32)(10, ClassifyHistoryTabComponent_Conditional_34_Conditional_10_Template, 26, 0, "table", 11)(11, ClassifyHistoryTabComponent_Conditional_34_Conditional_11_Template, 4, 0, "div", 33);
239
+ i0.ɵɵelementStart(12, "div", 34)(13, "div", 35)(14, "span", 27);
240
+ i0.ɵɵelement(15, "i", 36);
241
+ i0.ɵɵtext(16, " Items in this run ");
242
+ i0.ɵɵelementEnd()();
243
+ i0.ɵɵelementStart(17, "classify-item-grid", 37);
244
+ i0.ɵɵlistener("ItemSelected", function ClassifyHistoryTabComponent_Conditional_34_Template_classify_item_grid_ItemSelected_17_listener($event) { i0.ɵɵrestoreView(_r5); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onItemSelected($event)); });
245
+ i0.ɵɵelementEnd()()()();
246
+ } if (rf & 2) {
247
+ const ctx_r2 = i0.ɵɵnextContext();
248
+ i0.ɵɵadvance(4);
249
+ i0.ɵɵtextInterpolate1(" Run Detail: ", ctx_r2.SelectedRunID.slice(0, 14), "... ");
250
+ i0.ɵɵadvance(5);
251
+ i0.ɵɵconditional(ctx_r2.IsLoadingRunDetail ? 9 : ctx_r2.RunDetailRows.length > 0 ? 10 : 11);
252
+ i0.ɵɵadvance(8);
253
+ i0.ɵɵproperty("RunID", ctx_r2.SelectedRunID)("Provider", ctx_r2.Provider);
254
+ } }
255
+ export class ClassifyHistoryTabComponent extends BaseAngularComponent {
256
+ cdr = inject(ChangeDetectorRef);
257
+ /** Shared raw `MJ: Content Process Runs` rows, supplied by the host orchestrator. */
258
+ _runs = [];
259
+ set Runs(value) {
260
+ this._runs = value ?? [];
261
+ this.buildRunHistoryRows();
262
+ this.buildHistorySourceOptions();
263
+ this.FilterRunHistory();
264
+ // A fresh Runs binding (from the host reload) ends any in-flight refresh.
265
+ this.IsLoading = false;
266
+ this.cdr.detectChanges();
267
+ }
268
+ get Runs() {
269
+ return this._runs;
270
+ }
271
+ /** Total run count in the DB (from TotalRowCount) — drives the "Showing X of Y" line. */
272
+ TotalRunCount = 0;
273
+ /** True while the host is fetching the next page in response to LoadMoreRequested. */
274
+ IsLoadingMore = false;
275
+ /** Bubble a "load more" request to the host, which widens the loaded window. */
276
+ LoadMoreRequested = new EventEmitter();
277
+ /**
278
+ * Bubble a content-item selection (from the per-run item grid) up to the host,
279
+ * which owns NavigationService + the drilldown slide-in.
280
+ */
281
+ ItemSelected = new EventEmitter();
282
+ onItemSelected(itemID) {
283
+ this.ItemSelected.emit(itemID);
284
+ }
285
+ /** Whether more runs exist in the DB than are currently loaded. */
286
+ get HasMoreRuns() {
287
+ return this.TotalRunCount > this._runs.length;
288
+ }
289
+ onLoadMore() {
290
+ this.LoadMoreRequested.emit();
291
+ }
292
+ /** Shown while the host reloads the run list in response to RefreshRequested. */
293
+ IsLoading = false;
294
+ /**
295
+ * Bubble a refresh request up to the host, which owns the run-history data
296
+ * (`MJ: Content Process Runs`). The host reloads and re-binds `[Runs]`, whose
297
+ * setter rebuilds the rows; the host also clears IsLoading via [Loading].
298
+ */
299
+ RefreshRequested = new EventEmitter();
300
+ RunHistoryRows = [];
301
+ FilteredRunRows = [];
302
+ HistorySourceFilter = '';
303
+ HistoryStatusFilter = '';
304
+ HistorySourceOptions = [];
305
+ // Per-run detail panel
306
+ SelectedRunID = null;
307
+ RunDetailRows = [];
308
+ IsLoadingRunDetail = false;
309
+ // Template-facing formatters
310
+ FormatTokenCount = formatTokenCount;
311
+ /**
312
+ * Ask the host to reload the run history. Data is host-owned, so we surface a
313
+ * loading state and emit; the new `[Runs]` binding clears IsLoading.
314
+ */
315
+ Refresh() {
316
+ this.IsLoading = true;
317
+ this.cdr.detectChanges();
318
+ this.RefreshRequested.emit();
319
+ }
320
+ buildRunHistoryRows() {
321
+ this.RunHistoryRows = this._runs.map(run => {
322
+ const status = run['Status'] ?? 'Unknown';
323
+ const startTime = run['StartTime'];
324
+ const endTime = run['EndTime'];
325
+ const duration = computeDuration(startTime, endTime);
326
+ const processedItems = run['ProcessedItems'];
327
+ const errorCount = run['ErrorCount'];
328
+ const statusLower = status.toLowerCase();
329
+ const isFailed = statusLower === 'error' || statusLower === 'failed';
330
+ const isRunning = statusLower === 'running' || statusLower === 'processing';
331
+ const hasErrors = (errorCount ?? 0) > 0;
332
+ return {
333
+ ID: run['ID'],
334
+ Status: displayStatus(status),
335
+ StatusClass: isFailed ? 'failed' : isRunning ? 'running' : 'complete',
336
+ SourceName: run['Source'] ?? 'Unknown',
337
+ StartedDisplay: startTime ? formatDate(startTime) : '—',
338
+ Duration: duration,
339
+ Items: processedItems != null ? formatNumber(processedItems) : '—',
340
+ Tags: '—',
341
+ Errors: hasErrors ? formatNumber(errorCount) : (isFailed ? status : '0'),
342
+ ErrorClass: isFailed || hasErrors ? 'run-error-text' : ''
343
+ };
344
+ });
345
+ }
346
+ buildHistorySourceOptions() {
347
+ const sources = new Set();
348
+ for (const run of this._runs) {
349
+ const s = run['Source'];
350
+ if (s)
351
+ sources.add(s);
352
+ }
353
+ this.HistorySourceOptions = Array.from(sources).sort();
354
+ }
355
+ FilterRunHistory() {
356
+ this.FilteredRunRows = this.RunHistoryRows.filter(row => {
357
+ if (this.HistorySourceFilter && row.SourceName !== this.HistorySourceFilter)
358
+ return false;
359
+ if (this.HistoryStatusFilter && row.StatusClass !== this.HistoryStatusFilter)
360
+ return false;
361
+ return true;
362
+ });
363
+ this.cdr.detectChanges();
364
+ }
365
+ /**
366
+ * Filter fields for the Run History section, rendered inside an
367
+ * `<mj-filter-popover>` (many values, single-select → popover with dropdown).
368
+ */
369
+ get historyFilterFields() {
370
+ return [
371
+ {
372
+ key: 'source',
373
+ type: 'dropdown',
374
+ label: 'Source',
375
+ placeholder: 'All Sources',
376
+ filterable: this.HistorySourceOptions.length > 10,
377
+ options: [
378
+ { text: 'All Sources', value: '' },
379
+ ...this.HistorySourceOptions.map(s => ({ text: s, value: s }))
380
+ ]
381
+ },
382
+ {
383
+ key: 'status',
384
+ type: 'dropdown',
385
+ label: 'Status',
386
+ placeholder: 'All Status',
387
+ options: [
388
+ { text: 'All Status', value: '' },
389
+ { text: 'Complete', value: 'complete' },
390
+ { text: 'Failed', value: 'failed' },
391
+ { text: 'Running', value: 'running' }
392
+ ]
393
+ }
394
+ ];
395
+ }
396
+ get historyFilterValues() {
397
+ return { source: this.HistorySourceFilter, status: this.HistoryStatusFilter };
398
+ }
399
+ get historyActiveFilterCount() {
400
+ return (this.HistorySourceFilter ? 1 : 0) + (this.HistoryStatusFilter ? 1 : 0);
401
+ }
402
+ onHistoryFilterChange(values) {
403
+ this.HistorySourceFilter = values['source'] ?? '';
404
+ this.HistoryStatusFilter = values['status'] ?? '';
405
+ this.FilterRunHistory();
406
+ }
407
+ onHistoryFilterReset() {
408
+ this.HistorySourceFilter = '';
409
+ this.HistoryStatusFilter = '';
410
+ this.FilterRunHistory();
411
+ }
412
+ /** Open (or toggle closed) the detail view for a run, loading its per-source detail rows. */
413
+ async OpenRunDetail(runID) {
414
+ if (this.SelectedRunID === runID) {
415
+ this.CloseRunDetail();
416
+ return;
417
+ }
418
+ this.SelectedRunID = runID;
419
+ this.IsLoadingRunDetail = true;
420
+ this.RunDetailRows = [];
421
+ this.cdr.detectChanges();
422
+ await this.loadRunDetailRows(runID);
423
+ this.IsLoadingRunDetail = false;
424
+ this.cdr.detectChanges();
425
+ }
426
+ CloseRunDetail() {
427
+ this.SelectedRunID = null;
428
+ this.RunDetailRows = [];
429
+ this.IsLoadingRunDetail = false;
430
+ this.cdr.detectChanges();
431
+ }
432
+ async loadRunDetailRows(runID) {
433
+ const rv = RunView.FromMetadataProvider(this.ProviderToUse);
434
+ const result = await rv.RunView({
435
+ EntityName: 'MJ: Content Process Run Details',
436
+ ExtraFilter: `ContentProcessRunID='${runID}'`,
437
+ OrderBy: 'ContentSource',
438
+ ResultType: 'simple',
439
+ });
440
+ if (result.Success) {
441
+ this.RunDetailRows = mapRunDetailRecords(result.Results);
442
+ }
443
+ }
444
+ static ɵfac = /*@__PURE__*/ (() => { let ɵClassifyHistoryTabComponent_BaseFactory; return function ClassifyHistoryTabComponent_Factory(__ngFactoryType__) { return (ɵClassifyHistoryTabComponent_BaseFactory || (ɵClassifyHistoryTabComponent_BaseFactory = i0.ɵɵgetInheritedFactory(ClassifyHistoryTabComponent)))(__ngFactoryType__ || ClassifyHistoryTabComponent); }; })();
445
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ClassifyHistoryTabComponent, selectors: [["classify-history-tab"]], inputs: { Runs: "Runs", TotalRunCount: "TotalRunCount", IsLoadingMore: "IsLoadingMore" }, outputs: { LoadMoreRequested: "LoadMoreRequested", ItemSelected: "ItemSelected", RefreshRequested: "RefreshRequested" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 35, vars: 10, consts: [["Title", "Run History", "Subtitle", "Pipeline execution history and per-source run detail"], ["actions", ""], ["mjButton", "", "variant", "secondary", "size", "sm", 3, "click", "disabled"], ["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-load-more-bar"], [1, "at-card", 2, "margin-top", "12px"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "mj-action-label"], [1, "fa-solid", "fa-arrows-rotate"], [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-load-more-count"], ["mjButton", "", "variant", "secondary", "size", "sm", 3, "disabled"], [1, "fa-solid", "fa-chevron-down"], [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, "at-run-items-section"], [1, "at-card-header", 2, "padding-left", "0", "padding-right", "0"], [1, "fa-solid", "fa-list-check"], [3, "ItemSelected", "RunID", "Provider"], [1, "fa-solid", "fa-info-circle"]], template: function ClassifyHistoryTabComponent_Template(rf, ctx) { if (rf & 1) {
446
+ i0.ɵɵelementStart(0, "mj-page-header-interior", 0)(1, "div", 1)(2, "button", 2);
447
+ i0.ɵɵlistener("click", function ClassifyHistoryTabComponent_Template_button_click_2_listener() { return ctx.Refresh(); });
448
+ i0.ɵɵconditionalCreate(3, ClassifyHistoryTabComponent_Conditional_3_Template, 3, 0)(4, ClassifyHistoryTabComponent_Conditional_4_Template, 3, 0);
449
+ i0.ɵɵelementEnd()();
450
+ i0.ɵɵelementStart(5, "div", 3)(6, "mj-filter-popover", 4);
451
+ i0.ɵɵlistener("ClearAllRequested", function ClassifyHistoryTabComponent_Template_mj_filter_popover_ClearAllRequested_6_listener() { return ctx.onHistoryFilterReset(); });
452
+ i0.ɵɵelementStart(7, "mj-filter-panel", 5);
453
+ i0.ɵɵlistener("ValuesChange", function ClassifyHistoryTabComponent_Template_mj_filter_panel_ValuesChange_7_listener($event) { return ctx.onHistoryFilterChange($event); })("Reset", function ClassifyHistoryTabComponent_Template_mj_filter_panel_Reset_7_listener() { return ctx.onHistoryFilterReset(); });
454
+ i0.ɵɵelementEnd()()()();
455
+ i0.ɵɵelementStart(8, "mj-page-body-interior", 6)(9, "div", 7)(10, "div", 8)(11, "div", 9)(12, "div", 10)(13, "table", 11)(14, "thead")(15, "tr")(16, "th");
456
+ i0.ɵɵtext(17, "Status");
457
+ i0.ɵɵelementEnd();
458
+ i0.ɵɵelementStart(18, "th");
459
+ i0.ɵɵtext(19, "Source");
460
+ i0.ɵɵelementEnd();
461
+ i0.ɵɵelementStart(20, "th");
462
+ i0.ɵɵtext(21, "Started");
463
+ i0.ɵɵelementEnd();
464
+ i0.ɵɵelementStart(22, "th");
465
+ i0.ɵɵtext(23, "Duration");
466
+ i0.ɵɵelementEnd();
467
+ i0.ɵɵelementStart(24, "th");
468
+ i0.ɵɵtext(25, "Items");
469
+ i0.ɵɵelementEnd();
470
+ i0.ɵɵelementStart(26, "th");
471
+ i0.ɵɵtext(27, "Tags");
472
+ i0.ɵɵelementEnd();
473
+ i0.ɵɵelementStart(28, "th");
474
+ i0.ɵɵtext(29, "Errors");
475
+ i0.ɵɵelementEnd()()();
476
+ i0.ɵɵelementStart(30, "tbody");
477
+ i0.ɵɵrepeaterCreate(31, ClassifyHistoryTabComponent_For_32_Template, 17, 14, "tr", 12, _forTrack0);
478
+ i0.ɵɵelementEnd()()();
479
+ i0.ɵɵconditionalCreate(33, ClassifyHistoryTabComponent_Conditional_33_Template, 4, 3, "div", 13);
480
+ i0.ɵɵelementEnd();
481
+ i0.ɵɵconditionalCreate(34, ClassifyHistoryTabComponent_Conditional_34_Template, 18, 4, "div", 14);
482
+ i0.ɵɵelementEnd()()();
483
+ } if (rf & 2) {
484
+ i0.ɵɵadvance(2);
485
+ i0.ɵɵproperty("disabled", ctx.IsLoading);
486
+ i0.ɵɵadvance();
487
+ i0.ɵɵconditional(ctx.IsLoading ? 3 : 4);
488
+ i0.ɵɵadvance(3);
489
+ i0.ɵɵproperty("ActiveCount", ctx.historyActiveFilterCount)("ShowClearAll", ctx.historyActiveFilterCount > 0);
490
+ i0.ɵɵadvance();
491
+ i0.ɵɵproperty("Fields", ctx.historyFilterFields)("Values", ctx.historyFilterValues);
492
+ i0.ɵɵadvance();
493
+ i0.ɵɵproperty("Padding", false)("Flex", true);
494
+ i0.ɵɵadvance(23);
495
+ i0.ɵɵrepeater(ctx.FilteredRunRows);
496
+ i0.ɵɵadvance(2);
497
+ i0.ɵɵconditional(ctx.TotalRunCount > 0 ? 33 : -1);
498
+ i0.ɵɵadvance();
499
+ i0.ɵɵconditional(ctx.SelectedRunID ? 34 : -1);
500
+ } }, dependencies: [i1.LoadingComponent, i2.MJButtonDirective, i2.MJPageHeaderInteriorComponent, i2.MJPageBodyInteriorComponent, i2.MJFilterPopoverComponent, i2.MJFilterPanelComponent, i3.ClassifyItemGridComponent], styles: ["\n\n\n\n\n\n\n\n\n\n.at-run-items-section[_ngcontent-%COMP%] {\n margin-top: 16px;\n border-top: 1px solid var(--mj-border-subtle);\n padding-top: 12px;\n}"] });
501
+ }
502
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ClassifyHistoryTabComponent, [{
503
+ type: Component,
504
+ 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 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\u2026</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 <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 @if (TotalRunCount > 0) {\n <div class=\"at-load-more-bar\">\n <span class=\"at-load-more-count\">Showing {{ FilteredRunRows.length }} of {{ TotalRunCount }} runs</span>\n @if (HasMoreRuns) {\n <button mjButton variant=\"secondary\" size=\"sm\" (click)=\"onLoadMore()\" [disabled]=\"IsLoadingMore\">\n @if (IsLoadingMore) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Loading\u2026\n } @else {\n <i class=\"fa-solid fa-chevron-down\"></i> Load more\n }\n </button>\n }\n </div>\n }\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\n <!-- Phase 4: content items processed in this run -->\n <div class=\"at-run-items-section\">\n <div class=\"at-card-header\" style=\"padding-left: 0; padding-right: 0;\">\n <span class=\"at-card-title\">\n <i class=\"fa-solid fa-list-check\"></i> Items in this run\n </span>\n </div>\n <classify-item-grid\n [RunID]=\"SelectedRunID\"\n [Provider]=\"Provider\"\n (ItemSelected)=\"onItemSelected($event)\"></classify-item-grid>\n </div>\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\n.at-run-items-section {\n margin-top: 16px;\n border-top: 1px solid var(--mj-border-subtle);\n padding-top: 12px;\n}\n"] }]
505
+ }], null, { Runs: [{
506
+ type: Input
507
+ }], TotalRunCount: [{
508
+ type: Input
509
+ }], IsLoadingMore: [{
510
+ type: Input
511
+ }], LoadMoreRequested: [{
512
+ type: Output
513
+ }], ItemSelected: [{
514
+ type: Output
515
+ }], RefreshRequested: [{
516
+ type: Output
517
+ }] }); })();
518
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ClassifyHistoryTabComponent, { className: "ClassifyHistoryTabComponent", filePath: "src/AI/components/autotagging/tabs/history-tab.component.ts", lineNumber: 22 }); })();
519
+ //# 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":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAClG,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAGrE,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,aAAa,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;;;;;;;;ICPpI,wBAA2C;IAAC,gCAA8B;IAAA,gCAAW;IAAA,iBAAO;;;IAE5F,wBAAyC;IAAC,gCAA8B;IAAA,uBAAO;IAAA,iBAAO;;;IA4CtE,wBAAsE;;;;IAN9E,8BAEoC;IAAhC,6MAAS,+BAAqB,KAAC;IAE/B,AADF,0BAAI,eAC0D;IAC1D,mGAAqC;IAGrC,YACF;IACF,AADE,iBAAO,EACJ;IACL,8BAA+B;IAAA,YAAoB;IAAA,iBAAK;IACxD,0BAAI;IAAA,YAAwB;IAAA,iBAAK;IACjC,8BAA4B;IAAA,aAAkB;IAAA,iBAAK;IACnD,2BAAI;IAAA,aAAe;IAAA,iBAAK;IACxB,2BAAI;IAAA,aAAc;IAAA,iBAAK;IACvB,2BAA6B;IAAA,aAAgB;IAC/C,AAD+C,iBAAK,EAC/C;;;;IAhBD,yEAAsD;IAGpB,eAAyB;IAAzB,iCAAyB;IACzD,cAEC;IAFD,2DAEC;IACD,cACF;IADE,8CACF;IAE6B,eAAoB;IAApB,uCAAoB;IAC/C,eAAwB;IAAxB,2CAAwB;IACA,eAAkB;IAAlB,qCAAkB;IAC1C,eAAe;IAAf,kCAAe;IACf,eAAc;IAAd,iCAAc;IACd,cAAwB;IAAxB,gCAAwB;IAAC,cAAgB;IAAhB,mCAAgB;;;IAY7C,wBAA2C;IAAC,+BAC9C;;;IACE,wBAAwC;IAAC,2BAC3C;;;;IALF,iCAAiG;IAAlD,+MAAS,mBAAY,KAAC;IAGjE,AAFF,gHAAqB,0FAEZ;IAGX,iBAAS;;;IAN6D,+CAA0B;IAC9F,cAIC;IAJD,8CAIC;;;IAPL,AADF,+BAA8B,eACK;IAAA,YAAgE;IAAA,iBAAO;IACxG,gHAAmB;IASrB,iBAAM;;;IAV6B,eAAgE;IAAhE,uGAAgE;IACjG,cAQC;IARD,6CAQC;;;IAmBC,iCAAoE;;;IAoB5D,AADF,0BAAI,aAC6B;IAAA,YAAuB;IAAA,iBAAK;IAC3D,0BAAI;IAAA,YAAuB;IAAA,iBAAK;IAE9B,AADF,0BAAI,eAC6D;IAAA,YAAmB;IACpF,AADoF,iBAAO,EACtF;IACL,0BAAI;IAAA,YAA2B;IAAA,iBAAK;IACpC,2BAAI;IAAA,aAAwB;IAAA,iBAAK;IACjC,2BAAI;IAAA,aAA4B;IAAA,iBAAK;IACrC,2BAAmD;IAAA,aAAuB;IAAA,iBAAK;IAC/E,2BAAI;IAAA,aAA0C;IAAA,iBAAK;IACnD,2BAAI;IAAA,aAAwE;IAAA,iBAAK;IACjF,+BAA4B;IAAA,aAAqB;IACnD,AADmD,iBAAK,EACnD;;;;IAZ4B,eAAuB;IAAvB,0CAAuB;IAClD,eAAuB;IAAvB,0CAAuB;IAES,eAA4B;IAA5B,oCAA4B;IAAC,cAAmB;IAAnB,sCAAmB;IAEhF,eAA2B;IAA3B,8CAA2B;IAC3B,eAAwB;IAAxB,2CAAwB;IACxB,eAA4B;IAA5B,+CAA4B;IAC5B,cAA8C;IAA9C,0DAA8C;IAAC,cAAuB;IAAvB,0CAAuB;IACtE,eAA0C;IAA1C,oEAA0C;IAC1C,eAAwE;IAAxE,8FAAwE;IAChD,eAAqB;IAArB,wCAAqB;;;IA1BnD,AADF,AADF,AADF,iCAA4B,YACnB,SACD,SACE;IAAA,sBAAM;IAAA,iBAAK;IACf,0BAAI;IAAA,2BAAW;IAAA,iBAAK;IACpB,0BAAI;IAAA,sBAAM;IAAA,iBAAK;IACf,0BAAI;IAAA,sBAAK;IAAA,iBAAK;IACd,2BAAI;IAAA,uBAAM;IAAA,iBAAK;IACf,2BAAI;IAAA,2BAAU;IAAA,iBAAK;IACnB,2BAAI;IAAA,uBAAM;IAAA,iBAAK;IACf,2BAAI;IAAA,uBAAM;IAAA,iBAAK;IACf,2BAAI;IAAA,qBAAI;IAAA,iBAAK;IACb,2BAAI;IAAA,yBAAQ;IAEhB,AADE,AADc,iBAAK,EACd,EACC;IACR,8BAAO;IACL,kIAeC;IAEL,AADE,iBAAQ,EACF;;;IAjBJ,gBAeC;IAfD,mCAeC;;;IAIL,+BAA4B;IAC1B,wBAAuC;IACvC,yBAAG;IAAA,gEAAgD;IACrD,AADqD,iBAAI,EACnD;;;;IAlDR,AADF,AADF,+BAA+C,cACjB,eACE;IAC1B,wBAAkD;IAClD,YACF;IAAA,iBAAO;IACP,kCAAqH;IAA3B,gMAAS,uBAAgB,KAAC;IAClH,wBAAiC;IAAC,uBACpC;IACF,AADE,iBAAS,EACL;IACN,+BAA0B;IAsCtB,AAnCA,AAFF,oHAA0B,4FAEa,yFAmC9B;IAUL,AADF,AADF,gCAAkC,eACuC,gBACzC;IAC1B,yBAAsC;IAAC,oCACzC;IACF,AADE,iBAAO,EACH;IACN,+CAG4C;IAAxC,iOAAgB,6BAAsB,KAAC;IAGjD,AADE,AADE,AAD8C,iBAAqB,EAC7D,EACF,EACF;;;IAhEA,eACF;IADE,iFACF;IAMA,eA0CC;IA1CD,2FA0CC;IAUK,eAAuB;IACvB,AADA,4CAAuB,6BACF;;ADjIvC,MAAM,OAAO,2BAA4B,SAAQ,oBAAoB;IACzD,GAAG,GAAG,MAAM,CAAC,iBAAiB,CAAC,CAAC;IAExC,qFAAqF;IAC7E,KAAK,GAA8B,EAAE,CAAC;IAC9C,IACI,IAAI,CAAC,KAAgC;QACrC,IAAI,CAAC,KAAK,GAAG,KAAK,IAAI,EAAE,CAAC;QACzB,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC3B,IAAI,CAAC,yBAAyB,EAAE,CAAC;QACjC,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACxB,0EAA0E;QAC1E,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACvB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC7B,CAAC;IACD,IAAI,IAAI;QACJ,OAAO,IAAI,CAAC,KAAK,CAAC;IACtB,CAAC;IAED,yFAAyF;IAChF,aAAa,GAAG,CAAC,CAAC;IAE3B,sFAAsF;IAC7E,aAAa,GAAG,KAAK,CAAC;IAE/B,gFAAgF;IACtE,iBAAiB,GAAG,IAAI,YAAY,EAAQ,CAAC;IAEvD;;;OAGG;IACO,YAAY,GAAG,IAAI,YAAY,EAAU,CAAC;IAE7C,cAAc,CAAC,MAAc;QAChC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACnC,CAAC;IAED,mEAAmE;IACnE,IAAW,WAAW;QAClB,OAAO,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;IAClD,CAAC;IAEM,UAAU;QACb,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,CAAC;IAClC,CAAC;IAED,iFAAiF;IAC1E,SAAS,GAAG,KAAK,CAAC;IAEzB;;;;OAIG;IACO,gBAAgB,GAAG,IAAI,YAAY,EAAQ,CAAC;IAE/C,cAAc,GAAoB,EAAE,CAAC;IACrC,eAAe,GAAoB,EAAE,CAAC;IACtC,mBAAmB,GAAG,EAAE,CAAC;IACzB,mBAAmB,GAAG,EAAE,CAAC;IACzB,oBAAoB,GAAa,EAAE,CAAC;IAE3C,uBAAuB;IAChB,aAAa,GAAkB,IAAI,CAAC;IACpC,aAAa,GAAmB,EAAE,CAAC;IACnC,kBAAkB,GAAG,KAAK,CAAC;IAElC,6BAA6B;IACb,gBAAgB,GAAG,gBAAgB,CAAC;IAEpD;;;OAGG;IACI,OAAO;QACV,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QACzB,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC;IACjC,CAAC;IAEO,mBAAmB;QACvB,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;YACvC,MAAM,MAAM,GAAI,GAAG,CAAC,QAAQ,CAAY,IAAI,SAAS,CAAC;YACtD,MAAM,SAAS,GAAG,GAAG,CAAC,WAAW,CAAkB,CAAC;YACpD,MAAM,OAAO,GAAG,GAAG,CAAC,SAAS,CAAkB,CAAC;YAChD,MAAM,QAAQ,GAAG,eAAe,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YACrD,MAAM,cAAc,GAAG,GAAG,CAAC,gBAAgB,CAAkB,CAAC;YAC9D,MAAM,UAAU,GAAG,GAAG,CAAC,YAAY,CAAkB,CAAC;YACtD,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;YACzC,MAAM,QAAQ,GAAG,WAAW,KAAK,OAAO,IAAI,WAAW,KAAK,QAAQ,CAAC;YACrE,MAAM,SAAS,GAAG,WAAW,KAAK,SAAS,IAAI,WAAW,KAAK,YAAY,CAAC;YAC5E,MAAM,SAAS,GAAG,CAAC,UAAU,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;YAExC,OAAO;gBACH,EAAE,EAAE,GAAG,CAAC,IAAI,CAAW;gBACvB,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC;gBAC7B,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU;gBACrE,UAAU,EAAG,GAAG,CAAC,QAAQ,CAAY,IAAI,SAAS;gBAClD,cAAc,EAAE,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG;gBACvD,QAAQ,EAAE,QAAQ;gBAClB,KAAK,EAAE,cAAc,IAAI,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,GAAG;gBAClE,IAAI,EAAE,GAAG;gBACT,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,UAAW,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC;gBACzE,UAAU,EAAE,QAAQ,IAAI,SAAS,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE;aAC5D,CAAC;QACN,CAAC,CAAC,CAAC;IACP,CAAC;IAEO,yBAAyB;QAC7B,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;QAClC,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC3B,MAAM,CAAC,GAAG,GAAG,CAAC,QAAQ,CAAW,CAAC;YAClC,IAAI,CAAC;gBAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC1B,CAAC;QACD,IAAI,CAAC,oBAAoB,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;IAC3D,CAAC;IAEM,gBAAgB;QACnB,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE;YACpD,IAAI,IAAI,CAAC,mBAAmB,IAAI,GAAG,CAAC,UAAU,KAAK,IAAI,CAAC,mBAAmB;gBAAE,OAAO,KAAK,CAAC;YAC1F,IAAI,IAAI,CAAC,mBAAmB,IAAI,GAAG,CAAC,WAAW,KAAK,IAAI,CAAC,mBAAmB;gBAAE,OAAO,KAAK,CAAC;YAC3F,OAAO,IAAI,CAAC;QAChB,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC7B,CAAC;IAED;;;OAGG;IACH,IAAW,mBAAmB;QAC1B,OAAO;YACH;gBACI,GAAG,EAAE,QAAQ;gBACb,IAAI,EAAE,UAAU;gBAChB,KAAK,EAAE,QAAQ;gBACf,WAAW,EAAE,aAAa;gBAC1B,UAAU,EAAE,IAAI,CAAC,oBAAoB,CAAC,MAAM,GAAG,EAAE;gBACjD,OAAO,EAAE;oBACL,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,EAAE,EAAE;oBAClC,GAAG,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;iBACjE;aACJ;YACD;gBACI,GAAG,EAAE,QAAQ;gBACb,IAAI,EAAE,UAAU;gBAChB,KAAK,EAAE,QAAQ;gBACf,WAAW,EAAE,YAAY;gBACzB,OAAO,EAAE;oBACL,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,EAAE,EAAE;oBACjC,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE;oBACvC,EAAE,IAAI,EAAE,QAAQ,EAAI,KAAK,EAAE,QAAQ,EAAE;oBACrC,EAAE,IAAI,EAAE,SAAS,EAAG,KAAK,EAAE,SAAS,EAAE;iBACzC;aACJ;SACJ,CAAC;IACN,CAAC;IAED,IAAW,mBAAmB;QAC1B,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,mBAAmB,EAAE,MAAM,EAAE,IAAI,CAAC,mBAAmB,EAAE,CAAC;IAClF,CAAC;IAED,IAAW,wBAAwB;QAC/B,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACnF,CAAC;IAEM,qBAAqB,CAAC,MAA+B;QACxD,IAAI,CAAC,mBAAmB,GAAI,MAAM,CAAC,QAAQ,CAAY,IAAI,EAAE,CAAC;QAC9D,IAAI,CAAC,mBAAmB,GAAI,MAAM,CAAC,QAAQ,CAAY,IAAI,EAAE,CAAC;QAC9D,IAAI,CAAC,gBAAgB,EAAE,CAAC;IAC5B,CAAC;IAEM,oBAAoB;QACvB,IAAI,CAAC,mBAAmB,GAAG,EAAE,CAAC;QAC9B,IAAI,CAAC,mBAAmB,GAAG,EAAE,CAAC;QAC9B,IAAI,CAAC,gBAAgB,EAAE,CAAC;IAC5B,CAAC;IAED,6FAA6F;IACtF,KAAK,CAAC,aAAa,CAAC,KAAa;QACpC,IAAI,IAAI,CAAC,aAAa,KAAK,KAAK,EAAE,CAAC;YAC/B,IAAI,CAAC,cAAc,EAAE,CAAC;YACtB,OAAO;QACX,CAAC;QACD,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;QAC3B,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;QAC/B,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;QACxB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAEzB,MAAM,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;QAEpC,IAAI,CAAC,kBAAkB,GAAG,KAAK,CAAC;QAChC,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC7B,CAAC;IAEM,cAAc;QACjB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC1B,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;QACxB,IAAI,CAAC,kBAAkB,GAAG,KAAK,CAAC;QAChC,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC7B,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAAC,KAAa;QACzC,MAAM,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC5D,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC;YAC5B,UAAU,EAAE,iCAAiC;YAC7C,WAAW,EAAE,wBAAwB,KAAK,GAAG;YAC7C,OAAO,EAAE,eAAe;YACxB,UAAU,EAAE,QAAQ;SACvB,CAAC,CAAC;QACH,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACjB,IAAI,CAAC,aAAa,GAAG,mBAAmB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC7D,CAAC;IACL,CAAC;yRAtNQ,2BAA2B,yBAA3B,2BAA2B;6DAA3B,2BAA2B;YCjBpC,AADF,AAHF,kDAEoE,aACrD,gBAC+E;YAA3C,wGAAS,aAAS,IAAC;YAG9D,AAFF,mFAAiB,6DAER;YAIb,AADE,iBAAS,EACL;YAEJ,AADF,8BAAa,2BAIsC;YAA7C,2IAAqB,0BAAsB,IAAC;YAC9C,0CAIqC;YAAjC,AADA,qIAAgB,iCAA6B,IAAC,oGACrC,0BAAsB,IAAC;YAI1C,AADE,AADE,AADE,iBAAkB,EACA,EAChB,EACkB;YAUV,AADF,AADF,AADF,AADF,AADF,AADF,AADF,AADF,gDAAuD,aAC3B,cACE,cACH,eACoD,iBACzC,aACnB,UACD,UACE;YAAA,uBAAM;YAAA,iBAAK;YACf,2BAAI;YAAA,uBAAM;YAAA,iBAAK;YACf,2BAAI;YAAA,wBAAO;YAAA,iBAAK;YAChB,2BAAI;YAAA,yBAAQ;YAAA,iBAAK;YACjB,2BAAI;YAAA,sBAAK;YAAA,iBAAK;YACd,2BAAI;YAAA,qBAAI;YAAA,iBAAK;YACb,2BAAI;YAAA,uBAAM;YAEd,AADE,AADY,iBAAK,EACZ,EACC;YACR,8BAAO;YACL,kGAmBC;YAGP,AADE,AADE,iBAAQ,EACF,EACJ;YACN,gGAAyB;YAc3B,iBAAM;YAGN,iGAAqB;YAyE3B,AADE,AADE,iBAAM,EACF,EACgB;;YA1J+C,eAAsB;YAAtB,wCAAsB;YACvF,cAIC;YAJD,uCAIC;YAKC,eAAwC;YACxC,AADA,0DAAwC,kDACK;YAG3C,cAA8B;YAC9B,AADA,gDAA8B,mCACA;YAQjB,cAAiB;YAAC,AAAlB,+BAAiB,cAAc;YAkBxC,gBAmBC;YAnBD,kCAmBC;YAIP,eAaC;YAbD,iDAaC;YAIH,cAsEC;YAtED,6CAsEC;;;iFDtIM,2BAA2B;cANvC,SAAS;6BACM,KAAK,YACP,sBAAsB;;kBAS/B,KAAK;;kBAeL,KAAK;;kBAGL,KAAK;;kBAGL,MAAM;;kBAMN,MAAM;;kBAuBN,MAAM;;kFAvDE,2BAA2B","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, EventEmitter, Input, Output, 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 // A fresh Runs binding (from the host reload) ends any in-flight refresh.\n this.IsLoading = false;\n this.cdr.detectChanges();\n }\n get Runs(): Record<string, unknown>[] {\n return this._runs;\n }\n\n /** Total run count in the DB (from TotalRowCount) — drives the \"Showing X of Y\" line. */\n @Input() TotalRunCount = 0;\n\n /** True while the host is fetching the next page in response to LoadMoreRequested. */\n @Input() IsLoadingMore = false;\n\n /** Bubble a \"load more\" request to the host, which widens the loaded window. */\n @Output() LoadMoreRequested = new EventEmitter<void>();\n\n /**\n * Bubble a content-item selection (from the per-run item grid) up to the host,\n * which owns NavigationService + the drilldown slide-in.\n */\n @Output() ItemSelected = new EventEmitter<string>();\n\n public onItemSelected(itemID: string): void {\n this.ItemSelected.emit(itemID);\n }\n\n /** Whether more runs exist in the DB than are currently loaded. */\n public get HasMoreRuns(): boolean {\n return this.TotalRunCount > this._runs.length;\n }\n\n public onLoadMore(): void {\n this.LoadMoreRequested.emit();\n }\n\n /** Shown while the host reloads the run list in response to RefreshRequested. */\n public IsLoading = false;\n\n /**\n * Bubble a refresh request up to the host, which owns the run-history data\n * (`MJ: Content Process Runs`). The host reloads and re-binds `[Runs]`, whose\n * setter rebuilds the rows; the host also clears IsLoading via [Loading].\n */\n @Output() RefreshRequested = new EventEmitter<void>();\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 /**\n * Ask the host to reload the run history. Data is host-owned, so we surface a\n * loading state and emit; the new `[Runs]` binding clears IsLoading.\n */\n public Refresh(): void {\n this.IsLoading = true;\n this.cdr.detectChanges();\n this.RefreshRequested.emit();\n }\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 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 <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 @if (TotalRunCount > 0) {\n <div class=\"at-load-more-bar\">\n <span class=\"at-load-more-count\">Showing {{ FilteredRunRows.length }} of {{ TotalRunCount }} runs</span>\n @if (HasMoreRuns) {\n <button mjButton variant=\"secondary\" size=\"sm\" (click)=\"onLoadMore()\" [disabled]=\"IsLoadingMore\">\n @if (IsLoadingMore) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Loading…\n } @else {\n <i class=\"fa-solid fa-chevron-down\"></i> Load more\n }\n </button>\n }\n </div>\n }\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\n <!-- Phase 4: content items processed in this run -->\n <div class=\"at-run-items-section\">\n <div class=\"at-card-header\" style=\"padding-left: 0; padding-right: 0;\">\n <span class=\"at-card-title\">\n <i class=\"fa-solid fa-list-check\"></i> Items in this run\n </span>\n </div>\n <classify-item-grid\n [RunID]=\"SelectedRunID\"\n [Provider]=\"Provider\"\n (ItemSelected)=\"onItemSelected($event)\"></classify-item-grid>\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n</mj-page-body-interior>\n"]}