@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,1465 @@
1
+ /**
2
+ * @fileoverview Classify · Content Sources tab.
3
+ *
4
+ * Self-contained sub-page: owns its header-interior, the source cards grid,
5
+ * the per-source detail slide-in, and the quick-schedule dialog. Receives the
6
+ * shared raw data needed to build the cards (sources, items, tags, runs, and
7
+ * the cached ScheduledAction + EntityRecordDocument lookups) from the host
8
+ * orchestrator via `@Input()`. Cross-tab concerns — opening the add/edit slide-in
9
+ * form, running the pipeline, opening a content-item detail, and reloading the
10
+ * shared source list after a mutation — bubble up via `@Output()`.
11
+ *
12
+ * Out of scope (stays in the host): the add/edit source slide-in FORM, the
13
+ * pipeline tab, and the Content Duplicates section.
14
+ */
15
+ import { Component, ChangeDetectorRef, EventEmitter, Input, Output, inject } from '@angular/core';
16
+ import { CompositeKey, RunView } from '@memberjunction/core';
17
+ import { UUIDsEqual, NormalizeUUID } from '@memberjunction/global';
18
+ import { BaseAngularComponent } from '@memberjunction/ng-base-types';
19
+ import { MJNotificationService } from '@memberjunction/ng-notifications';
20
+ import { AIEngineBase } from '@memberjunction/ai-engine-base';
21
+ import { KnowledgeHubMetadataEngine } from '@memberjunction/core-entities';
22
+ import { formatNumber, formatDate, computeDuration, displayStatus, getSourceTypeIcon, CronToHumanReadable, deriveDisplayName } from '../shared/classify.format';
23
+ import * as i0 from "@angular/core";
24
+ import * as i1 from "@angular/forms";
25
+ import * as i2 from "@memberjunction/ng-shared-generic";
26
+ import * as i3 from "@memberjunction/ng-ui-components";
27
+ import * as i4 from "../dialogs/dry-run-preview.dialog.component";
28
+ import * as i5 from "@angular/common";
29
+ const _forTrack0 = ($index, $item) => $item.ID;
30
+ function ClassifySourcesTabComponent_Conditional_3_Template(rf, ctx) { if (rf & 1) {
31
+ i0.ɵɵelement(0, "i", 21);
32
+ i0.ɵɵelementStart(1, "span", 5);
33
+ i0.ɵɵtext(2, "Refreshing\u2026");
34
+ i0.ɵɵelementEnd();
35
+ } }
36
+ function ClassifySourcesTabComponent_Conditional_4_Template(rf, ctx) { if (rf & 1) {
37
+ i0.ɵɵelement(0, "i", 22);
38
+ i0.ɵɵelementStart(1, "span", 5);
39
+ i0.ɵɵtext(2, "Refresh");
40
+ i0.ɵɵelementEnd();
41
+ } }
42
+ function ClassifySourcesTabComponent_Conditional_15_Template(rf, ctx) { if (rf & 1) {
43
+ i0.ɵɵelementStart(0, "div", 10);
44
+ i0.ɵɵelement(1, "mj-loading", 23);
45
+ i0.ɵɵelementEnd();
46
+ } }
47
+ function ClassifySourcesTabComponent_Conditional_17_Template(rf, ctx) { if (rf & 1) {
48
+ const _r1 = i0.ɵɵgetCurrentView();
49
+ i0.ɵɵelementStart(0, "div", 12);
50
+ i0.ɵɵelement(1, "i", 24);
51
+ i0.ɵɵelementStart(2, "h3");
52
+ i0.ɵɵtext(3, "No content sources yet");
53
+ i0.ɵɵelementEnd();
54
+ i0.ɵɵelementStart(4, "p");
55
+ i0.ɵɵtext(5, "Use the guided setup to stand up your first source \u2014 pick an entity or URL, configure its document, taxonomy, and domain context in one flow.");
56
+ i0.ɵɵelementEnd();
57
+ i0.ɵɵelementStart(6, "div", 25)(7, "button", 6);
58
+ i0.ɵɵlistener("click", function ClassifySourcesTabComponent_Conditional_17_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onAddSourceGuided()); });
59
+ i0.ɵɵelement(8, "i", 4);
60
+ i0.ɵɵtext(9, " Add Source (Guided) ");
61
+ i0.ɵɵelementEnd();
62
+ i0.ɵɵelementStart(10, "button", 3);
63
+ i0.ɵɵlistener("click", function ClassifySourcesTabComponent_Conditional_17_Template_button_click_10_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onAddSource()); });
64
+ i0.ɵɵelement(11, "i", 7);
65
+ i0.ɵɵtext(12, " Add manually ");
66
+ i0.ɵɵelementEnd()()();
67
+ } }
68
+ function ClassifySourcesTabComponent_For_20_Conditional_9_Template(rf, ctx) { if (rf & 1) {
69
+ i0.ɵɵtext(0);
70
+ } if (rf & 2) {
71
+ const card_r4 = i0.ɵɵnextContext().$implicit;
72
+ i0.ɵɵtextInterpolate1(" \u00B7 ", card_r4.FileTypeName);
73
+ } }
74
+ function ClassifySourcesTabComponent_For_20_Conditional_13_Template(rf, ctx) { if (rf & 1) {
75
+ i0.ɵɵelementStart(0, "div", 33);
76
+ i0.ɵɵtext(1);
77
+ i0.ɵɵelementEnd();
78
+ } if (rf & 2) {
79
+ const card_r4 = i0.ɵɵnextContext().$implicit;
80
+ i0.ɵɵadvance();
81
+ i0.ɵɵtextInterpolate(card_r4.URL);
82
+ } }
83
+ function ClassifySourcesTabComponent_For_20_Conditional_35_Template(rf, ctx) { if (rf & 1) {
84
+ const _r5 = i0.ɵɵgetCurrentView();
85
+ i0.ɵɵelementStart(0, "div", 47);
86
+ i0.ɵɵlistener("click", function ClassifySourcesTabComponent_For_20_Conditional_35_Template_div_click_0_listener($event) { i0.ɵɵrestoreView(_r5); const card_r4 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(); ctx_r1.RemoveSchedule(card_r4); return i0.ɵɵresetView($event.stopPropagation()); });
87
+ i0.ɵɵelement(1, "i", 48);
88
+ i0.ɵɵelementStart(2, "span");
89
+ i0.ɵɵtext(3);
90
+ i0.ɵɵelementEnd()();
91
+ } if (rf & 2) {
92
+ const card_r4 = i0.ɵɵnextContext().$implicit;
93
+ const ctx_r1 = i0.ɵɵnextContext();
94
+ i0.ɵɵadvance(3);
95
+ i0.ɵɵtextInterpolate(ctx_r1.GetScheduleLabel(card_r4));
96
+ } }
97
+ function ClassifySourcesTabComponent_For_20_Conditional_46_Template(rf, ctx) { if (rf & 1) {
98
+ const _r6 = i0.ɵɵgetCurrentView();
99
+ i0.ɵɵelementStart(0, "button", 49);
100
+ i0.ɵɵlistener("click", function ClassifySourcesTabComponent_For_20_Conditional_46_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r6); const card_r4 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(); ctx_r1.OpenScheduleDialog(card_r4); return i0.ɵɵresetView($event.stopPropagation()); });
101
+ i0.ɵɵelement(1, "i", 48);
102
+ i0.ɵɵtext(2, " Schedule");
103
+ i0.ɵɵelementEnd();
104
+ } }
105
+ function ClassifySourcesTabComponent_For_20_Template(rf, ctx) { if (rf & 1) {
106
+ const _r3 = i0.ɵɵgetCurrentView();
107
+ i0.ɵɵelementStart(0, "div", 26);
108
+ i0.ɵɵlistener("click", function ClassifySourcesTabComponent_For_20_Template_div_click_0_listener() { const card_r4 = i0.ɵɵrestoreView(_r3).$implicit; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OpenSourceDetail(card_r4)); });
109
+ i0.ɵɵelementStart(1, "div", 27)(2, "div", 28);
110
+ i0.ɵɵelement(3, "i");
111
+ i0.ɵɵelementEnd();
112
+ i0.ɵɵelementStart(4, "div")(5, "div", 29);
113
+ i0.ɵɵtext(6);
114
+ i0.ɵɵelementEnd();
115
+ i0.ɵɵelementStart(7, "div", 30);
116
+ i0.ɵɵtext(8);
117
+ i0.ɵɵconditionalCreate(9, ClassifySourcesTabComponent_For_20_Conditional_9_Template, 1, 1);
118
+ i0.ɵɵelementEnd()();
119
+ i0.ɵɵelementStart(10, "div", 31);
120
+ i0.ɵɵelement(11, "div", 32);
121
+ i0.ɵɵtext(12);
122
+ i0.ɵɵelementEnd()();
123
+ i0.ɵɵconditionalCreate(13, ClassifySourcesTabComponent_For_20_Conditional_13_Template, 2, 1, "div", 33);
124
+ i0.ɵɵelementStart(14, "div", 34)(15, "div", 35)(16, "div", 36);
125
+ i0.ɵɵtext(17);
126
+ i0.ɵɵelementEnd();
127
+ i0.ɵɵelementStart(18, "div", 37);
128
+ i0.ɵɵtext(19, "Items");
129
+ i0.ɵɵelementEnd()();
130
+ i0.ɵɵelementStart(20, "div", 35)(21, "div", 36);
131
+ i0.ɵɵtext(22);
132
+ i0.ɵɵelementEnd();
133
+ i0.ɵɵelementStart(23, "div", 37);
134
+ i0.ɵɵtext(24, "Tags");
135
+ i0.ɵɵelementEnd()();
136
+ i0.ɵɵelementStart(25, "div", 35)(26, "div", 36);
137
+ i0.ɵɵtext(27);
138
+ i0.ɵɵelementEnd();
139
+ i0.ɵɵelementStart(28, "div", 37);
140
+ i0.ɵɵtext(29, "Avg Tags");
141
+ i0.ɵɵelementEnd()();
142
+ i0.ɵɵelementStart(30, "div", 35)(31, "div", 36);
143
+ i0.ɵɵtext(32);
144
+ i0.ɵɵelementEnd();
145
+ i0.ɵɵelementStart(33, "div", 37);
146
+ i0.ɵɵtext(34, "Last Run");
147
+ i0.ɵɵelementEnd()()();
148
+ i0.ɵɵconditionalCreate(35, ClassifySourcesTabComponent_For_20_Conditional_35_Template, 4, 1, "div", 38);
149
+ i0.ɵɵelementStart(36, "div", 39)(37, "button", 40);
150
+ i0.ɵɵlistener("click", function ClassifySourcesTabComponent_For_20_Template_button_click_37_listener($event) { const card_r4 = i0.ɵɵrestoreView(_r3).$implicit; const ctx_r1 = i0.ɵɵnextContext(); ctx_r1.onEditSource(card_r4); return i0.ɵɵresetView($event.stopPropagation()); });
151
+ i0.ɵɵelement(38, "i", 41);
152
+ i0.ɵɵtext(39, " Edit");
153
+ i0.ɵɵelementEnd();
154
+ i0.ɵɵelementStart(40, "button", 40);
155
+ i0.ɵɵlistener("click", function ClassifySourcesTabComponent_For_20_Template_button_click_40_listener($event) { const card_r4 = i0.ɵɵrestoreView(_r3).$implicit; const ctx_r1 = i0.ɵɵnextContext(); ctx_r1.onRunSource(card_r4.ID); return i0.ɵɵresetView($event.stopPropagation()); });
156
+ i0.ɵɵelement(41, "i", 42);
157
+ i0.ɵɵtext(42, " Run");
158
+ i0.ɵɵelementEnd();
159
+ i0.ɵɵelementStart(43, "button", 40);
160
+ i0.ɵɵlistener("click", function ClassifySourcesTabComponent_For_20_Template_button_click_43_listener($event) { const card_r4 = i0.ɵɵrestoreView(_r3).$implicit; const ctx_r1 = i0.ɵɵnextContext(); ctx_r1.OpenDryRunPreview(card_r4); return i0.ɵɵresetView($event.stopPropagation()); });
161
+ i0.ɵɵelement(44, "i", 43);
162
+ i0.ɵɵtext(45, " Preview");
163
+ i0.ɵɵelementEnd();
164
+ i0.ɵɵconditionalCreate(46, ClassifySourcesTabComponent_For_20_Conditional_46_Template, 3, 0, "button", 44);
165
+ i0.ɵɵelementStart(47, "button", 45);
166
+ i0.ɵɵlistener("click", function ClassifySourcesTabComponent_For_20_Template_button_click_47_listener($event) { const card_r4 = i0.ɵɵrestoreView(_r3).$implicit; const ctx_r1 = i0.ɵɵnextContext(); ctx_r1.DeleteSource(card_r4); return i0.ɵɵresetView($event.stopPropagation()); });
167
+ i0.ɵɵelement(48, "i", 46);
168
+ i0.ɵɵtext(49, " Delete");
169
+ i0.ɵɵelementEnd()()();
170
+ } if (rf & 2) {
171
+ const card_r4 = ctx.$implicit;
172
+ const ctx_r1 = i0.ɵɵnextContext();
173
+ i0.ɵɵadvance(3);
174
+ i0.ɵɵclassMap(card_r4.Icon);
175
+ i0.ɵɵadvance(3);
176
+ i0.ɵɵtextInterpolate(card_r4.Name);
177
+ i0.ɵɵadvance(2);
178
+ i0.ɵɵtextInterpolate(card_r4.SourceTypeName);
179
+ i0.ɵɵadvance();
180
+ i0.ɵɵconditional(card_r4.RequiresFileType ? 9 : -1);
181
+ i0.ɵɵadvance();
182
+ i0.ɵɵclassMap(card_r4.StatusClass);
183
+ i0.ɵɵadvance();
184
+ i0.ɵɵclassMap(card_r4.StatusClass);
185
+ i0.ɵɵadvance();
186
+ i0.ɵɵtextInterpolate1(" ", card_r4.StatusLabel, " ");
187
+ i0.ɵɵadvance();
188
+ i0.ɵɵconditional(card_r4.URL ? 13 : -1);
189
+ i0.ɵɵadvance(4);
190
+ i0.ɵɵtextInterpolate(ctx_r1.formatNumber(card_r4.ItemCount));
191
+ i0.ɵɵadvance(5);
192
+ i0.ɵɵtextInterpolate(ctx_r1.formatNumber(card_r4.TagCount));
193
+ i0.ɵɵadvance(5);
194
+ i0.ɵɵtextInterpolate(card_r4.AvgTags);
195
+ i0.ɵɵadvance(5);
196
+ i0.ɵɵtextInterpolate(card_r4.LastRunAgo);
197
+ i0.ɵɵadvance(3);
198
+ i0.ɵɵconditional(card_r4.ScheduledActionID ? 35 : -1);
199
+ i0.ɵɵadvance(11);
200
+ i0.ɵɵconditional(!card_r4.ScheduledActionID ? 46 : -1);
201
+ } }
202
+ function ClassifySourcesTabComponent_Conditional_27_Conditional_9_Template(rf, ctx) { if (rf & 1) {
203
+ i0.ɵɵelementStart(0, "div", 10);
204
+ i0.ɵɵelement(1, "mj-loading", 56);
205
+ i0.ɵɵelementEnd();
206
+ } }
207
+ function ClassifySourcesTabComponent_Conditional_27_Conditional_10_Conditional_15_Template(rf, ctx) { if (rf & 1) {
208
+ i0.ɵɵelementStart(0, "div", 65)(1, "span", 66);
209
+ i0.ɵɵtext(2, "URL");
210
+ i0.ɵɵelementEnd();
211
+ i0.ɵɵelementStart(3, "a", 86);
212
+ i0.ɵɵtext(4);
213
+ i0.ɵɵelementEnd()();
214
+ } if (rf & 2) {
215
+ const ctx_r1 = i0.ɵɵnextContext(3);
216
+ i0.ɵɵadvance(3);
217
+ i0.ɵɵproperty("href", ctx_r1.SelectedSource.URL, i0.ɵɵsanitizeUrl);
218
+ i0.ɵɵadvance();
219
+ i0.ɵɵtextInterpolate(ctx_r1.SelectedSource.URL);
220
+ } }
221
+ function ClassifySourcesTabComponent_Conditional_27_Conditional_10_Conditional_16_Template(rf, ctx) { if (rf & 1) {
222
+ i0.ɵɵelementStart(0, "div", 65)(1, "span", 66);
223
+ i0.ɵɵtext(2, "Content Type");
224
+ i0.ɵɵelementEnd();
225
+ i0.ɵɵelementStart(3, "span", 67);
226
+ i0.ɵɵtext(4);
227
+ i0.ɵɵelementEnd()();
228
+ i0.ɵɵelementStart(5, "div", 65)(6, "span", 66);
229
+ i0.ɵɵtext(7, "File Type");
230
+ i0.ɵɵelementEnd();
231
+ i0.ɵɵelementStart(8, "span", 67);
232
+ i0.ɵɵtext(9);
233
+ i0.ɵɵelementEnd()();
234
+ } if (rf & 2) {
235
+ const ctx_r1 = i0.ɵɵnextContext(3);
236
+ i0.ɵɵadvance(4);
237
+ i0.ɵɵtextInterpolate(ctx_r1.SelectedSource.ContentTypeName);
238
+ i0.ɵɵadvance(5);
239
+ i0.ɵɵtextInterpolate(ctx_r1.SelectedSource.FileTypeName);
240
+ } }
241
+ function ClassifySourcesTabComponent_Conditional_27_Conditional_10_For_64_Template(rf, ctx) { if (rf & 1) {
242
+ i0.ɵɵelementStart(0, "option", 75);
243
+ i0.ɵɵtext(1);
244
+ i0.ɵɵelementEnd();
245
+ } if (rf & 2) {
246
+ const opt_r9 = ctx.$implicit;
247
+ i0.ɵɵproperty("value", opt_r9);
248
+ i0.ɵɵadvance();
249
+ i0.ɵɵtextInterpolate(opt_r9);
250
+ } }
251
+ function ClassifySourcesTabComponent_Conditional_27_Conditional_10_Conditional_69_Template(rf, ctx) { if (rf & 1) {
252
+ i0.ɵɵelementStart(0, "div", 79)(1, "p");
253
+ i0.ɵɵtext(2);
254
+ i0.ɵɵelementEnd()();
255
+ } if (rf & 2) {
256
+ const ctx_r1 = i0.ɵɵnextContext(3);
257
+ i0.ɵɵadvance(2);
258
+ i0.ɵɵtextInterpolate(ctx_r1.SourceDetailStatusFilter === "All" ? "No content items yet." : "No items match this filter.");
259
+ } }
260
+ function ClassifySourcesTabComponent_Conditional_27_Conditional_10_For_71_Template(rf, ctx) { if (rf & 1) {
261
+ const _r10 = i0.ɵɵgetCurrentView();
262
+ i0.ɵɵelementStart(0, "div", 87);
263
+ i0.ɵɵlistener("click", function ClassifySourcesTabComponent_Conditional_27_Conditional_10_For_71_Template_div_click_0_listener() { const ci_r11 = i0.ɵɵrestoreView(_r10).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OpenContentItemDetail(ci_r11)); });
264
+ i0.ɵɵelement(1, "div", 88);
265
+ i0.ɵɵelementStart(2, "span", 89);
266
+ i0.ɵɵtext(3);
267
+ i0.ɵɵelementEnd();
268
+ i0.ɵɵelementStart(4, "span", 90);
269
+ i0.ɵɵtext(5);
270
+ i0.ɵɵelementEnd();
271
+ i0.ɵɵelementStart(6, "span", 90);
272
+ i0.ɵɵtext(7);
273
+ i0.ɵɵelementEnd();
274
+ i0.ɵɵelementStart(8, "span", 91);
275
+ i0.ɵɵtext(9);
276
+ i0.ɵɵelementEnd();
277
+ i0.ɵɵelementStart(10, "span", 92);
278
+ i0.ɵɵtext(11);
279
+ i0.ɵɵelementEnd()();
280
+ } if (rf & 2) {
281
+ const ci_r11 = ctx.$implicit;
282
+ const ctx_r1 = i0.ɵɵnextContext(3);
283
+ i0.ɵɵadvance();
284
+ i0.ɵɵclassMap(ci_r11.StatusDot);
285
+ i0.ɵɵadvance(2);
286
+ i0.ɵɵtextInterpolate(ci_r11.Name);
287
+ i0.ɵɵadvance();
288
+ i0.ɵɵclassMap(ctx_r1.GetStatusBadgeClass(ci_r11.EmbeddingStatus));
289
+ i0.ɵɵadvance();
290
+ i0.ɵɵtextInterpolate1("E:", ci_r11.EmbeddingStatus);
291
+ i0.ɵɵadvance();
292
+ i0.ɵɵclassMap(ctx_r1.GetStatusBadgeClass(ci_r11.TaggingStatus));
293
+ i0.ɵɵadvance();
294
+ i0.ɵɵtextInterpolate1("T:", ci_r11.TaggingStatus);
295
+ i0.ɵɵadvance(2);
296
+ i0.ɵɵtextInterpolate1("", ci_r11.TagCount, " tags");
297
+ i0.ɵɵadvance(2);
298
+ i0.ɵɵtextInterpolate(ci_r11.UpdatedAt);
299
+ } }
300
+ function ClassifySourcesTabComponent_Conditional_27_Conditional_10_Conditional_72_Template(rf, ctx) { if (rf & 1) {
301
+ const _r12 = i0.ɵɵgetCurrentView();
302
+ i0.ɵɵelementStart(0, "div", 81)(1, "button", 93);
303
+ i0.ɵɵlistener("click", function ClassifySourcesTabComponent_Conditional_27_Conditional_10_Conditional_72_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r12); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.SourceDetailPrevPage()); });
304
+ i0.ɵɵelement(2, "i", 94);
305
+ i0.ɵɵtext(3, " Prev ");
306
+ i0.ɵɵelementEnd();
307
+ i0.ɵɵelementStart(4, "span", 95);
308
+ i0.ɵɵtext(5);
309
+ i0.ɵɵelementEnd();
310
+ i0.ɵɵelementStart(6, "button", 93);
311
+ i0.ɵɵlistener("click", function ClassifySourcesTabComponent_Conditional_27_Conditional_10_Conditional_72_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r12); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.SourceDetailNextPage()); });
312
+ i0.ɵɵtext(7, " Next ");
313
+ i0.ɵɵelement(8, "i", 96);
314
+ i0.ɵɵelementEnd()();
315
+ } if (rf & 2) {
316
+ const ctx_r1 = i0.ɵɵnextContext(3);
317
+ i0.ɵɵadvance();
318
+ i0.ɵɵproperty("disabled", ctx_r1.SourceDetailPage === 0);
319
+ i0.ɵɵadvance(4);
320
+ i0.ɵɵtextInterpolate2("Page ", ctx_r1.SourceDetailPage + 1, " of ", ctx_r1.SourceDetailTotalPages);
321
+ i0.ɵɵadvance();
322
+ i0.ɵɵproperty("disabled", ctx_r1.SourceDetailPage >= ctx_r1.SourceDetailTotalPages - 1);
323
+ } }
324
+ function ClassifySourcesTabComponent_Conditional_27_Conditional_10_Conditional_73_For_5_Template(rf, ctx) { if (rf & 1) {
325
+ i0.ɵɵelementStart(0, "div", 98)(1, "span", 99);
326
+ i0.ɵɵtext(2);
327
+ i0.ɵɵelementEnd();
328
+ i0.ɵɵelementStart(3, "span", 100);
329
+ i0.ɵɵtext(4);
330
+ i0.ɵɵelementEnd();
331
+ i0.ɵɵelementStart(5, "span", 101);
332
+ i0.ɵɵtext(6);
333
+ i0.ɵɵelementEnd();
334
+ i0.ɵɵelementStart(7, "span", 102);
335
+ i0.ɵɵtext(8);
336
+ i0.ɵɵelementEnd()();
337
+ } if (rf & 2) {
338
+ const run_r13 = ctx.$implicit;
339
+ i0.ɵɵadvance();
340
+ i0.ɵɵclassMap(run_r13.StatusClass);
341
+ i0.ɵɵadvance();
342
+ i0.ɵɵtextInterpolate(run_r13.Status);
343
+ i0.ɵɵadvance(2);
344
+ i0.ɵɵtextInterpolate(run_r13.StartedDisplay);
345
+ i0.ɵɵadvance(2);
346
+ i0.ɵɵtextInterpolate(run_r13.Duration);
347
+ i0.ɵɵadvance(2);
348
+ i0.ɵɵtextInterpolate1("", run_r13.Items, " items");
349
+ } }
350
+ function ClassifySourcesTabComponent_Conditional_27_Conditional_10_Conditional_73_Template(rf, ctx) { if (rf & 1) {
351
+ i0.ɵɵelementStart(0, "div", 62)(1, "div", 63);
352
+ i0.ɵɵtext(2, "Recent Runs");
353
+ i0.ɵɵelementEnd();
354
+ i0.ɵɵelementStart(3, "div", 97);
355
+ i0.ɵɵrepeaterCreate(4, ClassifySourcesTabComponent_Conditional_27_Conditional_10_Conditional_73_For_5_Template, 9, 6, "div", 98, _forTrack0);
356
+ i0.ɵɵelementEnd()();
357
+ } if (rf & 2) {
358
+ const ctx_r1 = i0.ɵɵnextContext(3);
359
+ i0.ɵɵadvance(4);
360
+ i0.ɵɵrepeater(ctx_r1.SelectedSource.RunHistory);
361
+ } }
362
+ function ClassifySourcesTabComponent_Conditional_27_Conditional_10_Template(rf, ctx) { if (rf & 1) {
363
+ const _r8 = i0.ɵɵgetCurrentView();
364
+ i0.ɵɵelementStart(0, "div", 57)(1, "div", 28);
365
+ i0.ɵɵelement(2, "i");
366
+ i0.ɵɵelementEnd();
367
+ i0.ɵɵelementStart(3, "div")(4, "h4", 58);
368
+ i0.ɵɵtext(5);
369
+ i0.ɵɵelementEnd();
370
+ i0.ɵɵelementStart(6, "div", 59)(7, "span", 60);
371
+ i0.ɵɵtext(8);
372
+ i0.ɵɵelementEnd();
373
+ i0.ɵɵelementStart(9, "span", 61);
374
+ i0.ɵɵtext(10);
375
+ i0.ɵɵelementEnd()()()();
376
+ i0.ɵɵelementStart(11, "div", 62)(12, "div", 63);
377
+ i0.ɵɵtext(13, "Configuration");
378
+ i0.ɵɵelementEnd();
379
+ i0.ɵɵelementStart(14, "div", 64);
380
+ i0.ɵɵconditionalCreate(15, ClassifySourcesTabComponent_Conditional_27_Conditional_10_Conditional_15_Template, 5, 2, "div", 65);
381
+ i0.ɵɵconditionalCreate(16, ClassifySourcesTabComponent_Conditional_27_Conditional_10_Conditional_16_Template, 10, 2);
382
+ i0.ɵɵelementStart(17, "div", 65)(18, "span", 66);
383
+ i0.ɵɵtext(19, "Embedding Model");
384
+ i0.ɵɵelementEnd();
385
+ i0.ɵɵelementStart(20, "span", 67);
386
+ i0.ɵɵtext(21);
387
+ i0.ɵɵelementEnd()();
388
+ i0.ɵɵelementStart(22, "div", 65)(23, "span", 66);
389
+ i0.ɵɵtext(24, "Vector Index");
390
+ i0.ɵɵelementEnd();
391
+ i0.ɵɵelementStart(25, "span", 67);
392
+ i0.ɵɵtext(26);
393
+ i0.ɵɵelementEnd()()()();
394
+ i0.ɵɵelementStart(27, "div", 62)(28, "div", 63);
395
+ i0.ɵɵtext(29, "Statistics");
396
+ i0.ɵɵelementEnd();
397
+ i0.ɵɵelementStart(30, "div", 68)(31, "div", 69)(32, "div", 70);
398
+ i0.ɵɵtext(33);
399
+ i0.ɵɵelementEnd();
400
+ i0.ɵɵelementStart(34, "div", 71);
401
+ i0.ɵɵtext(35, "Items");
402
+ i0.ɵɵelementEnd()();
403
+ i0.ɵɵelementStart(36, "div", 69)(37, "div", 70);
404
+ i0.ɵɵtext(38);
405
+ i0.ɵɵelementEnd();
406
+ i0.ɵɵelementStart(39, "div", 71);
407
+ i0.ɵɵtext(40, "Tags");
408
+ i0.ɵɵelementEnd()();
409
+ i0.ɵɵelementStart(41, "div", 69)(42, "div", 70);
410
+ i0.ɵɵtext(43);
411
+ i0.ɵɵelementEnd();
412
+ i0.ɵɵelementStart(44, "div", 71);
413
+ i0.ɵɵtext(45, "Avg Tags");
414
+ i0.ɵɵelementEnd()();
415
+ i0.ɵɵelementStart(46, "div", 69)(47, "div", 70);
416
+ i0.ɵɵtext(48);
417
+ i0.ɵɵelementEnd();
418
+ i0.ɵɵelementStart(49, "div", 71);
419
+ i0.ɵɵtext(50, "Last Run");
420
+ i0.ɵɵelementEnd()();
421
+ i0.ɵɵelementStart(51, "div", 69)(52, "div", 70);
422
+ i0.ɵɵtext(53);
423
+ i0.ɵɵelementEnd();
424
+ i0.ɵɵelementStart(54, "div", 71);
425
+ i0.ɵɵtext(55, "Errors");
426
+ i0.ɵɵelementEnd()()()();
427
+ i0.ɵɵelementStart(56, "div", 62)(57, "div", 72)(58, "div", 63);
428
+ i0.ɵɵtext(59);
429
+ i0.ɵɵpipe(60, "number");
430
+ i0.ɵɵelementEnd();
431
+ i0.ɵɵelementStart(61, "div", 73)(62, "select", 74);
432
+ i0.ɵɵtwoWayListener("ngModelChange", function ClassifySourcesTabComponent_Conditional_27_Conditional_10_Template_select_ngModelChange_62_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r1.SourceDetailStatusFilter, $event) || (ctx_r1.SourceDetailStatusFilter = $event); return i0.ɵɵresetView($event); });
433
+ i0.ɵɵlistener("ngModelChange", function ClassifySourcesTabComponent_Conditional_27_Conditional_10_Template_select_ngModelChange_62_listener() { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnSourceDetailStatusFilterChange()); });
434
+ i0.ɵɵrepeaterCreate(63, ClassifySourcesTabComponent_Conditional_27_Conditional_10_For_64_Template, 2, 2, "option", 75, i0.ɵɵrepeaterTrackByIdentity);
435
+ i0.ɵɵelementEnd();
436
+ i0.ɵɵelementStart(65, "button", 76);
437
+ i0.ɵɵlistener("click", function ClassifySourcesTabComponent_Conditional_27_Conditional_10_Template_button_click_65_listener() { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.RetryFailedItems()); });
438
+ i0.ɵɵelement(66, "i", 77);
439
+ i0.ɵɵtext(67, " Retry Failed ");
440
+ i0.ɵɵelementEnd()()();
441
+ i0.ɵɵelementStart(68, "div", 78);
442
+ i0.ɵɵconditionalCreate(69, ClassifySourcesTabComponent_Conditional_27_Conditional_10_Conditional_69_Template, 3, 1, "div", 79);
443
+ i0.ɵɵrepeaterCreate(70, ClassifySourcesTabComponent_Conditional_27_Conditional_10_For_71_Template, 12, 11, "div", 80, _forTrack0);
444
+ i0.ɵɵelementEnd();
445
+ i0.ɵɵconditionalCreate(72, ClassifySourcesTabComponent_Conditional_27_Conditional_10_Conditional_72_Template, 9, 4, "div", 81);
446
+ i0.ɵɵelementEnd();
447
+ i0.ɵɵconditionalCreate(73, ClassifySourcesTabComponent_Conditional_27_Conditional_10_Conditional_73_Template, 6, 0, "div", 62);
448
+ i0.ɵɵelementStart(74, "div", 82)(75, "button", 83);
449
+ i0.ɵɵlistener("click", function ClassifySourcesTabComponent_Conditional_27_Conditional_10_Template_button_click_75_listener() { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OpenEditSourceFromDetail()); });
450
+ i0.ɵɵelement(76, "i", 41);
451
+ i0.ɵɵtext(77, " Edit ");
452
+ i0.ɵɵelementEnd();
453
+ i0.ɵɵelementStart(78, "button", 84);
454
+ i0.ɵɵlistener("click", function ClassifySourcesTabComponent_Conditional_27_Conditional_10_Template_button_click_78_listener() { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.RunSourceFromDetail()); });
455
+ i0.ɵɵelement(79, "i", 42);
456
+ i0.ɵɵtext(80, " Run Now ");
457
+ i0.ɵɵelementEnd();
458
+ i0.ɵɵelementStart(81, "button", 85);
459
+ i0.ɵɵlistener("click", function ClassifySourcesTabComponent_Conditional_27_Conditional_10_Template_button_click_81_listener() { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.DeleteSourceFromDetail()); });
460
+ i0.ɵɵelement(82, "i", 46);
461
+ i0.ɵɵtext(83, " Delete ");
462
+ i0.ɵɵelementEnd()();
463
+ } if (rf & 2) {
464
+ const ctx_r1 = i0.ɵɵnextContext(2);
465
+ i0.ɵɵadvance(2);
466
+ i0.ɵɵclassMap(ctx_r1.SelectedSource.Icon);
467
+ i0.ɵɵadvance(3);
468
+ i0.ɵɵtextInterpolate(ctx_r1.SelectedSource.Name);
469
+ i0.ɵɵadvance(3);
470
+ i0.ɵɵtextInterpolate(ctx_r1.SelectedSource.SourceTypeName);
471
+ i0.ɵɵadvance();
472
+ i0.ɵɵclassMap("at-detail-badge-status-" + ctx_r1.SelectedSource.StatusClass);
473
+ i0.ɵɵadvance();
474
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.SelectedSource.StatusLabel, " ");
475
+ i0.ɵɵadvance(5);
476
+ i0.ɵɵconditional(ctx_r1.SelectedSource.URL ? 15 : -1);
477
+ i0.ɵɵadvance();
478
+ i0.ɵɵconditional(ctx_r1.SelectedSource.RequiresFileType ? 16 : -1);
479
+ i0.ɵɵadvance(5);
480
+ i0.ɵɵtextInterpolate(ctx_r1.SelectedSource.EmbeddingModelName);
481
+ i0.ɵɵadvance(5);
482
+ i0.ɵɵtextInterpolate(ctx_r1.SelectedSource.VectorIndexName);
483
+ i0.ɵɵadvance(7);
484
+ i0.ɵɵtextInterpolate(ctx_r1.formatNumber(ctx_r1.SelectedSource.ItemCount));
485
+ i0.ɵɵadvance(5);
486
+ i0.ɵɵtextInterpolate(ctx_r1.formatNumber(ctx_r1.SelectedSource.TagCount));
487
+ i0.ɵɵadvance(5);
488
+ i0.ɵɵtextInterpolate(ctx_r1.SelectedSource.AvgTags);
489
+ i0.ɵɵadvance(5);
490
+ i0.ɵɵtextInterpolate(ctx_r1.SelectedSource.LastRunAgo);
491
+ i0.ɵɵadvance(4);
492
+ i0.ɵɵclassProp("at-kpi-error-value", ctx_r1.SelectedSource.ErrorCount > 0);
493
+ i0.ɵɵadvance();
494
+ i0.ɵɵtextInterpolate(ctx_r1.SelectedSource.ErrorCount);
495
+ i0.ɵɵadvance(6);
496
+ i0.ɵɵtextInterpolate2("Content Library (", ctx_r1.FilteredSourceDetailTotal, " of ", i0.ɵɵpipeBind1(60, 24, ctx_r1.SelectedSource.ItemCount), ")");
497
+ i0.ɵɵadvance(3);
498
+ i0.ɵɵtwoWayProperty("ngModel", ctx_r1.SourceDetailStatusFilter);
499
+ i0.ɵɵadvance();
500
+ i0.ɵɵrepeater(ctx_r1.SourceDetailStatusOptions);
501
+ i0.ɵɵadvance(6);
502
+ i0.ɵɵconditional(ctx_r1.FilteredSourceDetailItems.length === 0 ? 69 : -1);
503
+ i0.ɵɵadvance();
504
+ i0.ɵɵrepeater(ctx_r1.FilteredSourceDetailItems);
505
+ i0.ɵɵadvance(2);
506
+ i0.ɵɵconditional(ctx_r1.SourceDetailTotalPages > 1 ? 72 : -1);
507
+ i0.ɵɵadvance();
508
+ i0.ɵɵconditional(ctx_r1.SelectedSource.RunHistory.length > 0 ? 73 : -1);
509
+ } }
510
+ function ClassifySourcesTabComponent_Conditional_27_Template(rf, ctx) { if (rf & 1) {
511
+ const _r7 = i0.ɵɵgetCurrentView();
512
+ i0.ɵɵelementStart(0, "div", 50);
513
+ i0.ɵɵlistener("click", function ClassifySourcesTabComponent_Conditional_27_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.CloseSourceDetail()); });
514
+ i0.ɵɵelementEnd();
515
+ i0.ɵɵelementStart(1, "div", 51)(2, "div", 52)(3, "h3");
516
+ i0.ɵɵelement(4, "i", 24);
517
+ i0.ɵɵtext(5, " Source Detail");
518
+ i0.ɵɵelementEnd();
519
+ i0.ɵɵelementStart(6, "button", 53);
520
+ i0.ɵɵlistener("click", function ClassifySourcesTabComponent_Conditional_27_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.CloseSourceDetail()); });
521
+ i0.ɵɵelement(7, "i", 54);
522
+ i0.ɵɵelementEnd()();
523
+ i0.ɵɵelementStart(8, "div", 55);
524
+ i0.ɵɵconditionalCreate(9, ClassifySourcesTabComponent_Conditional_27_Conditional_9_Template, 2, 0, "div", 10);
525
+ i0.ɵɵconditionalCreate(10, ClassifySourcesTabComponent_Conditional_27_Conditional_10_Template, 84, 26);
526
+ i0.ɵɵelementEnd()();
527
+ } if (rf & 2) {
528
+ const ctx_r1 = i0.ɵɵnextContext();
529
+ i0.ɵɵadvance(9);
530
+ i0.ɵɵconditional(ctx_r1.SourceDetailLoading ? 9 : -1);
531
+ i0.ɵɵadvance();
532
+ i0.ɵɵconditional(!ctx_r1.SourceDetailLoading && ctx_r1.SelectedSource ? 10 : -1);
533
+ } }
534
+ function ClassifySourcesTabComponent_Conditional_28_Conditional_33_Template(rf, ctx) { if (rf & 1) {
535
+ i0.ɵɵelement(0, "i", 21);
536
+ i0.ɵɵtext(1, " Saving... ");
537
+ } }
538
+ function ClassifySourcesTabComponent_Conditional_28_Conditional_34_Template(rf, ctx) { if (rf & 1) {
539
+ i0.ɵɵelement(0, "i", 120);
540
+ i0.ɵɵtext(1, " Create Schedule ");
541
+ } }
542
+ function ClassifySourcesTabComponent_Conditional_28_Template(rf, ctx) { if (rf & 1) {
543
+ const _r14 = i0.ɵɵgetCurrentView();
544
+ i0.ɵɵelementStart(0, "div", 103);
545
+ i0.ɵɵlistener("click", function ClassifySourcesTabComponent_Conditional_28_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.CloseScheduleDialog()); });
546
+ i0.ɵɵelementStart(1, "div", 104);
547
+ i0.ɵɵlistener("click", function ClassifySourcesTabComponent_Conditional_28_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r14); return i0.ɵɵresetView($event.stopPropagation()); });
548
+ i0.ɵɵelementStart(2, "div", 105)(3, "h3");
549
+ i0.ɵɵelement(4, "i", 48);
550
+ i0.ɵɵtext(5, " Schedule Pipeline");
551
+ i0.ɵɵelementEnd();
552
+ i0.ɵɵelementStart(6, "button", 106);
553
+ i0.ɵɵlistener("click", function ClassifySourcesTabComponent_Conditional_28_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.CloseScheduleDialog()); });
554
+ i0.ɵɵelement(7, "i", 54);
555
+ i0.ɵɵelementEnd()();
556
+ i0.ɵɵelementStart(8, "div", 107)(9, "div", 108)(10, "label");
557
+ i0.ɵɵtext(11, "Source");
558
+ i0.ɵɵelementEnd();
559
+ i0.ɵɵelementStart(12, "div", 109);
560
+ i0.ɵɵelement(13, "i");
561
+ i0.ɵɵtext(14);
562
+ i0.ɵɵelementEnd()();
563
+ i0.ɵɵelementStart(15, "div", 108)(16, "label");
564
+ i0.ɵɵtext(17, "Action");
565
+ i0.ɵɵelementEnd();
566
+ i0.ɵɵelementStart(18, "div", 110);
567
+ i0.ɵɵtext(19, "Autotag and Vectorize Content");
568
+ i0.ɵɵelementEnd()();
569
+ i0.ɵɵelementStart(20, "div", 108)(21, "label", 111);
570
+ i0.ɵɵtext(22, "Cron Expression");
571
+ i0.ɵɵelementEnd();
572
+ i0.ɵɵelementStart(23, "input", 112);
573
+ i0.ɵɵtwoWayListener("ngModelChange", function ClassifySourcesTabComponent_Conditional_28_Template_input_ngModelChange_23_listener($event) { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.ScheduleCron, $event) || (ctx_r1.ScheduleCron = $event); return i0.ɵɵresetView($event); });
574
+ i0.ɵɵelementEnd();
575
+ i0.ɵɵelementStart(24, "div", 113);
576
+ i0.ɵɵelement(25, "i", 114);
577
+ i0.ɵɵtext(26);
578
+ i0.ɵɵelementEnd()();
579
+ i0.ɵɵelementStart(27, "div", 115)(28, "label", 116);
580
+ i0.ɵɵtext(29, "Enabled");
581
+ i0.ɵɵelementEnd();
582
+ i0.ɵɵelementStart(30, "input", 117);
583
+ i0.ɵɵtwoWayListener("ngModelChange", function ClassifySourcesTabComponent_Conditional_28_Template_input_ngModelChange_30_listener($event) { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.ScheduleEnabled, $event) || (ctx_r1.ScheduleEnabled = $event); return i0.ɵɵresetView($event); });
584
+ i0.ɵɵelementEnd()()();
585
+ i0.ɵɵelementStart(31, "div", 118)(32, "button", 119);
586
+ i0.ɵɵlistener("click", function ClassifySourcesTabComponent_Conditional_28_Template_button_click_32_listener() { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.SaveSchedule()); });
587
+ i0.ɵɵconditionalCreate(33, ClassifySourcesTabComponent_Conditional_28_Conditional_33_Template, 2, 0)(34, ClassifySourcesTabComponent_Conditional_28_Conditional_34_Template, 2, 0);
588
+ i0.ɵɵelementEnd();
589
+ i0.ɵɵelementStart(35, "button", 84);
590
+ i0.ɵɵlistener("click", function ClassifySourcesTabComponent_Conditional_28_Template_button_click_35_listener() { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.CloseScheduleDialog()); });
591
+ i0.ɵɵtext(36, "Cancel");
592
+ i0.ɵɵelementEnd()()()();
593
+ } if (rf & 2) {
594
+ const ctx_r1 = i0.ɵɵnextContext();
595
+ i0.ɵɵadvance(13);
596
+ i0.ɵɵclassMap(ctx_r1.SchedulingSourceCard.Icon);
597
+ i0.ɵɵadvance();
598
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.SchedulingSourceCard.Name, " ");
599
+ i0.ɵɵadvance(9);
600
+ i0.ɵɵtwoWayProperty("ngModel", ctx_r1.ScheduleCron);
601
+ i0.ɵɵadvance(3);
602
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.GetCronPreview(ctx_r1.ScheduleCron), " ");
603
+ i0.ɵɵadvance(4);
604
+ i0.ɵɵtwoWayProperty("ngModel", ctx_r1.ScheduleEnabled);
605
+ i0.ɵɵadvance(2);
606
+ i0.ɵɵproperty("disabled", ctx_r1.ScheduleSaving);
607
+ i0.ɵɵadvance();
608
+ i0.ɵɵconditional(ctx_r1.ScheduleSaving ? 33 : 34);
609
+ } }
610
+ export class ClassifySourcesTabComponent extends BaseAngularComponent {
611
+ cdr = inject(ChangeDetectorRef);
612
+ // ── Shared raw inputs (host is the data orchestrator) ──
613
+ /** Raw `MJ: Content Sources` rows — the primary source for the cards. */
614
+ _sources = [];
615
+ set Sources(value) {
616
+ this._sources = value ?? [];
617
+ this.rebuild();
618
+ }
619
+ get Sources() {
620
+ return this._sources;
621
+ }
622
+ /** Raw `MJ: Content Items` rows — used to count items per source. */
623
+ _items = [];
624
+ set Items(value) {
625
+ this._items = value ?? [];
626
+ this.rebuild();
627
+ }
628
+ get Items() {
629
+ return this._items;
630
+ }
631
+ /** Raw `MJ: Content Item Tags` rows — used to count tags per source. */
632
+ _tags = [];
633
+ set Tags(value) {
634
+ this._tags = value ?? [];
635
+ this.rebuild();
636
+ }
637
+ get Tags() {
638
+ return this._tags;
639
+ }
640
+ /** Raw `MJ: Content Process Runs` rows — used to derive last-run + status. */
641
+ _runs = [];
642
+ set Runs(value) {
643
+ this._runs = value ?? [];
644
+ this.rebuild();
645
+ }
646
+ get Runs() {
647
+ return this._runs;
648
+ }
649
+ /** Accurate total item count from TotalRowCount (used when a single source exists). */
650
+ _totalItemCount = 0;
651
+ set TotalItemCount(value) {
652
+ this._totalItemCount = value ?? 0;
653
+ this.rebuild();
654
+ }
655
+ get TotalItemCount() {
656
+ return this._totalItemCount;
657
+ }
658
+ /** Accurate total tag count from TotalRowCount (used when a single source exists). */
659
+ _totalTagCount = 0;
660
+ set TotalTagCount(value) {
661
+ this._totalTagCount = value ?? 0;
662
+ this.rebuild();
663
+ }
664
+ get TotalTagCount() {
665
+ return this._totalTagCount;
666
+ }
667
+ /** Cached ScheduledAction entities, keyed by normalized ID, supplied by the host. */
668
+ _scheduledActions = new Map();
669
+ set ScheduledActions(value) {
670
+ this._scheduledActions = value ?? new Map();
671
+ this.rebuild();
672
+ }
673
+ get ScheduledActions() {
674
+ return this._scheduledActions;
675
+ }
676
+ /** Cache: EntityRecordDocument ID → RecordID, supplied by the host. */
677
+ _entityRecordDocCache = new Map();
678
+ set EntityRecordDocCache(value) {
679
+ this._entityRecordDocCache = value ?? new Map();
680
+ }
681
+ get EntityRecordDocCache() {
682
+ return this._entityRecordDocCache;
683
+ }
684
+ // ── Tab-local view state ──
685
+ /** Shown while a manual Refresh() recomputes the source cards. */
686
+ IsLoading = false;
687
+ SourceCards = [];
688
+ // Source Detail slide-in
689
+ SelectedSource = null;
690
+ ShowSourceDetail = false;
691
+ SourceDetailLoading = false;
692
+ SourceDetailStatusFilter = 'All';
693
+ SourceDetailStatusOptions = ['All', 'Complete', 'Processing', 'Failed', 'Pending'];
694
+ SourceDetailPage = 0;
695
+ SourceDetailPageSize = 10;
696
+ // Dry-run preview dialog (hosted here, like the schedule + detail dialogs)
697
+ ShowDryRunPreview = false;
698
+ DryRunSourceCard = null;
699
+ // Schedule dialog
700
+ ShowScheduleDialog = false;
701
+ ScheduleSaving = false;
702
+ SchedulingSourceCard = null;
703
+ ScheduleCron = '0 2 * * *';
704
+ ScheduleEnabled = true;
705
+ /** Template-facing formatter. */
706
+ formatNumber = formatNumber;
707
+ // ── Cross-tab intents (host owns the slide-in form, navigation, pipeline) ──
708
+ /** Bubble "add source" up — host opens its slide-in CRUD form. */
709
+ AddSourceRequested = new EventEmitter();
710
+ /** Bubble "add source (guided)" up — host opens the setup wizard. */
711
+ AddSourceGuidedRequested = new EventEmitter();
712
+ /** Bubble "edit source" up — host opens its slide-in CRUD form pre-filled. */
713
+ EditSourceRequested = new EventEmitter();
714
+ /** Bubble "run pipeline for source" up — host runs the pipeline for the given source ID. */
715
+ RunSourceRequested = new EventEmitter();
716
+ /** Bubble "open content item detail" up — host owns the item-detail slide-in. */
717
+ OpenContentItemRequested = new EventEmitter();
718
+ /** Fired after a delete / schedule change so the host reloads the shared source list. */
719
+ DataChanged = new EventEmitter();
720
+ /**
721
+ * Recompute the source cards from the current host-supplied inputs. The data
722
+ * itself is owned by the host (flows in via @Input); Refresh just rebuilds the
723
+ * view models and surfaces a brief loading state for user feedback.
724
+ */
725
+ async Refresh() {
726
+ this.IsLoading = true;
727
+ this.cdr.detectChanges();
728
+ this.rebuild();
729
+ this.IsLoading = false;
730
+ this.cdr.detectChanges();
731
+ }
732
+ onAddSource() {
733
+ this.AddSourceRequested.emit();
734
+ }
735
+ onAddSourceGuided() {
736
+ this.AddSourceGuidedRequested.emit();
737
+ }
738
+ onEditSource(card) {
739
+ this.EditSourceRequested.emit(card);
740
+ }
741
+ onRunSource(sourceID) {
742
+ this.RunSourceRequested.emit(sourceID);
743
+ }
744
+ // ── Dry-run preview (in-memory, nothing persisted) ──
745
+ /** Opens the dry-run disposition preview for a source. */
746
+ OpenDryRunPreview(card) {
747
+ this.DryRunSourceCard = card;
748
+ this.ShowDryRunPreview = true;
749
+ this.cdr.detectChanges();
750
+ }
751
+ CloseDryRunPreview() {
752
+ this.ShowDryRunPreview = false;
753
+ this.DryRunSourceCard = null;
754
+ this.cdr.detectChanges();
755
+ }
756
+ // ════════════════════════════════════════════
757
+ // SOURCE CARDS
758
+ // ════════════════════════════════════════════
759
+ /** Rebuild the source card view models from the current inputs. */
760
+ rebuild() {
761
+ const singleSource = this._sources.length === 1;
762
+ const itemCountBySource = singleSource ? null : this.countItemsBySource();
763
+ const tagCountBySource = singleSource ? null : this.countTagsBySource();
764
+ const lastRunBySource = this.getLastRunBySource();
765
+ this.SourceCards = this._sources.map(source => {
766
+ const id = source['ID'];
767
+ const itemCount = singleSource ? this._totalItemCount : (itemCountBySource.get(id) ?? 0);
768
+ const tagCount = singleSource ? this._totalTagCount : (tagCountBySource.get(id) ?? 0);
769
+ const avgTags = itemCount > 0 ? (tagCount / itemCount).toFixed(1) : '0';
770
+ const lastRun = lastRunBySource.get(id);
771
+ const typeName = source['ContentSourceType'] ?? 'Unknown';
772
+ const lastRunStatus = lastRun ? lastRun['Status']?.toLowerCase() : null;
773
+ const hasError = lastRunStatus === 'error' || lastRunStatus === 'failed';
774
+ const scheduledActionID = source['ScheduledActionID'] ?? null;
775
+ const scheduledActionName = source['ScheduledAction'] ?? null;
776
+ const cronExpr = scheduledActionID ? this.getScheduledActionCron(scheduledActionID) : null;
777
+ return {
778
+ ID: id,
779
+ Name: source['Name'] ?? 'Unnamed Source',
780
+ SourceTypeName: typeName,
781
+ ContentTypeName: source['ContentType'] ?? 'Unknown',
782
+ FileTypeName: source['ContentFileType'] ?? 'Unknown',
783
+ Icon: getSourceTypeIcon(typeName),
784
+ StatusClass: hasError ? 'error' : 'active',
785
+ StatusLabel: hasError ? 'Error' : 'Active',
786
+ URL: source['URL'] ?? '',
787
+ ItemCount: itemCount,
788
+ TagCount: tagCount,
789
+ AvgTags: avgTags,
790
+ LastRunAgo: lastRun ? this.formatRelativeTime(lastRun['StartTime']) : 'Never',
791
+ ContentSourceTypeID: source['ContentSourceTypeID'],
792
+ ContentTypeID: source['ContentTypeID'],
793
+ ContentFileTypeID: source['ContentFileTypeID'],
794
+ EmbeddingModelID: source['EmbeddingModelID'] ?? '',
795
+ VectorIndexID: source['VectorIndexID'] ?? '',
796
+ EntityID: source['EntityID'] ?? '',
797
+ EntityDocumentID: source['EntityDocumentID'] ?? '',
798
+ RequiresFileType: this.sourceTypeRequiresFileType(source['ContentSourceTypeID']),
799
+ ScheduledActionID: scheduledActionID,
800
+ ScheduledActionName: scheduledActionName,
801
+ ScheduleDescription: cronExpr ? CronToHumanReadable(cronExpr) : null,
802
+ };
803
+ });
804
+ this.cdr.detectChanges();
805
+ }
806
+ // ── Aggregation utilities (read only the raw inputs) ──
807
+ countItemsBySource() {
808
+ const counts = new Map();
809
+ for (const item of this._items) {
810
+ const sourceId = item['ContentSourceID'];
811
+ if (sourceId)
812
+ counts.set(sourceId, (counts.get(sourceId) ?? 0) + 1);
813
+ }
814
+ return counts;
815
+ }
816
+ countTagsBySource() {
817
+ const itemSourceMap = new Map();
818
+ for (const item of this._items) {
819
+ itemSourceMap.set(item['ID'], item['ContentSourceID']);
820
+ }
821
+ const counts = new Map();
822
+ for (const tag of this._tags) {
823
+ const sourceId = itemSourceMap.get(tag['ItemID']);
824
+ if (sourceId)
825
+ counts.set(sourceId, (counts.get(sourceId) ?? 0) + 1);
826
+ }
827
+ return counts;
828
+ }
829
+ getLastRunBySource() {
830
+ const map = new Map();
831
+ for (const run of this._runs) {
832
+ const sourceId = run['SourceID'];
833
+ if (sourceId && !map.has(sourceId)) {
834
+ map.set(sourceId, run);
835
+ }
836
+ }
837
+ return map;
838
+ }
839
+ countTagsByItem() {
840
+ const counts = new Map();
841
+ for (const tag of this._tags) {
842
+ const itemId = NormalizeUUID(tag['ItemID']);
843
+ if (itemId)
844
+ counts.set(itemId, (counts.get(itemId) ?? 0) + 1);
845
+ }
846
+ return counts;
847
+ }
848
+ getAllWeightedTagsForItem(itemId) {
849
+ const tags = [];
850
+ for (const tag of this._tags) {
851
+ if (UUIDsEqual(tag['ItemID'], itemId)) {
852
+ tags.push({
853
+ Tag: tag['Tag'],
854
+ Weight: Number(tag['Weight'] ?? 1),
855
+ });
856
+ }
857
+ }
858
+ return tags.sort((a, b) => b.Weight - a.Weight);
859
+ }
860
+ /** Check if a source type's Configuration says RequiresFileType !== false */
861
+ sourceTypeRequiresFileType(sourceTypeID) {
862
+ try {
863
+ const engine = KnowledgeHubMetadataEngine.Instance;
864
+ const st = engine.ContentSourceTypes.find(t => UUIDsEqual(t.ID, sourceTypeID));
865
+ return st?.ConfigurationObject?.RequiresFileType !== false;
866
+ }
867
+ catch {
868
+ return true;
869
+ }
870
+ }
871
+ /** Resolve the entity record ID from the EntityRecordDocument for entity-sourced content items */
872
+ resolveEntityRecordID(item) {
873
+ const erdID = item['EntityRecordDocumentID'];
874
+ if (!erdID)
875
+ return null;
876
+ return this._entityRecordDocCache.get(NormalizeUUID(erdID)) ?? null;
877
+ }
878
+ /** Resolve the entity name for an entity-sourced content source */
879
+ resolveEntityName(sourceId) {
880
+ try {
881
+ const engine = KnowledgeHubMetadataEngine.Instance;
882
+ const source = engine.ContentSources.find(cs => UUIDsEqual(cs.ID, sourceId));
883
+ if (!source?.EntityID)
884
+ return null;
885
+ const md = this.ProviderToUse;
886
+ const entityInfo = md.Entities.find(e => UUIDsEqual(e.ID, source.EntityID));
887
+ return entityInfo?.Name ?? null;
888
+ }
889
+ catch {
890
+ return null;
891
+ }
892
+ }
893
+ resolveEmbeddingModelName(modelId) {
894
+ if (!modelId)
895
+ return 'System default';
896
+ const aiEngine = AIEngineBase.Instance;
897
+ const model = aiEngine.Models.find(m => UUIDsEqual(m.ID, modelId));
898
+ return model ? model.Name : 'Unknown';
899
+ }
900
+ resolveVectorIndexName(indexId) {
901
+ if (!indexId)
902
+ return 'System default';
903
+ const engine = KnowledgeHubMetadataEngine.Instance;
904
+ const idx = engine.GetVectorIndexById(indexId);
905
+ return idx ? idx.Name : 'Unknown';
906
+ }
907
+ /**
908
+ * Infer embedding and tagging pipeline statuses for a content item. Uses tag
909
+ * count + run-history heuristics since dedicated status columns are not yet
910
+ * available on the ContentItem entity.
911
+ */
912
+ inferPipelineStatuses(rawItem, tagCount) {
913
+ const explicitEmbedding = rawItem['EmbeddingStatus'];
914
+ const explicitTagging = rawItem['TaggingStatus'];
915
+ if (explicitEmbedding || explicitTagging) {
916
+ return {
917
+ EmbeddingStatus: this.mapStatusString(explicitEmbedding),
918
+ TaggingStatus: this.mapStatusString(explicitTagging),
919
+ };
920
+ }
921
+ const hasChecksum = !!rawItem['Checksum'];
922
+ const hasText = !!(rawItem['Text']?.trim());
923
+ const sourceID = rawItem['ContentSourceID'];
924
+ const lastRun = this._runs.find(r => r['SourceID'] === sourceID);
925
+ const lastRunFailed = lastRun &&
926
+ (lastRun['Status']?.toLowerCase() === 'error' ||
927
+ lastRun['Status']?.toLowerCase() === 'failed');
928
+ let embeddingStatus = 'Pending';
929
+ if (hasChecksum || hasText)
930
+ embeddingStatus = 'Complete';
931
+ else if (lastRunFailed)
932
+ embeddingStatus = 'Failed';
933
+ let taggingStatus = 'Pending';
934
+ if (tagCount > 0)
935
+ taggingStatus = 'Complete';
936
+ else if (embeddingStatus === 'Complete')
937
+ taggingStatus = lastRunFailed ? 'Failed' : 'Pending';
938
+ else if (lastRunFailed)
939
+ taggingStatus = 'Failed';
940
+ return { EmbeddingStatus: embeddingStatus, TaggingStatus: taggingStatus };
941
+ }
942
+ mapStatusString(status) {
943
+ if (!status)
944
+ return 'Pending';
945
+ const lower = status.toLowerCase();
946
+ if (lower === 'complete' || lower === 'completed' || lower === 'done')
947
+ return 'Complete';
948
+ if (lower === 'processing' || lower === 'running')
949
+ return 'Processing';
950
+ if (lower === 'failed' || lower === 'error')
951
+ return 'Failed';
952
+ return 'Pending';
953
+ }
954
+ formatRelativeTime(dateStr) {
955
+ if (!dateStr)
956
+ return 'Never';
957
+ const now = new Date();
958
+ const then = new Date(dateStr);
959
+ const diffMs = now.getTime() - then.getTime();
960
+ const diffMins = Math.floor(diffMs / 60000);
961
+ if (diffMins < 1)
962
+ return 'Just now';
963
+ if (diffMins < 60)
964
+ return `${diffMins}m ago`;
965
+ const diffHours = Math.floor(diffMins / 60);
966
+ if (diffHours < 24)
967
+ return `${diffHours}h ago`;
968
+ const diffDays = Math.floor(diffHours / 24);
969
+ return `${diffDays}d ago`;
970
+ }
971
+ /** Looks up the cron expression for a cached ScheduledAction by ID */
972
+ getScheduledActionCron(scheduledActionID) {
973
+ const cached = this._scheduledActions.get(NormalizeUUID(scheduledActionID));
974
+ return cached?.CronExpression ?? null;
975
+ }
976
+ /** Returns the CSS class for a pipeline status badge color */
977
+ GetStatusBadgeClass(status) {
978
+ switch (status) {
979
+ case 'Complete': return 'at-status-badge-complete';
980
+ case 'Processing': return 'at-status-badge-processing';
981
+ case 'Failed': return 'at-status-badge-failed';
982
+ case 'Pending': return 'at-status-badge-pending';
983
+ }
984
+ }
985
+ // ════════════════════════════════════════════
986
+ // DELETE
987
+ // ════════════════════════════════════════════
988
+ async DeleteSource(card) {
989
+ if (!confirm(`Delete source "${card.Name}"? This cannot be undone.`))
990
+ return;
991
+ try {
992
+ const p = this.ProviderToUse;
993
+ const entity = await p.GetEntityObject('MJ: Content Sources', p.CurrentUser);
994
+ await entity.InnerLoad(new CompositeKey([{ FieldName: 'ID', Value: card.ID }]));
995
+ const deleted = await entity.Delete();
996
+ if (deleted) {
997
+ MJNotificationService.Instance.CreateSimpleNotification('Source deleted', 'success', 2500);
998
+ this.DataChanged.emit();
999
+ }
1000
+ else {
1001
+ MJNotificationService.Instance.CreateSimpleNotification('Failed to delete source', 'error', 3000);
1002
+ }
1003
+ }
1004
+ catch (error) {
1005
+ const msg = error instanceof Error ? error.message : String(error);
1006
+ MJNotificationService.Instance.CreateSimpleNotification(`Error: ${msg}`, 'error', 4000);
1007
+ }
1008
+ }
1009
+ // ════════════════════════════════════════════
1010
+ // SCHEDULE DIALOG — Quick Schedule for Source
1011
+ // ════════════════════════════════════════════
1012
+ OpenScheduleDialog(card) {
1013
+ this.SchedulingSourceCard = card;
1014
+ this.ScheduleCron = '0 2 * * *';
1015
+ this.ScheduleEnabled = true;
1016
+ this.ShowScheduleDialog = true;
1017
+ this.cdr.detectChanges();
1018
+ }
1019
+ CloseScheduleDialog() {
1020
+ this.ShowScheduleDialog = false;
1021
+ this.SchedulingSourceCard = null;
1022
+ this.cdr.detectChanges();
1023
+ }
1024
+ /**
1025
+ * Saves a new ScheduledAction for the current source, links it via
1026
+ * ContentSource.ScheduledActionID, and creates the default action params
1027
+ * for the Autotag and Vectorize action.
1028
+ */
1029
+ async SaveSchedule() {
1030
+ if (this.ScheduleSaving || !this.SchedulingSourceCard)
1031
+ return;
1032
+ this.ScheduleSaving = true;
1033
+ this.cdr.detectChanges();
1034
+ const card = this.SchedulingSourceCard;
1035
+ try {
1036
+ const p = this.ProviderToUse;
1037
+ // 1. Find the "Autotag and Vectorize Content" action
1038
+ const actionID = await this.findAutotagActionID();
1039
+ if (!actionID) {
1040
+ MJNotificationService.Instance.CreateSimpleNotification('Could not find the "Autotag and Vectorize Content" action. Please check action configuration.', 'error', 5000);
1041
+ return;
1042
+ }
1043
+ // 2. Create the ScheduledAction
1044
+ const scheduledAction = await p.GetEntityObject('MJ: Scheduled Actions', p.CurrentUser);
1045
+ scheduledAction.NewRecord();
1046
+ scheduledAction.Name = `Autotag: ${card.Name}`;
1047
+ scheduledAction.Description = `Automated classification pipeline for content source "${card.Name}"`;
1048
+ scheduledAction.ActionID = actionID;
1049
+ scheduledAction.Type = 'Custom';
1050
+ scheduledAction.CronExpression = this.ScheduleCron;
1051
+ scheduledAction.CustomCronExpression = this.ScheduleCron;
1052
+ scheduledAction.Status = this.ScheduleEnabled ? 'Active' : 'Disabled';
1053
+ scheduledAction.Timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
1054
+ const saved = await scheduledAction.Save();
1055
+ if (!saved) {
1056
+ const errorDetail = scheduledAction.LatestResult?.CompleteMessage ?? 'Unknown error';
1057
+ MJNotificationService.Instance.CreateSimpleNotification(`Failed to create schedule: ${errorDetail}`, 'error', 5000);
1058
+ return;
1059
+ }
1060
+ // 3. Create ScheduledActionParam for sourceIDs
1061
+ await this.createSourceIDParam(scheduledAction.ID, actionID, card.ID);
1062
+ // 4. Link ScheduledAction to ContentSource
1063
+ await this.linkScheduleToSource(card.ID, scheduledAction.ID);
1064
+ // 5. Cache the new action for cron display
1065
+ this._scheduledActions.set(NormalizeUUID(scheduledAction.ID), scheduledAction);
1066
+ MJNotificationService.Instance.CreateSimpleNotification(`Schedule created: ${CronToHumanReadable(this.ScheduleCron)}`, 'success', 3000);
1067
+ this.CloseScheduleDialog();
1068
+ this.DataChanged.emit();
1069
+ }
1070
+ catch (error) {
1071
+ const msg = error instanceof Error ? error.message : String(error);
1072
+ console.error('[Classify] Schedule creation error:', error);
1073
+ MJNotificationService.Instance.CreateSimpleNotification(`Error: ${msg}`, 'error', 5000);
1074
+ }
1075
+ finally {
1076
+ this.ScheduleSaving = false;
1077
+ this.cdr.detectChanges();
1078
+ }
1079
+ }
1080
+ /**
1081
+ * Removes the schedule from a source card by unlinking the ScheduledActionID.
1082
+ */
1083
+ async RemoveSchedule(card) {
1084
+ if (!card.ScheduledActionID)
1085
+ return;
1086
+ if (!confirm(`Remove the schedule "${card.ScheduleDescription ?? 'schedule'}" from "${card.Name}"?`))
1087
+ return;
1088
+ try {
1089
+ await this.linkScheduleToSource(card.ID, null);
1090
+ MJNotificationService.Instance.CreateSimpleNotification('Schedule removed from source', 'success', 2500);
1091
+ this.DataChanged.emit();
1092
+ }
1093
+ catch (error) {
1094
+ const msg = error instanceof Error ? error.message : String(error);
1095
+ MJNotificationService.Instance.CreateSimpleNotification(`Error: ${msg}`, 'error', 4000);
1096
+ }
1097
+ }
1098
+ /** Returns the human-readable schedule description for a source card. */
1099
+ GetScheduleLabel(card) {
1100
+ return card.ScheduleDescription ?? 'Scheduled';
1101
+ }
1102
+ /** Returns a human-readable preview of a cron expression for the schedule dialog. */
1103
+ GetCronPreview(cron) {
1104
+ return CronToHumanReadable(cron);
1105
+ }
1106
+ /** Finds the Action ID for "Autotag and Vectorize Content" by querying actions */
1107
+ async findAutotagActionID() {
1108
+ const rv = RunView.FromMetadataProvider(this.ProviderToUse);
1109
+ const result = await rv.RunView({
1110
+ EntityName: 'Actions',
1111
+ ExtraFilter: `Name = 'Autotag and Vectorize Content'`,
1112
+ Fields: ['ID'],
1113
+ ResultType: 'simple',
1114
+ MaxRows: 1,
1115
+ });
1116
+ if (result.Success && result.Results.length > 0) {
1117
+ return result.Results[0].ID;
1118
+ }
1119
+ return null;
1120
+ }
1121
+ /**
1122
+ * Creates a ScheduledActionParam that passes the source ID to the action.
1123
+ * Looks up the "EntityNames" action param and sets the source ID as its value.
1124
+ */
1125
+ async createSourceIDParam(scheduledActionID, actionID, sourceID) {
1126
+ const rv = RunView.FromMetadataProvider(this.ProviderToUse);
1127
+ const paramResult = await rv.RunView({
1128
+ EntityName: 'Action Params',
1129
+ ExtraFilter: `ActionID = '${actionID}' AND Name = 'EntityNames'`,
1130
+ Fields: ['ID', 'Name'],
1131
+ ResultType: 'simple',
1132
+ MaxRows: 1,
1133
+ });
1134
+ if (!paramResult.Success || paramResult.Results.length === 0) {
1135
+ console.warn('[Classify] Could not find EntityNames action param for source ID scheduling');
1136
+ return;
1137
+ }
1138
+ const p = this.ProviderToUse;
1139
+ const param = await p.GetEntityObject('MJ: Scheduled Action Params', p.CurrentUser);
1140
+ param.NewRecord();
1141
+ param.ScheduledActionID = scheduledActionID;
1142
+ param.ActionParamID = paramResult.Results[0].ID;
1143
+ param.ValueType = 'Static';
1144
+ param.Value = sourceID;
1145
+ const saved = await param.Save();
1146
+ if (!saved) {
1147
+ console.warn('[Classify] Failed to save schedule param:', param.LatestResult?.CompleteMessage);
1148
+ }
1149
+ }
1150
+ /**
1151
+ * Links (or unlinks) a ScheduledAction to a ContentSource by updating
1152
+ * the ContentSource.ScheduledActionID field.
1153
+ */
1154
+ async linkScheduleToSource(sourceID, scheduledActionID) {
1155
+ const p = this.ProviderToUse;
1156
+ const entity = await p.GetEntityObject('MJ: Content Sources', p.CurrentUser);
1157
+ await entity.InnerLoad(new CompositeKey([{ FieldName: 'ID', Value: sourceID }]));
1158
+ entity.ScheduledActionID = scheduledActionID;
1159
+ const saved = await entity.Save();
1160
+ if (!saved) {
1161
+ throw new Error(entity.LatestResult?.CompleteMessage ?? 'Failed to update content source');
1162
+ }
1163
+ }
1164
+ // ════════════════════════════════════════════
1165
+ // SOURCE DETAIL SLIDE-IN
1166
+ // ════════════════════════════════════════════
1167
+ async OpenSourceDetail(card) {
1168
+ this.SourceDetailLoading = true;
1169
+ this.SourceDetailPage = 0;
1170
+ this.SourceDetailStatusFilter = 'All';
1171
+ this.ShowSourceDetail = true;
1172
+ this.cdr.detectChanges();
1173
+ try {
1174
+ const sourceItems = await this.loadContentItemsForSource(card.ID);
1175
+ const sourceRuns = await this.loadRunHistoryForSource(card.ID);
1176
+ const embeddingModelName = this.resolveEmbeddingModelName(card.EmbeddingModelID);
1177
+ const vectorIndexName = this.resolveVectorIndexName(card.VectorIndexID);
1178
+ const errorCount = sourceRuns.filter(r => r.StatusClass === 'failed').length;
1179
+ this.SelectedSource = {
1180
+ ID: card.ID,
1181
+ Name: card.Name,
1182
+ SourceTypeName: card.SourceTypeName,
1183
+ FileTypeName: card.FileTypeName,
1184
+ ContentTypeName: card.ContentTypeName,
1185
+ RequiresFileType: card.RequiresFileType,
1186
+ StatusClass: card.StatusClass,
1187
+ StatusLabel: card.StatusLabel,
1188
+ Icon: card.Icon,
1189
+ URL: card.URL,
1190
+ EmbeddingModelName: embeddingModelName,
1191
+ VectorIndexName: vectorIndexName,
1192
+ ItemCount: card.ItemCount,
1193
+ TagCount: card.TagCount,
1194
+ AvgTags: card.AvgTags,
1195
+ LastRunAgo: card.LastRunAgo,
1196
+ ErrorCount: errorCount,
1197
+ ContentItems: sourceItems,
1198
+ RunHistory: sourceRuns
1199
+ };
1200
+ }
1201
+ catch (error) {
1202
+ console.error('[Autotagging] Error loading source detail:', error);
1203
+ }
1204
+ finally {
1205
+ this.SourceDetailLoading = false;
1206
+ this.cdr.detectChanges();
1207
+ }
1208
+ }
1209
+ CloseSourceDetail() {
1210
+ this.ShowSourceDetail = false;
1211
+ this.SelectedSource = null;
1212
+ this.cdr.detectChanges();
1213
+ }
1214
+ OpenContentItemDetail(item) {
1215
+ this.OpenContentItemRequested.emit(item);
1216
+ }
1217
+ OpenEditSourceFromDetail() {
1218
+ if (!this.SelectedSource)
1219
+ return;
1220
+ const card = this.SourceCards.find(c => UUIDsEqual(c.ID, this.SelectedSource.ID));
1221
+ if (card) {
1222
+ this.CloseSourceDetail();
1223
+ this.EditSourceRequested.emit(card);
1224
+ }
1225
+ }
1226
+ RunSourceFromDetail() {
1227
+ if (!this.SelectedSource)
1228
+ return;
1229
+ const sourceID = this.SelectedSource.ID;
1230
+ this.CloseSourceDetail();
1231
+ this.RunSourceRequested.emit(sourceID);
1232
+ }
1233
+ async DeleteSourceFromDetail() {
1234
+ if (!this.SelectedSource)
1235
+ return;
1236
+ const card = this.SourceCards.find(c => UUIDsEqual(c.ID, this.SelectedSource.ID));
1237
+ if (card) {
1238
+ this.CloseSourceDetail();
1239
+ await this.DeleteSource(card);
1240
+ }
1241
+ }
1242
+ // ── Source-detail filtering + pagination ──
1243
+ get FilteredSourceDetailItems() {
1244
+ if (!this.SelectedSource)
1245
+ return [];
1246
+ const items = this.SourceDetailStatusFilter === 'All'
1247
+ ? this.SelectedSource.ContentItems
1248
+ : this.SelectedSource.ContentItems.filter(ci => ci.EmbeddingStatus === this.SourceDetailStatusFilter ||
1249
+ ci.TaggingStatus === this.SourceDetailStatusFilter);
1250
+ const start = this.SourceDetailPage * this.SourceDetailPageSize;
1251
+ return items.slice(start, start + this.SourceDetailPageSize);
1252
+ }
1253
+ get FilteredSourceDetailTotal() {
1254
+ if (!this.SelectedSource)
1255
+ return 0;
1256
+ if (this.SourceDetailStatusFilter === 'All')
1257
+ return this.SelectedSource.ContentItems.length;
1258
+ return this.SelectedSource.ContentItems.filter(ci => ci.EmbeddingStatus === this.SourceDetailStatusFilter ||
1259
+ ci.TaggingStatus === this.SourceDetailStatusFilter).length;
1260
+ }
1261
+ get SourceDetailTotalPages() {
1262
+ return Math.max(1, Math.ceil(this.FilteredSourceDetailTotal / this.SourceDetailPageSize));
1263
+ }
1264
+ SourceDetailPrevPage() {
1265
+ if (this.SourceDetailPage > 0) {
1266
+ this.SourceDetailPage--;
1267
+ this.cdr.detectChanges();
1268
+ }
1269
+ }
1270
+ SourceDetailNextPage() {
1271
+ if (this.SourceDetailPage < this.SourceDetailTotalPages - 1) {
1272
+ this.SourceDetailPage++;
1273
+ this.cdr.detectChanges();
1274
+ }
1275
+ }
1276
+ OnSourceDetailStatusFilterChange() {
1277
+ this.SourceDetailPage = 0;
1278
+ this.cdr.detectChanges();
1279
+ }
1280
+ /**
1281
+ * Placeholder handler for retrying failed items in source detail. Surfaces a
1282
+ * notification; the pipeline re-processes failed items on the next run.
1283
+ */
1284
+ RetryFailedItems() {
1285
+ if (!this.SelectedSource)
1286
+ return;
1287
+ const failedCount = this.SelectedSource.ContentItems.filter(ci => ci.EmbeddingStatus === 'Failed' || ci.TaggingStatus === 'Failed').length;
1288
+ if (failedCount === 0) {
1289
+ MJNotificationService.Instance.CreateSimpleNotification('No failed items to retry', 'info', 2500);
1290
+ return;
1291
+ }
1292
+ MJNotificationService.Instance.CreateSimpleNotification(`Retry queued for ${failedCount} failed item${failedCount > 1 ? 's' : ''}. Pipeline will re-process on next run.`, 'info', 3000);
1293
+ }
1294
+ async loadContentItemsForSource(sourceId) {
1295
+ const rv = RunView.FromMetadataProvider(this.ProviderToUse);
1296
+ const result = await rv.RunView({
1297
+ EntityName: 'MJ: Content Items',
1298
+ ExtraFilter: `ContentSourceID='${sourceId}'`,
1299
+ OrderBy: '__mj_UpdatedAt DESC',
1300
+ MaxRows: 100,
1301
+ ResultType: 'simple'
1302
+ });
1303
+ if (!result.Success)
1304
+ return [];
1305
+ const tagsByItem = this.countTagsByItem();
1306
+ return result.Results.map(item => {
1307
+ const itemId = item['ID'];
1308
+ const allTags = this.getAllWeightedTagsForItem(itemId);
1309
+ const tagCount = tagsByItem.get(itemId) ?? allTags.length;
1310
+ const contentSourceTypeID = item['ContentSourceTypeID'] ?? '';
1311
+ const itemStatuses = this.inferPipelineStatuses(item, tagCount);
1312
+ return {
1313
+ ID: itemId,
1314
+ Name: deriveDisplayName({ Name: item['Name'], Description: item['Description'] }),
1315
+ SourceName: item['ContentSource'] ?? '',
1316
+ SourceTypeName: item['ContentSourceType'] ?? '',
1317
+ ContentTypeName: item['ContentType'] ?? '',
1318
+ FileTypeName: item['ContentFileType'] ?? '',
1319
+ URL: item['URL'] ?? '',
1320
+ TextContent: item['Text'] ?? '',
1321
+ Checksum: item['Checksum'] ?? '',
1322
+ Tags: allTags,
1323
+ CreatedAt: formatDate(item['__mj_CreatedAt'] ?? ''),
1324
+ UpdatedAt: formatDate(item['__mj_UpdatedAt'] ?? ''),
1325
+ ContentSourceID: sourceId,
1326
+ ContentSourceTypeID: contentSourceTypeID,
1327
+ StatusDot: tagCount > 0 ? 'complete' : 'processing',
1328
+ TagCount: tagCount,
1329
+ RequiresContentType: this.sourceTypeRequiresFileType(contentSourceTypeID),
1330
+ EntityRecordID: this.resolveEntityRecordID(item),
1331
+ EntityName: this.resolveEntityName(sourceId),
1332
+ EmbeddingStatus: itemStatuses.EmbeddingStatus,
1333
+ TaggingStatus: itemStatuses.TaggingStatus,
1334
+ };
1335
+ });
1336
+ }
1337
+ async loadRunHistoryForSource(sourceId) {
1338
+ const rv = RunView.FromMetadataProvider(this.ProviderToUse);
1339
+ const result = await rv.RunView({
1340
+ EntityName: 'MJ: Content Process Runs',
1341
+ ExtraFilter: `SourceID='${sourceId}'`,
1342
+ OrderBy: 'StartTime DESC',
1343
+ MaxRows: 10,
1344
+ ResultType: 'simple'
1345
+ });
1346
+ if (!result.Success)
1347
+ return [];
1348
+ return result.Results.map(run => {
1349
+ const status = run['Status'] ?? 'Unknown';
1350
+ const startTime = run['StartTime'];
1351
+ const endTime = run['EndTime'];
1352
+ const duration = computeDuration(startTime, endTime);
1353
+ const processedItems = run['ProcessedItems'];
1354
+ const errorCount = run['ErrorCount'];
1355
+ const statusLower = status.toLowerCase();
1356
+ const isFailed = statusLower === 'error' || statusLower === 'failed';
1357
+ const isRunning = statusLower === 'running' || statusLower === 'processing';
1358
+ const hasErrors = (errorCount ?? 0) > 0;
1359
+ return {
1360
+ ID: run['ID'],
1361
+ Status: displayStatus(status),
1362
+ StatusClass: isFailed ? 'failed' : isRunning ? 'running' : 'complete',
1363
+ SourceName: run['Source'] ?? 'Unknown',
1364
+ StartedDisplay: startTime ? formatDate(startTime) : '—',
1365
+ Duration: duration,
1366
+ Items: processedItems != null ? formatNumber(processedItems) : '—',
1367
+ Tags: '—',
1368
+ Errors: hasErrors ? formatNumber(errorCount) : (isFailed ? status : '0'),
1369
+ ErrorClass: isFailed || hasErrors ? 'run-error-text' : ''
1370
+ };
1371
+ });
1372
+ }
1373
+ static ɵfac = /*@__PURE__*/ (() => { let ɵClassifySourcesTabComponent_BaseFactory; return function ClassifySourcesTabComponent_Factory(__ngFactoryType__) { return (ɵClassifySourcesTabComponent_BaseFactory || (ɵClassifySourcesTabComponent_BaseFactory = i0.ɵɵgetInheritedFactory(ClassifySourcesTabComponent)))(__ngFactoryType__ || ClassifySourcesTabComponent); }; })();
1374
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ClassifySourcesTabComponent, selectors: [["classify-sources-tab"]], inputs: { Sources: "Sources", Items: "Items", Tags: "Tags", Runs: "Runs", TotalItemCount: "TotalItemCount", TotalTagCount: "TotalTagCount", ScheduledActions: "ScheduledActions", EntityRecordDocCache: "EntityRecordDocCache" }, outputs: { AddSourceRequested: "AddSourceRequested", AddSourceGuidedRequested: "AddSourceGuidedRequested", EditSourceRequested: "EditSourceRequested", RunSourceRequested: "RunSourceRequested", OpenContentItemRequested: "OpenContentItemRequested", DataChanged: "DataChanged" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 30, vars: 11, consts: [["Title", "Content Sources", "Subtitle", "Configure where content is ingested from"], ["actions", ""], ["mjButton", "", "variant", "secondary", "size", "sm", 3, "click", "disabled"], ["mjButton", "", "variant", "secondary", "size", "sm", 3, "click"], [1, "fa-solid", "fa-wand-magic-sparkles"], [1, "mj-action-label"], ["mjButton", "", "variant", "primary", "size", "sm", 3, "click"], [1, "fa-solid", "fa-plus"], [3, "Padding", "Flex"], [1, "at-main-area"], [1, "at-loading-overlay"], [1, "at-page-body"], [1, "at-sources-empty"], [1, "at-sources-grid"], [1, "at-source-card-full", "at-source-card-clickable"], [1, "at-add-source-card", 3, "click"], [1, "fa-solid", "fa-plus-circle"], [2, "font-size", "0.85rem", "font-weight", "600"], [2, "font-size", "0.72rem"], [1, "at-schedule-overlay"], [3, "Closed", "Provider", "Show", "SourceCard"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "fa-solid", "fa-arrows-rotate"], ["text", "Refreshing sources\u2026"], [1, "fa-solid", "fa-database"], [1, "at-sources-empty-actions"], [1, "at-source-card-full", "at-source-card-clickable", 3, "click"], [1, "at-source-card-header"], [1, "at-source-card-icon"], [1, "at-source-card-title"], [1, "at-source-card-type"], [1, "at-source-card-status"], [1, "at-source-mini-status"], [1, "at-source-card-url"], [1, "at-source-card-stats"], [1, "at-source-stat"], [1, "at-source-stat-value"], [1, "at-source-stat-label"], ["title", "Click to remove schedule", 1, "at-schedule-indicator"], [1, "at-source-card-actions"], [1, "at-source-action-btn", 3, "click"], [1, "fa-solid", "fa-pen"], [1, "fa-solid", "fa-play"], [1, "fa-solid", "fa-flask"], [1, "at-source-action-btn", "at-source-schedule-btn"], [1, "at-source-action-btn", "at-source-delete-btn", 3, "click"], [1, "fa-solid", "fa-trash"], ["title", "Click to remove schedule", 1, "at-schedule-indicator", 3, "click"], [1, "fa-regular", "fa-clock"], [1, "at-source-action-btn", "at-source-schedule-btn", 3, "click"], [1, "at-slide-overlay", 3, "click"], [1, "at-slide-panel", "at-detail-panel"], [1, "at-slide-header"], ["aria-label", "Close source detail", 1, "at-slide-close", 3, "click"], [1, "fa-solid", "fa-times"], [1, "at-slide-body"], ["text", "Loading source details..."], [1, "at-detail-source-header"], [1, "at-detail-item-name"], [1, "at-detail-badges"], [1, "at-detail-badge", "at-detail-badge-type"], [1, "at-detail-badge"], [1, "at-detail-section"], [1, "at-detail-section-label"], [1, "at-detail-meta-grid"], [1, "at-detail-meta-row"], [1, "at-detail-meta-key"], [1, "at-detail-meta-value"], [1, "at-detail-stats-strip"], [1, "at-detail-stat"], [1, "at-detail-stat-value"], [1, "at-detail-stat-label"], [1, "at-detail-section-header-row"], [1, "at-detail-section-controls"], [1, "at-detail-filter-select", 3, "ngModelChange", "ngModel"], [3, "value"], ["title", "Re-queue failed items for processing", 1, "at-action-btn", "at-retry-btn", 3, "click"], [1, "fa-solid", "fa-rotate-right"], [1, "at-detail-content-list"], [1, "at-empty-state", 2, "padding", "16px"], [1, "at-detail-content-item"], [1, "at-detail-pagination"], [1, "at-detail-actions"], [1, "at-action-btn", "at-primary-btn", 3, "click"], [1, "at-action-btn", "at-secondary-btn", 3, "click"], [1, "at-action-btn", "at-secondary-btn", "at-source-delete-btn", 3, "click"], ["target", "_blank", 1, "at-detail-link", "at-detail-meta-value", 3, "href"], [1, "at-detail-content-item", 3, "click"], [1, "at-feed-status-dot"], [1, "at-detail-content-item-name"], [1, "at-status-badge"], [1, "at-detail-content-item-tags"], [1, "at-detail-content-item-time"], [1, "at-page-btn", 3, "click", "disabled"], [1, "fa-solid", "fa-chevron-left"], [1, "at-page-info"], [1, "fa-solid", "fa-chevron-right"], [1, "at-detail-run-history"], [1, "at-detail-run-row"], [1, "at-run-status-badge"], [1, "at-detail-run-time"], [1, "at-detail-run-duration"], [1, "at-detail-run-items"], [1, "at-schedule-overlay", 3, "click"], [1, "at-schedule-dialog", 3, "click"], [1, "at-schedule-dialog-header"], ["aria-label", "Close", 1, "at-schedule-dialog-close", 3, "click"], [1, "at-schedule-dialog-body"], [1, "at-schedule-field"], [1, "at-schedule-source-name"], [1, "at-schedule-action-name"], ["for", "schedule-cron"], ["id", "schedule-cron", "type", "text", "placeholder", "0 2 * * *", 1, "mj-input", "at-schedule-cron-input", 3, "ngModelChange", "ngModel"], [1, "at-schedule-cron-preview"], [1, "fa-solid", "fa-info-circle"], [1, "at-schedule-field", "at-schedule-toggle-row"], ["for", "schedule-enabled"], ["id", "schedule-enabled", "type", "checkbox", 1, "mj-checkbox", 3, "ngModelChange", "ngModel"], [1, "at-schedule-dialog-footer"], [1, "at-action-btn", "at-primary-btn", 3, "click", "disabled"], [1, "fa-solid", "fa-check"]], template: function ClassifySourcesTabComponent_Template(rf, ctx) { if (rf & 1) {
1375
+ i0.ɵɵelementStart(0, "mj-page-header-interior", 0)(1, "div", 1)(2, "button", 2);
1376
+ i0.ɵɵlistener("click", function ClassifySourcesTabComponent_Template_button_click_2_listener() { return ctx.Refresh(); });
1377
+ i0.ɵɵconditionalCreate(3, ClassifySourcesTabComponent_Conditional_3_Template, 3, 0)(4, ClassifySourcesTabComponent_Conditional_4_Template, 3, 0);
1378
+ i0.ɵɵelementEnd();
1379
+ i0.ɵɵelementStart(5, "button", 3);
1380
+ i0.ɵɵlistener("click", function ClassifySourcesTabComponent_Template_button_click_5_listener() { return ctx.onAddSourceGuided(); });
1381
+ i0.ɵɵelement(6, "i", 4);
1382
+ i0.ɵɵelementStart(7, "span", 5);
1383
+ i0.ɵɵtext(8, "Add Source (Guided)");
1384
+ i0.ɵɵelementEnd()();
1385
+ i0.ɵɵelementStart(9, "button", 6);
1386
+ i0.ɵɵlistener("click", function ClassifySourcesTabComponent_Template_button_click_9_listener() { return ctx.onAddSource(); });
1387
+ i0.ɵɵelement(10, "i", 7);
1388
+ i0.ɵɵelementStart(11, "span", 5);
1389
+ i0.ɵɵtext(12, "Add Source");
1390
+ i0.ɵɵelementEnd()()()();
1391
+ i0.ɵɵelementStart(13, "mj-page-body-interior", 8)(14, "div", 9);
1392
+ i0.ɵɵconditionalCreate(15, ClassifySourcesTabComponent_Conditional_15_Template, 2, 0, "div", 10);
1393
+ i0.ɵɵelementStart(16, "div", 11);
1394
+ i0.ɵɵconditionalCreate(17, ClassifySourcesTabComponent_Conditional_17_Template, 13, 0, "div", 12);
1395
+ i0.ɵɵelementStart(18, "div", 13);
1396
+ i0.ɵɵrepeaterCreate(19, ClassifySourcesTabComponent_For_20_Template, 50, 17, "div", 14, _forTrack0);
1397
+ i0.ɵɵelementStart(21, "div", 15);
1398
+ i0.ɵɵlistener("click", function ClassifySourcesTabComponent_Template_div_click_21_listener() { return ctx.onAddSource(); });
1399
+ i0.ɵɵelement(22, "i", 16);
1400
+ i0.ɵɵelementStart(23, "span", 17);
1401
+ i0.ɵɵtext(24, "Add Content Source");
1402
+ i0.ɵɵelementEnd();
1403
+ i0.ɵɵelementStart(25, "span", 18);
1404
+ i0.ɵɵtext(26, "Web, RSS, Email, Files, API");
1405
+ i0.ɵɵelementEnd()()()()()();
1406
+ i0.ɵɵconditionalCreate(27, ClassifySourcesTabComponent_Conditional_27_Template, 11, 2);
1407
+ i0.ɵɵconditionalCreate(28, ClassifySourcesTabComponent_Conditional_28_Template, 37, 8, "div", 19);
1408
+ i0.ɵɵelementStart(29, "classify-dry-run-preview", 20);
1409
+ i0.ɵɵlistener("Closed", function ClassifySourcesTabComponent_Template_classify_dry_run_preview_Closed_29_listener() { return ctx.CloseDryRunPreview(); });
1410
+ i0.ɵɵelementEnd();
1411
+ } if (rf & 2) {
1412
+ i0.ɵɵadvance(2);
1413
+ i0.ɵɵproperty("disabled", ctx.IsLoading);
1414
+ i0.ɵɵadvance();
1415
+ i0.ɵɵconditional(ctx.IsLoading ? 3 : 4);
1416
+ i0.ɵɵadvance(10);
1417
+ i0.ɵɵproperty("Padding", false)("Flex", true);
1418
+ i0.ɵɵadvance(2);
1419
+ i0.ɵɵconditional(ctx.IsLoading ? 15 : -1);
1420
+ i0.ɵɵadvance(2);
1421
+ i0.ɵɵconditional(ctx.SourceCards.length === 0 && !ctx.IsLoading ? 17 : -1);
1422
+ i0.ɵɵadvance(2);
1423
+ i0.ɵɵrepeater(ctx.SourceCards);
1424
+ i0.ɵɵadvance(8);
1425
+ i0.ɵɵconditional(ctx.ShowSourceDetail ? 27 : -1);
1426
+ i0.ɵɵadvance();
1427
+ i0.ɵɵconditional(ctx.ShowScheduleDialog && ctx.SchedulingSourceCard ? 28 : -1);
1428
+ i0.ɵɵadvance();
1429
+ i0.ɵɵproperty("Provider", ctx.Provider)("Show", ctx.ShowDryRunPreview)("SourceCard", ctx.DryRunSourceCard);
1430
+ } }, dependencies: [i1.NgSelectOption, i1.ɵNgSelectMultipleOption, i1.DefaultValueAccessor, i1.CheckboxControlValueAccessor, i1.SelectControlValueAccessor, i1.NgControlStatus, i1.NgModel, i2.LoadingComponent, i3.MJButtonDirective, i3.MJPageHeaderInteriorComponent, i3.MJPageBodyInteriorComponent, i4.ClassifyDryRunPreviewDialogComponent, i5.DecimalPipe], styles: ["\n\n\n\n\n\n\n\n\n\n\n.at-sources-empty[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n text-align: center;\n gap: 10px;\n padding: 48px 24px;\n background: var(--mj-bg-surface-card);\n border: 1px dashed var(--mj-border-default);\n border-radius: 12px;\n}\n.at-sources-empty[_ngcontent-%COMP%] > i[_ngcontent-%COMP%] {\n font-size: 2rem;\n color: var(--mj-brand-primary);\n}\n.at-sources-empty[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 1rem;\n color: var(--mj-text-primary);\n}\n.at-sources-empty[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n max-width: 460px;\n font-size: 0.85rem;\n color: var(--mj-text-muted);\n line-height: 1.5;\n}\n.at-sources-empty-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n margin-top: 6px;\n}"] });
1431
+ }
1432
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ClassifySourcesTabComponent, [{
1433
+ type: Component,
1434
+ args: [{ standalone: false, selector: 'classify-sources-tab', template: "<mj-page-header-interior\n Title=\"Content Sources\"\n Subtitle=\"Configure where content is ingested from\">\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 <button mjButton variant=\"secondary\" size=\"sm\" (click)=\"onAddSourceGuided()\">\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i> <span class=\"mj-action-label\">Add Source (Guided)</span>\n </button>\n <button mjButton variant=\"primary\" size=\"sm\" (click)=\"onAddSource()\">\n <i class=\"fa-solid fa-plus\"></i> <span class=\"mj-action-label\">Add Source</span>\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-loading-overlay\">\n <mj-loading text=\"Refreshing sources\u2026\"></mj-loading>\n </div>\n }\n <div class=\"at-page-body\">\n @if (SourceCards.length === 0 && !IsLoading) {\n <div class=\"at-sources-empty\">\n <i class=\"fa-solid fa-database\"></i>\n <h3>No content sources yet</h3>\n <p>Use the guided setup to stand up your first source \u2014 pick an entity or URL, configure its document, taxonomy, and domain context in one flow.</p>\n <div class=\"at-sources-empty-actions\">\n <button mjButton variant=\"primary\" size=\"sm\" (click)=\"onAddSourceGuided()\">\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i> Add Source (Guided)\n </button>\n <button mjButton variant=\"secondary\" size=\"sm\" (click)=\"onAddSource()\">\n <i class=\"fa-solid fa-plus\"></i> Add manually\n </button>\n </div>\n </div>\n }\n\n <div class=\"at-sources-grid\">\n @for (card of SourceCards; track card.ID) {\n <div class=\"at-source-card-full at-source-card-clickable\" (click)=\"OpenSourceDetail(card)\">\n <div class=\"at-source-card-header\">\n <div class=\"at-source-card-icon\"><i [class]=\"card.Icon\"></i></div>\n <div>\n <div class=\"at-source-card-title\">{{ card.Name }}</div>\n <div class=\"at-source-card-type\">{{ card.SourceTypeName }}@if (card.RequiresFileType) { \u00B7 {{ card.FileTypeName }}}</div>\n </div>\n <div class=\"at-source-card-status\" [class]=\"card.StatusClass\">\n <div class=\"at-source-mini-status\" [class]=\"card.StatusClass\"></div>\n {{ card.StatusLabel }}\n </div>\n </div>\n @if (card.URL) {\n <div class=\"at-source-card-url\">{{ card.URL }}</div>\n }\n <div class=\"at-source-card-stats\">\n <div class=\"at-source-stat\">\n <div class=\"at-source-stat-value\">{{ formatNumber(card.ItemCount) }}</div>\n <div class=\"at-source-stat-label\">Items</div>\n </div>\n <div class=\"at-source-stat\">\n <div class=\"at-source-stat-value\">{{ formatNumber(card.TagCount) }}</div>\n <div class=\"at-source-stat-label\">Tags</div>\n </div>\n <div class=\"at-source-stat\">\n <div class=\"at-source-stat-value\">{{ card.AvgTags }}</div>\n <div class=\"at-source-stat-label\">Avg Tags</div>\n </div>\n <div class=\"at-source-stat\">\n <div class=\"at-source-stat-value\">{{ card.LastRunAgo }}</div>\n <div class=\"at-source-stat-label\">Last Run</div>\n </div>\n </div>\n <!-- Schedule indicator -->\n @if (card.ScheduledActionID) {\n <div class=\"at-schedule-indicator\" (click)=\"RemoveSchedule(card); $event.stopPropagation()\" title=\"Click to remove schedule\">\n <i class=\"fa-regular fa-clock\"></i>\n <span>{{ GetScheduleLabel(card) }}</span>\n </div>\n }\n <div class=\"at-source-card-actions\">\n <button class=\"at-source-action-btn\" (click)=\"onEditSource(card); $event.stopPropagation()\"><i class=\"fa-solid fa-pen\"></i> Edit</button>\n <button class=\"at-source-action-btn\" (click)=\"onRunSource(card.ID); $event.stopPropagation()\"><i class=\"fa-solid fa-play\"></i> Run</button>\n <button class=\"at-source-action-btn\" (click)=\"OpenDryRunPreview(card); $event.stopPropagation()\"><i class=\"fa-solid fa-flask\"></i> Preview</button>\n @if (!card.ScheduledActionID) {\n <button class=\"at-source-action-btn at-source-schedule-btn\" (click)=\"OpenScheduleDialog(card); $event.stopPropagation()\"><i class=\"fa-regular fa-clock\"></i> Schedule</button>\n }\n <button class=\"at-source-action-btn at-source-delete-btn\" (click)=\"DeleteSource(card); $event.stopPropagation()\"><i class=\"fa-solid fa-trash\"></i> Delete</button>\n </div>\n </div>\n }\n\n <!-- Add Source Card -->\n <div class=\"at-add-source-card\" (click)=\"onAddSource()\">\n <i class=\"fa-solid fa-plus-circle\"></i>\n <span style=\"font-size: 0.85rem; font-weight: 600;\">Add Content Source</span>\n <span style=\"font-size: 0.72rem;\">Web, RSS, Email, Files, API</span>\n </div>\n </div>\n </div>\n </div>\n</mj-page-body-interior>\n\n<!-- \u2550\u2550\u2550\u2550\u2550\u2550 SOURCE DETAIL SLIDE-IN \u2550\u2550\u2550\u2550\u2550\u2550 -->\n@if (ShowSourceDetail) {\n <div class=\"at-slide-overlay\" (click)=\"CloseSourceDetail()\"></div>\n <div class=\"at-slide-panel at-detail-panel\">\n <div class=\"at-slide-header\">\n <h3><i class=\"fa-solid fa-database\"></i> Source Detail</h3>\n <button class=\"at-slide-close\" aria-label=\"Close source detail\" (click)=\"CloseSourceDetail()\"><i class=\"fa-solid fa-times\"></i></button>\n </div>\n <div class=\"at-slide-body\">\n @if (SourceDetailLoading) {\n <div class=\"at-loading-overlay\">\n <mj-loading text=\"Loading source details...\"></mj-loading>\n </div>\n }\n @if (!SourceDetailLoading && SelectedSource) {\n <!-- Source Header -->\n <div class=\"at-detail-source-header\">\n <div class=\"at-source-card-icon\"><i [class]=\"SelectedSource.Icon\"></i></div>\n <div>\n <h4 class=\"at-detail-item-name\">{{ SelectedSource.Name }}</h4>\n <div class=\"at-detail-badges\">\n <span class=\"at-detail-badge at-detail-badge-type\">{{ SelectedSource.SourceTypeName }}</span>\n <span class=\"at-detail-badge\" [class]=\"'at-detail-badge-status-' + SelectedSource.StatusClass\">\n {{ SelectedSource.StatusLabel }}\n </span>\n </div>\n </div>\n </div>\n\n <!-- Configuration -->\n <div class=\"at-detail-section\">\n <div class=\"at-detail-section-label\">Configuration</div>\n <div class=\"at-detail-meta-grid\">\n @if (SelectedSource.URL) {\n <div class=\"at-detail-meta-row\">\n <span class=\"at-detail-meta-key\">URL</span>\n <a [href]=\"SelectedSource.URL\" target=\"_blank\" class=\"at-detail-link at-detail-meta-value\">{{ SelectedSource.URL }}</a>\n </div>\n }\n @if (SelectedSource.RequiresFileType) {\n <div class=\"at-detail-meta-row\">\n <span class=\"at-detail-meta-key\">Content Type</span>\n <span class=\"at-detail-meta-value\">{{ SelectedSource.ContentTypeName }}</span>\n </div>\n <div class=\"at-detail-meta-row\">\n <span class=\"at-detail-meta-key\">File Type</span>\n <span class=\"at-detail-meta-value\">{{ SelectedSource.FileTypeName }}</span>\n </div>\n }\n <div class=\"at-detail-meta-row\">\n <span class=\"at-detail-meta-key\">Embedding Model</span>\n <span class=\"at-detail-meta-value\">{{ SelectedSource.EmbeddingModelName }}</span>\n </div>\n <div class=\"at-detail-meta-row\">\n <span class=\"at-detail-meta-key\">Vector Index</span>\n <span class=\"at-detail-meta-value\">{{ SelectedSource.VectorIndexName }}</span>\n </div>\n </div>\n </div>\n\n <!-- Stats -->\n <div class=\"at-detail-section\">\n <div class=\"at-detail-section-label\">Statistics</div>\n <div class=\"at-detail-stats-strip\">\n <div class=\"at-detail-stat\">\n <div class=\"at-detail-stat-value\">{{ formatNumber(SelectedSource.ItemCount) }}</div>\n <div class=\"at-detail-stat-label\">Items</div>\n </div>\n <div class=\"at-detail-stat\">\n <div class=\"at-detail-stat-value\">{{ formatNumber(SelectedSource.TagCount) }}</div>\n <div class=\"at-detail-stat-label\">Tags</div>\n </div>\n <div class=\"at-detail-stat\">\n <div class=\"at-detail-stat-value\">{{ SelectedSource.AvgTags }}</div>\n <div class=\"at-detail-stat-label\">Avg Tags</div>\n </div>\n <div class=\"at-detail-stat\">\n <div class=\"at-detail-stat-value\">{{ SelectedSource.LastRunAgo }}</div>\n <div class=\"at-detail-stat-label\">Last Run</div>\n </div>\n <div class=\"at-detail-stat\">\n <div class=\"at-detail-stat-value\" [class.at-kpi-error-value]=\"SelectedSource.ErrorCount > 0\">{{ SelectedSource.ErrorCount }}</div>\n <div class=\"at-detail-stat-label\">Errors</div>\n </div>\n </div>\n </div>\n\n <!-- Content Library (status badges, pagination) -->\n <div class=\"at-detail-section\">\n <div class=\"at-detail-section-header-row\">\n <div class=\"at-detail-section-label\">Content Library ({{ FilteredSourceDetailTotal }} of {{ SelectedSource.ItemCount | number }})</div>\n <div class=\"at-detail-section-controls\">\n <select class=\"at-detail-filter-select\" [(ngModel)]=\"SourceDetailStatusFilter\" (ngModelChange)=\"OnSourceDetailStatusFilterChange()\">\n @for (opt of SourceDetailStatusOptions; track opt) {\n <option [value]=\"opt\">{{ opt }}</option>\n }\n </select>\n <button class=\"at-action-btn at-retry-btn\" (click)=\"RetryFailedItems()\" title=\"Re-queue failed items for processing\">\n <i class=\"fa-solid fa-rotate-right\"></i> Retry Failed\n </button>\n </div>\n </div>\n <div class=\"at-detail-content-list\">\n @if (FilteredSourceDetailItems.length === 0) {\n <div class=\"at-empty-state\" style=\"padding: 16px;\">\n <p>{{ SourceDetailStatusFilter === 'All' ? 'No content items yet.' : 'No items match this filter.' }}</p>\n </div>\n }\n @for (ci of FilteredSourceDetailItems; track ci.ID) {\n <div class=\"at-detail-content-item\" (click)=\"OpenContentItemDetail(ci)\">\n <div class=\"at-feed-status-dot\" [class]=\"ci.StatusDot\"></div>\n <span class=\"at-detail-content-item-name\">{{ ci.Name }}</span>\n <span class=\"at-status-badge\" [class]=\"GetStatusBadgeClass(ci.EmbeddingStatus)\">E:{{ ci.EmbeddingStatus }}</span>\n <span class=\"at-status-badge\" [class]=\"GetStatusBadgeClass(ci.TaggingStatus)\">T:{{ ci.TaggingStatus }}</span>\n <span class=\"at-detail-content-item-tags\">{{ ci.TagCount }} tags</span>\n <span class=\"at-detail-content-item-time\">{{ ci.UpdatedAt }}</span>\n </div>\n }\n </div>\n <!-- Pagination -->\n @if (SourceDetailTotalPages > 1) {\n <div class=\"at-detail-pagination\">\n <button class=\"at-page-btn\" [disabled]=\"SourceDetailPage === 0\" (click)=\"SourceDetailPrevPage()\">\n <i class=\"fa-solid fa-chevron-left\"></i> Prev\n </button>\n <span class=\"at-page-info\">Page {{ SourceDetailPage + 1 }} of {{ SourceDetailTotalPages }}</span>\n <button class=\"at-page-btn\" [disabled]=\"SourceDetailPage >= SourceDetailTotalPages - 1\" (click)=\"SourceDetailNextPage()\">\n Next <i class=\"fa-solid fa-chevron-right\"></i>\n </button>\n </div>\n }\n </div>\n\n <!-- Run History -->\n @if (SelectedSource.RunHistory.length > 0) {\n <div class=\"at-detail-section\">\n <div class=\"at-detail-section-label\">Recent Runs</div>\n <div class=\"at-detail-run-history\">\n @for (run of SelectedSource.RunHistory; track run.ID) {\n <div class=\"at-detail-run-row\">\n <span class=\"at-run-status-badge\" [class]=\"run.StatusClass\">{{ run.Status }}</span>\n <span class=\"at-detail-run-time\">{{ run.StartedDisplay }}</span>\n <span class=\"at-detail-run-duration\">{{ run.Duration }}</span>\n <span class=\"at-detail-run-items\">{{ run.Items }} items</span>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Actions -->\n <div class=\"at-detail-actions\">\n <button class=\"at-action-btn at-primary-btn\" (click)=\"OpenEditSourceFromDetail()\">\n <i class=\"fa-solid fa-pen\"></i> Edit\n </button>\n <button class=\"at-action-btn at-secondary-btn\" (click)=\"RunSourceFromDetail()\">\n <i class=\"fa-solid fa-play\"></i> Run Now\n </button>\n <button class=\"at-action-btn at-secondary-btn at-source-delete-btn\" (click)=\"DeleteSourceFromDetail()\">\n <i class=\"fa-solid fa-trash\"></i> Delete\n </button>\n </div>\n }\n </div>\n </div>\n}\n\n<!-- \u2550\u2550\u2550\u2550\u2550\u2550 SCHEDULE DIALOG \u2550\u2550\u2550\u2550\u2550\u2550 -->\n@if (ShowScheduleDialog && SchedulingSourceCard) {\n <div class=\"at-schedule-overlay\" (click)=\"CloseScheduleDialog()\">\n <div class=\"at-schedule-dialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"at-schedule-dialog-header\">\n <h3><i class=\"fa-regular fa-clock\"></i> Schedule Pipeline</h3>\n <button class=\"at-schedule-dialog-close\" (click)=\"CloseScheduleDialog()\" aria-label=\"Close\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n <div class=\"at-schedule-dialog-body\">\n <div class=\"at-schedule-field\">\n <label>Source</label>\n <div class=\"at-schedule-source-name\">\n <i [class]=\"SchedulingSourceCard.Icon\"></i>\n {{ SchedulingSourceCard.Name }}\n </div>\n </div>\n <div class=\"at-schedule-field\">\n <label>Action</label>\n <div class=\"at-schedule-action-name\">Autotag and Vectorize Content</div>\n </div>\n <div class=\"at-schedule-field\">\n <label for=\"schedule-cron\">Cron Expression</label>\n <input id=\"schedule-cron\"\n type=\"text\"\n class=\"mj-input at-schedule-cron-input\"\n [(ngModel)]=\"ScheduleCron\"\n placeholder=\"0 2 * * *\" />\n <div class=\"at-schedule-cron-preview\">\n <i class=\"fa-solid fa-info-circle\"></i>\n {{ GetCronPreview(ScheduleCron) }}\n </div>\n </div>\n <div class=\"at-schedule-field at-schedule-toggle-row\">\n <label for=\"schedule-enabled\">Enabled</label>\n <input id=\"schedule-enabled\"\n type=\"checkbox\"\n class=\"mj-checkbox\"\n [(ngModel)]=\"ScheduleEnabled\" />\n </div>\n </div>\n <div class=\"at-schedule-dialog-footer\">\n <button class=\"at-action-btn at-primary-btn\" (click)=\"SaveSchedule()\" [disabled]=\"ScheduleSaving\">\n @if (ScheduleSaving) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Saving...\n } @else {\n <i class=\"fa-solid fa-check\"></i> Create Schedule\n }\n </button>\n <button class=\"at-action-btn at-secondary-btn\" (click)=\"CloseScheduleDialog()\">Cancel</button>\n </div>\n </div>\n </div>\n}\n\n<!-- \u2550\u2550\u2550\u2550\u2550\u2550 DRY-RUN DISPOSITION PREVIEW (in-memory, nothing persisted) \u2550\u2550\u2550\u2550\u2550\u2550 -->\n<classify-dry-run-preview\n [Provider]=\"Provider\"\n [Show]=\"ShowDryRunPreview\"\n [SourceCard]=\"DryRunSourceCard\"\n (Closed)=\"CloseDryRunPreview()\">\n</classify-dry-run-preview>\n", styles: ["/*\n * Content Sources tab styles.\n *\n * The host (AutotaggingPipelineResourceComponent) uses ViewEncapsulation.None,\n * so its `.at-*` rules are global and already style this tab's markup (cards,\n * source-detail slide-in, schedule dialog) while it renders inside the host\n * shell. Tab-specific rules would live here; none are needed during the\n * host-slim step.\n */\n\n.at-sources-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n text-align: center;\n gap: 10px;\n padding: 48px 24px;\n background: var(--mj-bg-surface-card);\n border: 1px dashed var(--mj-border-default);\n border-radius: 12px;\n}\n.at-sources-empty > i {\n font-size: 2rem;\n color: var(--mj-brand-primary);\n}\n.at-sources-empty h3 {\n margin: 0;\n font-size: 1rem;\n color: var(--mj-text-primary);\n}\n.at-sources-empty p {\n margin: 0;\n max-width: 460px;\n font-size: 0.85rem;\n color: var(--mj-text-muted);\n line-height: 1.5;\n}\n.at-sources-empty-actions {\n display: flex;\n gap: 8px;\n margin-top: 6px;\n}\n"] }]
1435
+ }], null, { Sources: [{
1436
+ type: Input
1437
+ }], Items: [{
1438
+ type: Input
1439
+ }], Tags: [{
1440
+ type: Input
1441
+ }], Runs: [{
1442
+ type: Input
1443
+ }], TotalItemCount: [{
1444
+ type: Input
1445
+ }], TotalTagCount: [{
1446
+ type: Input
1447
+ }], ScheduledActions: [{
1448
+ type: Input
1449
+ }], EntityRecordDocCache: [{
1450
+ type: Input
1451
+ }], AddSourceRequested: [{
1452
+ type: Output
1453
+ }], AddSourceGuidedRequested: [{
1454
+ type: Output
1455
+ }], EditSourceRequested: [{
1456
+ type: Output
1457
+ }], RunSourceRequested: [{
1458
+ type: Output
1459
+ }], OpenContentItemRequested: [{
1460
+ type: Output
1461
+ }], DataChanged: [{
1462
+ type: Output
1463
+ }] }); })();
1464
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ClassifySourcesTabComponent, { className: "ClassifySourcesTabComponent", filePath: "src/AI/components/autotagging/tabs/sources-tab.component.ts", lineNumber: 34 }); })();
1465
+ //# sourceMappingURL=sources-tab.component.js.map