@memberjunction/ng-dashboards 5.39.0 → 5.40.1

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 (129) hide show
  1. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts +128 -4
  2. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts.map +1 -1
  3. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js +548 -145
  4. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js.map +1 -1
  5. package/dist/AI/components/autotagging/components/classify-item-drilldown.component.d.ts +56 -0
  6. package/dist/AI/components/autotagging/components/classify-item-drilldown.component.d.ts.map +1 -0
  7. package/dist/AI/components/autotagging/components/classify-item-drilldown.component.js +423 -0
  8. package/dist/AI/components/autotagging/components/classify-item-drilldown.component.js.map +1 -0
  9. package/dist/AI/components/autotagging/components/classify-item-grid.component.d.ts +70 -0
  10. package/dist/AI/components/autotagging/components/classify-item-grid.component.d.ts.map +1 -0
  11. package/dist/AI/components/autotagging/components/classify-item-grid.component.js +308 -0
  12. package/dist/AI/components/autotagging/components/classify-item-grid.component.js.map +1 -0
  13. package/dist/AI/components/autotagging/components/classify-org-context-editor.component.d.ts +29 -0
  14. package/dist/AI/components/autotagging/components/classify-org-context-editor.component.d.ts.map +1 -0
  15. package/dist/AI/components/autotagging/components/classify-org-context-editor.component.js +186 -0
  16. package/dist/AI/components/autotagging/components/classify-org-context-editor.component.js.map +1 -0
  17. package/dist/AI/components/autotagging/components/classify-overview-analytics.component.d.ts +69 -0
  18. package/dist/AI/components/autotagging/components/classify-overview-analytics.component.d.ts.map +1 -0
  19. package/dist/AI/components/autotagging/components/classify-overview-analytics.component.js +278 -0
  20. package/dist/AI/components/autotagging/components/classify-overview-analytics.component.js.map +1 -0
  21. package/dist/AI/components/autotagging/components/classify-seed-taxonomy.component.d.ts +73 -0
  22. package/dist/AI/components/autotagging/components/classify-seed-taxonomy.component.d.ts.map +1 -0
  23. package/dist/AI/components/autotagging/components/classify-seed-taxonomy.component.js +393 -0
  24. package/dist/AI/components/autotagging/components/classify-seed-taxonomy.component.js.map +1 -0
  25. package/dist/AI/components/autotagging/dialogs/classify-setup-wizard.component.d.ts +122 -0
  26. package/dist/AI/components/autotagging/dialogs/classify-setup-wizard.component.d.ts.map +1 -0
  27. package/dist/AI/components/autotagging/dialogs/classify-setup-wizard.component.js +908 -0
  28. package/dist/AI/components/autotagging/dialogs/classify-setup-wizard.component.js.map +1 -0
  29. package/dist/AI/components/autotagging/dialogs/source-type-form.dialog.component.d.ts +100 -2
  30. package/dist/AI/components/autotagging/dialogs/source-type-form.dialog.component.d.ts.map +1 -1
  31. package/dist/AI/components/autotagging/dialogs/source-type-form.dialog.component.js +603 -213
  32. package/dist/AI/components/autotagging/dialogs/source-type-form.dialog.component.js.map +1 -1
  33. package/dist/AI/components/autotagging/shared/classify.format.d.ts +15 -0
  34. package/dist/AI/components/autotagging/shared/classify.format.d.ts.map +1 -1
  35. package/dist/AI/components/autotagging/shared/classify.format.js +51 -0
  36. package/dist/AI/components/autotagging/shared/classify.format.js.map +1 -1
  37. package/dist/AI/components/autotagging/shared/classify.types.d.ts +43 -0
  38. package/dist/AI/components/autotagging/shared/classify.types.d.ts.map +1 -1
  39. package/dist/AI/components/autotagging/shared/classify.types.js.map +1 -1
  40. package/dist/AI/components/autotagging/tabs/history-tab.component.d.ts +38 -1
  41. package/dist/AI/components/autotagging/tabs/history-tab.component.d.ts.map +1 -1
  42. package/dist/AI/components/autotagging/tabs/history-tab.component.js +185 -68
  43. package/dist/AI/components/autotagging/tabs/history-tab.component.js.map +1 -1
  44. package/dist/AI/components/autotagging/tabs/pipeline-tab.component.d.ts +10 -1
  45. package/dist/AI/components/autotagging/tabs/pipeline-tab.component.d.ts.map +1 -1
  46. package/dist/AI/components/autotagging/tabs/pipeline-tab.component.js +249 -188
  47. package/dist/AI/components/autotagging/tabs/pipeline-tab.component.js.map +1 -1
  48. package/dist/AI/components/autotagging/tabs/sources-tab.component.d.ts +12 -1
  49. package/dist/AI/components/autotagging/tabs/sources-tab.component.d.ts.map +1 -1
  50. package/dist/AI/components/autotagging/tabs/sources-tab.component.js +377 -296
  51. package/dist/AI/components/autotagging/tabs/sources-tab.component.js.map +1 -1
  52. package/dist/AI/components/autotagging/tabs/tags-tab.component.d.ts +8 -0
  53. package/dist/AI/components/autotagging/tabs/tags-tab.component.d.ts.map +1 -1
  54. package/dist/AI/components/autotagging/tabs/tags-tab.component.js +112 -68
  55. package/dist/AI/components/autotagging/tabs/tags-tab.component.js.map +1 -1
  56. package/dist/AI/components/autotagging/tabs/types-tab.component.d.ts +9 -0
  57. package/dist/AI/components/autotagging/tabs/types-tab.component.d.ts.map +1 -1
  58. package/dist/AI/components/autotagging/tabs/types-tab.component.js +87 -36
  59. package/dist/AI/components/autotagging/tabs/types-tab.component.js.map +1 -1
  60. package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts +3 -0
  61. package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts.map +1 -1
  62. package/dist/AI/components/duplicates/duplicate-detection-resource.component.js +15 -3
  63. package/dist/AI/components/duplicates/duplicate-detection-resource.component.js.map +1 -1
  64. package/dist/AI/components/execution-monitoring.component.js +1 -1
  65. package/dist/AI/components/execution-monitoring.component.js.map +1 -1
  66. package/dist/AI/components/tags/tags-resource.component.d.ts +1 -0
  67. package/dist/AI/components/tags/tags-resource.component.d.ts.map +1 -1
  68. package/dist/AI/components/tags/tags-resource.component.js +28 -6
  69. package/dist/AI/components/tags/tags-resource.component.js.map +1 -1
  70. package/dist/AI/components/vectors/vector-management-resource.component.d.ts +3 -0
  71. package/dist/AI/components/vectors/vector-management-resource.component.d.ts.map +1 -1
  72. package/dist/AI/components/vectors/vector-management-resource.component.js +330 -302
  73. package/dist/AI/components/vectors/vector-management-resource.component.js.map +1 -1
  74. package/dist/APIKeys/api-applications-panel.component.js +2 -2
  75. package/dist/APIKeys/api-key-create-dialog.component.js +2 -2
  76. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +31 -340
  77. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
  78. package/dist/DataExplorer/data-explorer-dashboard.component.js +468 -1958
  79. package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
  80. package/dist/DataExplorer/data-explorer-resource.component.d.ts.map +1 -1
  81. package/dist/DataExplorer/data-explorer-resource.component.js +10 -0
  82. package/dist/DataExplorer/data-explorer-resource.component.js.map +1 -1
  83. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.d.ts.map +1 -1
  84. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js +12 -9
  85. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js.map +1 -1
  86. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.d.ts +27 -2
  87. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.d.ts.map +1 -1
  88. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js +244 -120
  89. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js.map +1 -1
  90. package/dist/KnowledgeHub/components/visualize/record-drilldown/record-drilldown.component.d.ts +65 -0
  91. package/dist/KnowledgeHub/components/visualize/record-drilldown/record-drilldown.component.d.ts.map +1 -0
  92. package/dist/KnowledgeHub/components/visualize/record-drilldown/record-drilldown.component.js +176 -0
  93. package/dist/KnowledgeHub/components/visualize/record-drilldown/record-drilldown.component.js.map +1 -0
  94. package/dist/KnowledgeHub/components/visualize/tag-cloud/tag-cloud.component.d.ts +81 -0
  95. package/dist/KnowledgeHub/components/visualize/tag-cloud/tag-cloud.component.d.ts.map +1 -0
  96. package/dist/KnowledgeHub/components/visualize/tag-cloud/tag-cloud.component.js +308 -0
  97. package/dist/KnowledgeHub/components/visualize/tag-cloud/tag-cloud.component.js.map +1 -0
  98. package/dist/KnowledgeHub/components/visualize/visualize-resource.component.d.ts +85 -0
  99. package/dist/KnowledgeHub/components/visualize/visualize-resource.component.d.ts.map +1 -0
  100. package/dist/KnowledgeHub/components/visualize/visualize-resource.component.js +362 -0
  101. package/dist/KnowledgeHub/components/visualize/visualize-resource.component.js.map +1 -0
  102. package/dist/KnowledgeHub/index.d.ts +3 -0
  103. package/dist/KnowledgeHub/index.d.ts.map +1 -1
  104. package/dist/KnowledgeHub/index.js +3 -0
  105. package/dist/KnowledgeHub/index.js.map +1 -1
  106. package/dist/MCP/components/mcp-server-dialog.component.js +2 -2
  107. package/dist/QueryBrowser/query-browser-resource.component.js +1 -1
  108. package/dist/QueryBrowser/query-browser-resource.component.js.map +1 -1
  109. package/dist/ai-dashboards.module.d.ts +48 -38
  110. package/dist/ai-dashboards.module.d.ts.map +1 -1
  111. package/dist/ai-dashboards.module.js +41 -1
  112. package/dist/ai-dashboards.module.js.map +1 -1
  113. package/dist/data-explorer-dashboards.module.d.ts +12 -14
  114. package/dist/data-explorer-dashboards.module.d.ts.map +1 -1
  115. package/dist/data-explorer-dashboards.module.js +5 -14
  116. package/dist/data-explorer-dashboards.module.js.map +1 -1
  117. package/dist/public-api.d.ts +3 -0
  118. package/dist/public-api.d.ts.map +1 -1
  119. package/dist/public-api.js +3 -0
  120. package/dist/public-api.js.map +1 -1
  121. package/package.json +57 -55
  122. package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.d.ts +0 -79
  123. package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.d.ts.map +0 -1
  124. package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.js +0 -195
  125. package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.js.map +0 -1
  126. package/dist/DataExplorer/components/view-selector/view-selector.component.d.ts +0 -226
  127. package/dist/DataExplorer/components/view-selector/view-selector.component.d.ts.map +0 -1
  128. package/dist/DataExplorer/components/view-selector/view-selector.component.js +0 -861
  129. package/dist/DataExplorer/components/view-selector/view-selector.component.js.map +0 -1
@@ -6,33 +6,46 @@
6
6
  * via `[Runs]` (the host is the data orchestrator); loads per-run detail rows
7
7
  * on demand itself. Cross-tab navigation (none today) would bubble via @Output.
8
8
  */
9
- import { Component, ChangeDetectorRef, Input, inject } from '@angular/core';
9
+ import { Component, ChangeDetectorRef, EventEmitter, Input, Output, inject } from '@angular/core';
10
10
  import { RunView } from '@memberjunction/core';
11
11
  import { BaseAngularComponent } from '@memberjunction/ng-base-types';
12
12
  import { formatNumber, formatDate, computeDuration, displayStatus, formatTokenCount, mapRunDetailRecords } from '../shared/classify.format';
13
13
  import * as i0 from "@angular/core";
14
14
  import * as i1 from "@memberjunction/ng-shared-generic";
15
15
  import * as i2 from "@memberjunction/ng-ui-components";
16
+ import * as i3 from "../components/classify-item-grid.component";
16
17
  const _forTrack0 = ($index, $item) => $item.ID;
17
18
  const _forTrack1 = ($index, $item) => $item.SourceName;
18
- function ClassifyHistoryTabComponent_For_28_Conditional_3_Template(rf, ctx) { if (rf & 1) {
19
- i0.ɵɵelement(0, "i", 14);
19
+ function ClassifyHistoryTabComponent_Conditional_3_Template(rf, ctx) { if (rf & 1) {
20
+ i0.ɵɵelement(0, "i", 15);
21
+ i0.ɵɵelementStart(1, "span", 16);
22
+ i0.ɵɵtext(2, "Refreshing\u2026");
23
+ i0.ɵɵelementEnd();
24
+ } }
25
+ function ClassifyHistoryTabComponent_Conditional_4_Template(rf, ctx) { if (rf & 1) {
26
+ i0.ɵɵelement(0, "i", 17);
27
+ i0.ɵɵelementStart(1, "span", 16);
28
+ i0.ɵɵtext(2, "Refresh");
29
+ i0.ɵɵelementEnd();
20
30
  } }
21
- function ClassifyHistoryTabComponent_For_28_Template(rf, ctx) { if (rf & 1) {
31
+ function ClassifyHistoryTabComponent_For_32_Conditional_3_Template(rf, ctx) { if (rf & 1) {
32
+ i0.ɵɵelement(0, "i", 20);
33
+ } }
34
+ function ClassifyHistoryTabComponent_For_32_Template(rf, ctx) { if (rf & 1) {
22
35
  const _r1 = i0.ɵɵgetCurrentView();
23
- i0.ɵɵelementStart(0, "tr", 12);
24
- i0.ɵɵlistener("click", function ClassifyHistoryTabComponent_For_28_Template_tr_click_0_listener() { const row_r2 = i0.ɵɵrestoreView(_r1).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OpenRunDetail(row_r2.ID)); });
25
- i0.ɵɵelementStart(1, "td")(2, "span", 13);
26
- i0.ɵɵconditionalCreate(3, ClassifyHistoryTabComponent_For_28_Conditional_3_Template, 1, 0, "i", 14);
36
+ i0.ɵɵelementStart(0, "tr", 18);
37
+ i0.ɵɵlistener("click", function ClassifyHistoryTabComponent_For_32_Template_tr_click_0_listener() { const row_r2 = i0.ɵɵrestoreView(_r1).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OpenRunDetail(row_r2.ID)); });
38
+ i0.ɵɵelementStart(1, "td")(2, "span", 19);
39
+ i0.ɵɵconditionalCreate(3, ClassifyHistoryTabComponent_For_32_Conditional_3_Template, 1, 0, "i", 20);
27
40
  i0.ɵɵtext(4);
28
41
  i0.ɵɵelementEnd()();
29
- i0.ɵɵelementStart(5, "td", 15);
42
+ i0.ɵɵelementStart(5, "td", 21);
30
43
  i0.ɵɵtext(6);
31
44
  i0.ɵɵelementEnd();
32
45
  i0.ɵɵelementStart(7, "td");
33
46
  i0.ɵɵtext(8);
34
47
  i0.ɵɵelementEnd();
35
- i0.ɵɵelementStart(9, "td", 16);
48
+ i0.ɵɵelementStart(9, "td", 22);
36
49
  i0.ɵɵtext(10);
37
50
  i0.ɵɵelementEnd();
38
51
  i0.ɵɵelementStart(11, "td");
@@ -69,17 +82,50 @@ function ClassifyHistoryTabComponent_For_28_Template(rf, ctx) { if (rf & 1) {
69
82
  i0.ɵɵadvance();
70
83
  i0.ɵɵtextInterpolate(row_r2.Errors);
71
84
  } }
72
- function ClassifyHistoryTabComponent_Conditional_29_Conditional_9_Template(rf, ctx) { if (rf & 1) {
73
- i0.ɵɵelement(0, "mj-loading", 23);
85
+ function ClassifyHistoryTabComponent_Conditional_33_Conditional_3_Conditional_1_Template(rf, ctx) { if (rf & 1) {
86
+ i0.ɵɵelement(0, "i", 15);
87
+ i0.ɵɵtext(1, " Loading\u2026 ");
88
+ } }
89
+ function ClassifyHistoryTabComponent_Conditional_33_Conditional_3_Conditional_2_Template(rf, ctx) { if (rf & 1) {
90
+ i0.ɵɵelement(0, "i", 25);
91
+ i0.ɵɵtext(1, " Load more ");
92
+ } }
93
+ function ClassifyHistoryTabComponent_Conditional_33_Conditional_3_Template(rf, ctx) { if (rf & 1) {
94
+ const _r4 = i0.ɵɵgetCurrentView();
95
+ i0.ɵɵelementStart(0, "button", 2);
96
+ i0.ɵɵlistener("click", function ClassifyHistoryTabComponent_Conditional_33_Conditional_3_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.onLoadMore()); });
97
+ i0.ɵɵconditionalCreate(1, ClassifyHistoryTabComponent_Conditional_33_Conditional_3_Conditional_1_Template, 2, 0)(2, ClassifyHistoryTabComponent_Conditional_33_Conditional_3_Conditional_2_Template, 2, 0);
98
+ i0.ɵɵelementEnd();
99
+ } if (rf & 2) {
100
+ const ctx_r2 = i0.ɵɵnextContext(2);
101
+ i0.ɵɵproperty("disabled", ctx_r2.IsLoadingMore);
102
+ i0.ɵɵadvance();
103
+ i0.ɵɵconditional(ctx_r2.IsLoadingMore ? 1 : 2);
104
+ } }
105
+ function ClassifyHistoryTabComponent_Conditional_33_Template(rf, ctx) { if (rf & 1) {
106
+ i0.ɵɵelementStart(0, "div", 13)(1, "span", 23);
107
+ i0.ɵɵtext(2);
108
+ i0.ɵɵelementEnd();
109
+ i0.ɵɵconditionalCreate(3, ClassifyHistoryTabComponent_Conditional_33_Conditional_3_Template, 3, 2, "button", 24);
110
+ i0.ɵɵelementEnd();
111
+ } if (rf & 2) {
112
+ const ctx_r2 = i0.ɵɵnextContext();
113
+ i0.ɵɵadvance(2);
114
+ i0.ɵɵtextInterpolate2("Showing ", ctx_r2.FilteredRunRows.length, " of ", ctx_r2.TotalRunCount, " runs");
115
+ i0.ɵɵadvance();
116
+ i0.ɵɵconditional(ctx_r2.HasMoreRuns ? 3 : -1);
117
+ } }
118
+ function ClassifyHistoryTabComponent_Conditional_34_Conditional_9_Template(rf, ctx) { if (rf & 1) {
119
+ i0.ɵɵelement(0, "mj-loading", 32);
74
120
  } }
75
- function ClassifyHistoryTabComponent_Conditional_29_Conditional_10_For_25_Template(rf, ctx) { if (rf & 1) {
76
- i0.ɵɵelementStart(0, "tr")(1, "td", 15);
121
+ function ClassifyHistoryTabComponent_Conditional_34_Conditional_10_For_25_Template(rf, ctx) { if (rf & 1) {
122
+ i0.ɵɵelementStart(0, "tr")(1, "td", 21);
77
123
  i0.ɵɵtext(2);
78
124
  i0.ɵɵelementEnd();
79
125
  i0.ɵɵelementStart(3, "td");
80
126
  i0.ɵɵtext(4);
81
127
  i0.ɵɵelementEnd();
82
- i0.ɵɵelementStart(5, "td")(6, "span", 13);
128
+ i0.ɵɵelementStart(5, "td")(6, "span", 19);
83
129
  i0.ɵɵtext(7);
84
130
  i0.ɵɵelementEnd()();
85
131
  i0.ɵɵelementStart(8, "td");
@@ -100,39 +146,39 @@ function ClassifyHistoryTabComponent_Conditional_29_Conditional_10_For_25_Templa
100
146
  i0.ɵɵelementStart(18, "td");
101
147
  i0.ɵɵtext(19);
102
148
  i0.ɵɵelementEnd();
103
- i0.ɵɵelementStart(20, "td", 16);
149
+ i0.ɵɵelementStart(20, "td", 22);
104
150
  i0.ɵɵtext(21);
105
151
  i0.ɵɵelementEnd()();
106
152
  } if (rf & 2) {
107
- const detail_r5 = ctx.$implicit;
153
+ const detail_r6 = ctx.$implicit;
108
154
  const ctx_r2 = i0.ɵɵnextContext(3);
109
155
  i0.ɵɵadvance(2);
110
- i0.ɵɵtextInterpolate(detail_r5.SourceName);
156
+ i0.ɵɵtextInterpolate(detail_r6.SourceName);
111
157
  i0.ɵɵadvance(2);
112
- i0.ɵɵtextInterpolate(detail_r5.SourceType);
158
+ i0.ɵɵtextInterpolate(detail_r6.SourceType);
113
159
  i0.ɵɵadvance(2);
114
- i0.ɵɵclassMap(detail_r5.StatusClass);
160
+ i0.ɵɵclassMap(detail_r6.StatusClass);
115
161
  i0.ɵɵadvance();
116
- i0.ɵɵtextInterpolate(detail_r5.Status);
162
+ i0.ɵɵtextInterpolate(detail_r6.Status);
117
163
  i0.ɵɵadvance(2);
118
- i0.ɵɵtextInterpolate(detail_r5.ItemsProcessed);
164
+ i0.ɵɵtextInterpolate(detail_r6.ItemsProcessed);
119
165
  i0.ɵɵadvance(2);
120
- i0.ɵɵtextInterpolate(detail_r5.ItemsTagged);
166
+ i0.ɵɵtextInterpolate(detail_r6.ItemsTagged);
121
167
  i0.ɵɵadvance(2);
122
- i0.ɵɵtextInterpolate(detail_r5.ItemsVectorized);
168
+ i0.ɵɵtextInterpolate(detail_r6.ItemsVectorized);
123
169
  i0.ɵɵadvance();
124
- i0.ɵɵclassProp("run-error-text", detail_r5.ErrorCount > 0);
170
+ i0.ɵɵclassProp("run-error-text", detail_r6.ErrorCount > 0);
125
171
  i0.ɵɵadvance();
126
- i0.ɵɵtextInterpolate(detail_r5.ErrorCount);
172
+ i0.ɵɵtextInterpolate(detail_r6.ErrorCount);
127
173
  i0.ɵɵadvance(2);
128
- i0.ɵɵtextInterpolate(ctx_r2.FormatTokenCount(detail_r5.TotalTokens));
174
+ i0.ɵɵtextInterpolate(ctx_r2.FormatTokenCount(detail_r6.TotalTokens));
129
175
  i0.ɵɵadvance(2);
130
- i0.ɵɵtextInterpolate(detail_r5.TotalCost > 0 ? "$" + detail_r5.TotalCost.toFixed(4) : "$0.00");
176
+ i0.ɵɵtextInterpolate(detail_r6.TotalCost > 0 ? "$" + detail_r6.TotalCost.toFixed(4) : "$0.00");
131
177
  i0.ɵɵadvance(2);
132
- i0.ɵɵtextInterpolate(detail_r5.Duration);
178
+ i0.ɵɵtextInterpolate(detail_r6.Duration);
133
179
  } }
134
- function ClassifyHistoryTabComponent_Conditional_29_Conditional_10_Template(rf, ctx) { if (rf & 1) {
135
- i0.ɵɵelementStart(0, "table", 9)(1, "thead")(2, "tr")(3, "th");
180
+ function ClassifyHistoryTabComponent_Conditional_34_Conditional_10_Template(rf, ctx) { if (rf & 1) {
181
+ i0.ɵɵelementStart(0, "table", 11)(1, "thead")(2, "tr")(3, "th");
136
182
  i0.ɵɵtext(4, "Source");
137
183
  i0.ɵɵelementEnd();
138
184
  i0.ɵɵelementStart(5, "th");
@@ -163,40 +209,48 @@ function ClassifyHistoryTabComponent_Conditional_29_Conditional_10_Template(rf,
163
209
  i0.ɵɵtext(22, "Duration");
164
210
  i0.ɵɵelementEnd()()();
165
211
  i0.ɵɵelementStart(23, "tbody");
166
- i0.ɵɵrepeaterCreate(24, ClassifyHistoryTabComponent_Conditional_29_Conditional_10_For_25_Template, 22, 14, "tr", null, _forTrack1);
212
+ i0.ɵɵrepeaterCreate(24, ClassifyHistoryTabComponent_Conditional_34_Conditional_10_For_25_Template, 22, 14, "tr", null, _forTrack1);
167
213
  i0.ɵɵelementEnd()();
168
214
  } if (rf & 2) {
169
215
  const ctx_r2 = i0.ɵɵnextContext(2);
170
216
  i0.ɵɵadvance(24);
171
217
  i0.ɵɵrepeater(ctx_r2.RunDetailRows);
172
218
  } }
173
- function ClassifyHistoryTabComponent_Conditional_29_Conditional_11_Template(rf, ctx) { if (rf & 1) {
174
- i0.ɵɵelementStart(0, "div", 24);
175
- i0.ɵɵelement(1, "i", 25);
219
+ function ClassifyHistoryTabComponent_Conditional_34_Conditional_11_Template(rf, ctx) { if (rf & 1) {
220
+ i0.ɵɵelementStart(0, "div", 33);
221
+ i0.ɵɵelement(1, "i", 38);
176
222
  i0.ɵɵelementStart(2, "p");
177
223
  i0.ɵɵtext(3, "No per-source detail records found for this run.");
178
224
  i0.ɵɵelementEnd()();
179
225
  } }
180
- function ClassifyHistoryTabComponent_Conditional_29_Template(rf, ctx) { if (rf & 1) {
181
- const _r4 = i0.ɵɵgetCurrentView();
182
- i0.ɵɵelementStart(0, "div", 11)(1, "div", 17)(2, "span", 18);
183
- i0.ɵɵelement(3, "i", 19);
226
+ function ClassifyHistoryTabComponent_Conditional_34_Template(rf, ctx) { if (rf & 1) {
227
+ const _r5 = i0.ɵɵgetCurrentView();
228
+ i0.ɵɵelementStart(0, "div", 14)(1, "div", 26)(2, "span", 27);
229
+ i0.ɵɵelement(3, "i", 28);
184
230
  i0.ɵɵtext(4);
185
231
  i0.ɵɵelementEnd();
186
- i0.ɵɵelementStart(5, "button", 20);
187
- i0.ɵɵlistener("click", function ClassifyHistoryTabComponent_Conditional_29_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.CloseRunDetail()); });
188
- i0.ɵɵelement(6, "i", 21);
232
+ i0.ɵɵelementStart(5, "button", 29);
233
+ i0.ɵɵlistener("click", function ClassifyHistoryTabComponent_Conditional_34_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r5); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.CloseRunDetail()); });
234
+ i0.ɵɵelement(6, "i", 30);
189
235
  i0.ɵɵtext(7, " Close ");
190
236
  i0.ɵɵelementEnd()();
191
- i0.ɵɵelementStart(8, "div", 22);
192
- i0.ɵɵconditionalCreate(9, ClassifyHistoryTabComponent_Conditional_29_Conditional_9_Template, 1, 0, "mj-loading", 23)(10, ClassifyHistoryTabComponent_Conditional_29_Conditional_10_Template, 26, 0, "table", 9)(11, ClassifyHistoryTabComponent_Conditional_29_Conditional_11_Template, 4, 0, "div", 24);
237
+ i0.ɵɵelementStart(8, "div", 31);
238
+ i0.ɵɵconditionalCreate(9, ClassifyHistoryTabComponent_Conditional_34_Conditional_9_Template, 1, 0, "mj-loading", 32)(10, ClassifyHistoryTabComponent_Conditional_34_Conditional_10_Template, 26, 0, "table", 11)(11, ClassifyHistoryTabComponent_Conditional_34_Conditional_11_Template, 4, 0, "div", 33);
239
+ i0.ɵɵelementStart(12, "div", 34)(13, "div", 35)(14, "span", 27);
240
+ i0.ɵɵelement(15, "i", 36);
241
+ i0.ɵɵtext(16, " Items in this run ");
193
242
  i0.ɵɵelementEnd()();
243
+ i0.ɵɵelementStart(17, "classify-item-grid", 37);
244
+ i0.ɵɵlistener("ItemSelected", function ClassifyHistoryTabComponent_Conditional_34_Template_classify_item_grid_ItemSelected_17_listener($event) { i0.ɵɵrestoreView(_r5); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.onItemSelected($event)); });
245
+ i0.ɵɵelementEnd()()()();
194
246
  } if (rf & 2) {
195
247
  const ctx_r2 = i0.ɵɵnextContext();
196
248
  i0.ɵɵadvance(4);
197
249
  i0.ɵɵtextInterpolate1(" Run Detail: ", ctx_r2.SelectedRunID.slice(0, 14), "... ");
198
250
  i0.ɵɵadvance(5);
199
251
  i0.ɵɵconditional(ctx_r2.IsLoadingRunDetail ? 9 : ctx_r2.RunDetailRows.length > 0 ? 10 : 11);
252
+ i0.ɵɵadvance(8);
253
+ i0.ɵɵproperty("RunID", ctx_r2.SelectedRunID)("Provider", ctx_r2.Provider);
200
254
  } }
201
255
  export class ClassifyHistoryTabComponent extends BaseAngularComponent {
202
256
  cdr = inject(ChangeDetectorRef);
@@ -207,10 +261,42 @@ export class ClassifyHistoryTabComponent extends BaseAngularComponent {
207
261
  this.buildRunHistoryRows();
208
262
  this.buildHistorySourceOptions();
209
263
  this.FilterRunHistory();
264
+ // A fresh Runs binding (from the host reload) ends any in-flight refresh.
265
+ this.IsLoading = false;
266
+ this.cdr.detectChanges();
210
267
  }
211
268
  get Runs() {
212
269
  return this._runs;
213
270
  }
271
+ /** Total run count in the DB (from TotalRowCount) — drives the "Showing X of Y" line. */
272
+ TotalRunCount = 0;
273
+ /** True while the host is fetching the next page in response to LoadMoreRequested. */
274
+ IsLoadingMore = false;
275
+ /** Bubble a "load more" request to the host, which widens the loaded window. */
276
+ LoadMoreRequested = new EventEmitter();
277
+ /**
278
+ * Bubble a content-item selection (from the per-run item grid) up to the host,
279
+ * which owns NavigationService + the drilldown slide-in.
280
+ */
281
+ ItemSelected = new EventEmitter();
282
+ onItemSelected(itemID) {
283
+ this.ItemSelected.emit(itemID);
284
+ }
285
+ /** Whether more runs exist in the DB than are currently loaded. */
286
+ get HasMoreRuns() {
287
+ return this.TotalRunCount > this._runs.length;
288
+ }
289
+ onLoadMore() {
290
+ this.LoadMoreRequested.emit();
291
+ }
292
+ /** Shown while the host reloads the run list in response to RefreshRequested. */
293
+ IsLoading = false;
294
+ /**
295
+ * Bubble a refresh request up to the host, which owns the run-history data
296
+ * (`MJ: Content Process Runs`). The host reloads and re-binds `[Runs]`, whose
297
+ * setter rebuilds the rows; the host also clears IsLoading via [Loading].
298
+ */
299
+ RefreshRequested = new EventEmitter();
214
300
  RunHistoryRows = [];
215
301
  FilteredRunRows = [];
216
302
  HistorySourceFilter = '';
@@ -222,6 +308,15 @@ export class ClassifyHistoryTabComponent extends BaseAngularComponent {
222
308
  IsLoadingRunDetail = false;
223
309
  // Template-facing formatters
224
310
  FormatTokenCount = formatTokenCount;
311
+ /**
312
+ * Ask the host to reload the run history. Data is host-owned, so we surface a
313
+ * loading state and emit; the new `[Runs]` binding clears IsLoading.
314
+ */
315
+ Refresh() {
316
+ this.IsLoading = true;
317
+ this.cdr.detectChanges();
318
+ this.RefreshRequested.emit();
319
+ }
225
320
  buildRunHistoryRows() {
226
321
  this.RunHistoryRows = this._runs.map(run => {
227
322
  const status = run['Status'] ?? 'Unknown';
@@ -347,40 +442,50 @@ export class ClassifyHistoryTabComponent extends BaseAngularComponent {
347
442
  }
348
443
  }
349
444
  static ɵfac = /*@__PURE__*/ (() => { let ɵClassifyHistoryTabComponent_BaseFactory; return function ClassifyHistoryTabComponent_Factory(__ngFactoryType__) { return (ɵClassifyHistoryTabComponent_BaseFactory || (ɵClassifyHistoryTabComponent_BaseFactory = i0.ɵɵgetInheritedFactory(ClassifyHistoryTabComponent)))(__ngFactoryType__ || ClassifyHistoryTabComponent); }; })();
350
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ClassifyHistoryTabComponent, selectors: [["classify-history-tab"]], inputs: { Runs: "Runs" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 30, vars: 7, consts: [["Title", "Run History", "Subtitle", "Pipeline execution history and per-source run detail"], ["toolbar", ""], [3, "ClearAllRequested", "ActiveCount", "ShowClearAll"], [3, "ValuesChange", "Reset", "Fields", "Values"], [3, "Padding", "Flex"], [1, "at-main-area"], [1, "at-page-body"], [1, "at-card"], [1, "at-card-body", 2, "max-height", "600px", "overflow-y", "auto"], [1, "at-run-table"], [1, "at-run-row-clickable", 3, "at-run-row-selected"], [1, "at-card", 2, "margin-top", "12px"], [1, "at-run-row-clickable", 3, "click"], [1, "at-run-status-badge"], [1, "fa-solid", "fa-spinner", "fa-spin", 2, "font-size", "0.55rem"], [1, "at-run-source-name"], [1, "at-run-duration"], [1, "at-card-header"], [1, "at-card-title"], [1, "fa-solid", "fa-magnifying-glass-chart"], [1, "at-action-btn", "at-secondary-btn", 2, "font-size", "11px", "padding", "3px 8px", 3, "click"], [1, "fa-solid", "fa-times"], [1, "at-card-body"], ["text", "Loading run details...", "size", "small"], [1, "at-empty-state"], [1, "fa-solid", "fa-info-circle"]], template: function ClassifyHistoryTabComponent_Template(rf, ctx) { if (rf & 1) {
351
- i0.ɵɵelementStart(0, "mj-page-header-interior", 0)(1, "div", 1)(2, "mj-filter-popover", 2);
352
- i0.ɵɵlistener("ClearAllRequested", function ClassifyHistoryTabComponent_Template_mj_filter_popover_ClearAllRequested_2_listener() { return ctx.onHistoryFilterReset(); });
353
- i0.ɵɵelementStart(3, "mj-filter-panel", 3);
354
- i0.ɵɵlistener("ValuesChange", function ClassifyHistoryTabComponent_Template_mj_filter_panel_ValuesChange_3_listener($event) { return ctx.onHistoryFilterChange($event); })("Reset", function ClassifyHistoryTabComponent_Template_mj_filter_panel_Reset_3_listener() { return ctx.onHistoryFilterReset(); });
445
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ClassifyHistoryTabComponent, selectors: [["classify-history-tab"]], inputs: { Runs: "Runs", TotalRunCount: "TotalRunCount", IsLoadingMore: "IsLoadingMore" }, outputs: { LoadMoreRequested: "LoadMoreRequested", ItemSelected: "ItemSelected", RefreshRequested: "RefreshRequested" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 35, vars: 10, consts: [["Title", "Run History", "Subtitle", "Pipeline execution history and per-source run detail"], ["actions", ""], ["mjButton", "", "variant", "secondary", "size", "sm", 3, "click", "disabled"], ["toolbar", ""], [3, "ClearAllRequested", "ActiveCount", "ShowClearAll"], [3, "ValuesChange", "Reset", "Fields", "Values"], [3, "Padding", "Flex"], [1, "at-main-area"], [1, "at-page-body"], [1, "at-card"], [1, "at-card-body", 2, "max-height", "600px", "overflow-y", "auto"], [1, "at-run-table"], [1, "at-run-row-clickable", 3, "at-run-row-selected"], [1, "at-load-more-bar"], [1, "at-card", 2, "margin-top", "12px"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "mj-action-label"], [1, "fa-solid", "fa-arrows-rotate"], [1, "at-run-row-clickable", 3, "click"], [1, "at-run-status-badge"], [1, "fa-solid", "fa-spinner", "fa-spin", 2, "font-size", "0.55rem"], [1, "at-run-source-name"], [1, "at-run-duration"], [1, "at-load-more-count"], ["mjButton", "", "variant", "secondary", "size", "sm", 3, "disabled"], [1, "fa-solid", "fa-chevron-down"], [1, "at-card-header"], [1, "at-card-title"], [1, "fa-solid", "fa-magnifying-glass-chart"], [1, "at-action-btn", "at-secondary-btn", 2, "font-size", "11px", "padding", "3px 8px", 3, "click"], [1, "fa-solid", "fa-times"], [1, "at-card-body"], ["text", "Loading run details...", "size", "small"], [1, "at-empty-state"], [1, "at-run-items-section"], [1, "at-card-header", 2, "padding-left", "0", "padding-right", "0"], [1, "fa-solid", "fa-list-check"], [3, "ItemSelected", "RunID", "Provider"], [1, "fa-solid", "fa-info-circle"]], template: function ClassifyHistoryTabComponent_Template(rf, ctx) { if (rf & 1) {
446
+ i0.ɵɵelementStart(0, "mj-page-header-interior", 0)(1, "div", 1)(2, "button", 2);
447
+ i0.ɵɵlistener("click", function ClassifyHistoryTabComponent_Template_button_click_2_listener() { return ctx.Refresh(); });
448
+ i0.ɵɵconditionalCreate(3, ClassifyHistoryTabComponent_Conditional_3_Template, 3, 0)(4, ClassifyHistoryTabComponent_Conditional_4_Template, 3, 0);
449
+ i0.ɵɵelementEnd()();
450
+ i0.ɵɵelementStart(5, "div", 3)(6, "mj-filter-popover", 4);
451
+ i0.ɵɵlistener("ClearAllRequested", function ClassifyHistoryTabComponent_Template_mj_filter_popover_ClearAllRequested_6_listener() { return ctx.onHistoryFilterReset(); });
452
+ i0.ɵɵelementStart(7, "mj-filter-panel", 5);
453
+ i0.ɵɵlistener("ValuesChange", function ClassifyHistoryTabComponent_Template_mj_filter_panel_ValuesChange_7_listener($event) { return ctx.onHistoryFilterChange($event); })("Reset", function ClassifyHistoryTabComponent_Template_mj_filter_panel_Reset_7_listener() { return ctx.onHistoryFilterReset(); });
355
454
  i0.ɵɵelementEnd()()()();
356
- i0.ɵɵelementStart(4, "mj-page-body-interior", 4)(5, "div", 5)(6, "div", 6)(7, "div", 7)(8, "div", 8)(9, "table", 9)(10, "thead")(11, "tr")(12, "th");
357
- i0.ɵɵtext(13, "Status");
358
- i0.ɵɵelementEnd();
359
- i0.ɵɵelementStart(14, "th");
360
- i0.ɵɵtext(15, "Source");
361
- i0.ɵɵelementEnd();
362
- i0.ɵɵelementStart(16, "th");
363
- i0.ɵɵtext(17, "Started");
455
+ i0.ɵɵelementStart(8, "mj-page-body-interior", 6)(9, "div", 7)(10, "div", 8)(11, "div", 9)(12, "div", 10)(13, "table", 11)(14, "thead")(15, "tr")(16, "th");
456
+ i0.ɵɵtext(17, "Status");
364
457
  i0.ɵɵelementEnd();
365
458
  i0.ɵɵelementStart(18, "th");
366
- i0.ɵɵtext(19, "Duration");
459
+ i0.ɵɵtext(19, "Source");
367
460
  i0.ɵɵelementEnd();
368
461
  i0.ɵɵelementStart(20, "th");
369
- i0.ɵɵtext(21, "Items");
462
+ i0.ɵɵtext(21, "Started");
370
463
  i0.ɵɵelementEnd();
371
464
  i0.ɵɵelementStart(22, "th");
372
- i0.ɵɵtext(23, "Tags");
465
+ i0.ɵɵtext(23, "Duration");
373
466
  i0.ɵɵelementEnd();
374
467
  i0.ɵɵelementStart(24, "th");
375
- i0.ɵɵtext(25, "Errors");
468
+ i0.ɵɵtext(25, "Items");
469
+ i0.ɵɵelementEnd();
470
+ i0.ɵɵelementStart(26, "th");
471
+ i0.ɵɵtext(27, "Tags");
472
+ i0.ɵɵelementEnd();
473
+ i0.ɵɵelementStart(28, "th");
474
+ i0.ɵɵtext(29, "Errors");
376
475
  i0.ɵɵelementEnd()()();
377
- i0.ɵɵelementStart(26, "tbody");
378
- i0.ɵɵrepeaterCreate(27, ClassifyHistoryTabComponent_For_28_Template, 17, 14, "tr", 10, _forTrack0);
379
- i0.ɵɵelementEnd()()()();
380
- i0.ɵɵconditionalCreate(29, ClassifyHistoryTabComponent_Conditional_29_Template, 12, 2, "div", 11);
476
+ i0.ɵɵelementStart(30, "tbody");
477
+ i0.ɵɵrepeaterCreate(31, ClassifyHistoryTabComponent_For_32_Template, 17, 14, "tr", 12, _forTrack0);
478
+ i0.ɵɵelementEnd()()();
479
+ i0.ɵɵconditionalCreate(33, ClassifyHistoryTabComponent_Conditional_33_Template, 4, 3, "div", 13);
480
+ i0.ɵɵelementEnd();
481
+ i0.ɵɵconditionalCreate(34, ClassifyHistoryTabComponent_Conditional_34_Template, 18, 4, "div", 14);
381
482
  i0.ɵɵelementEnd()()();
382
483
  } if (rf & 2) {
383
484
  i0.ɵɵadvance(2);
485
+ i0.ɵɵproperty("disabled", ctx.IsLoading);
486
+ i0.ɵɵadvance();
487
+ i0.ɵɵconditional(ctx.IsLoading ? 3 : 4);
488
+ i0.ɵɵadvance(3);
384
489
  i0.ɵɵproperty("ActiveCount", ctx.historyActiveFilterCount)("ShowClearAll", ctx.historyActiveFilterCount > 0);
385
490
  i0.ɵɵadvance();
386
491
  i0.ɵɵproperty("Fields", ctx.historyFilterFields)("Values", ctx.historyFilterValues);
@@ -389,14 +494,26 @@ export class ClassifyHistoryTabComponent extends BaseAngularComponent {
389
494
  i0.ɵɵadvance(23);
390
495
  i0.ɵɵrepeater(ctx.FilteredRunRows);
391
496
  i0.ɵɵadvance(2);
392
- i0.ɵɵconditional(ctx.SelectedRunID ? 29 : -1);
393
- } }, dependencies: [i1.LoadingComponent, i2.MJPageHeaderInteriorComponent, i2.MJPageBodyInteriorComponent, i2.MJFilterPopoverComponent, i2.MJFilterPanelComponent], encapsulation: 2 });
497
+ i0.ɵɵconditional(ctx.TotalRunCount > 0 ? 33 : -1);
498
+ i0.ɵɵadvance();
499
+ i0.ɵɵconditional(ctx.SelectedRunID ? 34 : -1);
500
+ } }, dependencies: [i1.LoadingComponent, i2.MJButtonDirective, i2.MJPageHeaderInteriorComponent, i2.MJPageBodyInteriorComponent, i2.MJFilterPopoverComponent, i2.MJFilterPanelComponent, i3.ClassifyItemGridComponent], styles: ["\n\n\n\n\n\n\n\n\n\n.at-run-items-section[_ngcontent-%COMP%] {\n margin-top: 16px;\n border-top: 1px solid var(--mj-border-subtle);\n padding-top: 12px;\n}"] });
394
501
  }
395
502
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ClassifyHistoryTabComponent, [{
396
503
  type: Component,
397
- args: [{ standalone: false, selector: 'classify-history-tab', template: "<mj-page-header-interior\n Title=\"Run History\"\n Subtitle=\"Pipeline execution history and per-source run detail\">\n <div toolbar>\n <mj-filter-popover\n [ActiveCount]=\"historyActiveFilterCount\"\n [ShowClearAll]=\"historyActiveFilterCount > 0\"\n (ClearAllRequested)=\"onHistoryFilterReset()\">\n <mj-filter-panel\n [Fields]=\"historyFilterFields\"\n [Values]=\"historyFilterValues\"\n (ValuesChange)=\"onHistoryFilterChange($event)\"\n (Reset)=\"onHistoryFilterReset()\">\n </mj-filter-panel>\n </mj-filter-popover>\n </div>\n</mj-page-header-interior>\n\n<mj-page-body-interior [Padding]=\"false\" [Flex]=\"true\">\n <div class=\"at-main-area\">\n <div class=\"at-page-body\">\n <div class=\"at-card\">\n <div class=\"at-card-body\" style=\"max-height: 600px; overflow-y: auto;\">\n <table class=\"at-run-table\">\n <thead>\n <tr>\n <th>Status</th>\n <th>Source</th>\n <th>Started</th>\n <th>Duration</th>\n <th>Items</th>\n <th>Tags</th>\n <th>Errors</th>\n </tr>\n </thead>\n <tbody>\n @for (row of FilteredRunRows; track row.ID) {\n <tr class=\"at-run-row-clickable\"\n [class.at-run-row-selected]=\"SelectedRunID === row.ID\"\n (click)=\"OpenRunDetail(row.ID)\">\n <td>\n <span class=\"at-run-status-badge\" [class]=\"row.StatusClass\">\n @if (row.StatusClass === 'running') {\n <i class=\"fa-solid fa-spinner fa-spin\" style=\"font-size: 0.55rem\"></i>\n }\n {{ row.Status }}\n </span>\n </td>\n <td class=\"at-run-source-name\">{{ row.SourceName }}</td>\n <td>{{ row.StartedDisplay }}</td>\n <td class=\"at-run-duration\">{{ row.Duration }}</td>\n <td>{{ row.Items }}</td>\n <td>{{ row.Tags }}</td>\n <td [class]=\"row.ErrorClass\">{{ row.Errors }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </div>\n\n <!-- Per-run detail panel -->\n @if (SelectedRunID) {\n <div class=\"at-card\" style=\"margin-top: 12px;\">\n <div class=\"at-card-header\">\n <span class=\"at-card-title\">\n <i class=\"fa-solid fa-magnifying-glass-chart\"></i>\n Run Detail: {{ SelectedRunID.slice(0, 14) }}...\n </span>\n <button class=\"at-action-btn at-secondary-btn\" style=\"font-size: 11px; padding: 3px 8px;\" (click)=\"CloseRunDetail()\">\n <i class=\"fa-solid fa-times\"></i> Close\n </button>\n </div>\n <div class=\"at-card-body\">\n @if (IsLoadingRunDetail) {\n <mj-loading text=\"Loading run details...\" size=\"small\"></mj-loading>\n } @else if (RunDetailRows.length > 0) {\n <table class=\"at-run-table\">\n <thead>\n <tr>\n <th>Source</th>\n <th>Source Type</th>\n <th>Status</th>\n <th>Items</th>\n <th>Tagged</th>\n <th>Vectorized</th>\n <th>Errors</th>\n <th>Tokens</th>\n <th>Cost</th>\n <th>Duration</th>\n </tr>\n </thead>\n <tbody>\n @for (detail of RunDetailRows; track detail.SourceName) {\n <tr>\n <td class=\"at-run-source-name\">{{ detail.SourceName }}</td>\n <td>{{ detail.SourceType }}</td>\n <td>\n <span class=\"at-run-status-badge\" [class]=\"detail.StatusClass\">{{ detail.Status }}</span>\n </td>\n <td>{{ detail.ItemsProcessed }}</td>\n <td>{{ detail.ItemsTagged }}</td>\n <td>{{ detail.ItemsVectorized }}</td>\n <td [class.run-error-text]=\"detail.ErrorCount > 0\">{{ detail.ErrorCount }}</td>\n <td>{{ FormatTokenCount(detail.TotalTokens) }}</td>\n <td>{{ detail.TotalCost > 0 ? '$' + detail.TotalCost.toFixed(4) : '$0.00' }}</td>\n <td class=\"at-run-duration\">{{ detail.Duration }}</td>\n </tr>\n }\n </tbody>\n </table>\n } @else {\n <div class=\"at-empty-state\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <p>No per-source detail records found for this run.</p>\n </div>\n }\n </div>\n </div>\n }\n </div>\n </div>\n</mj-page-body-interior>\n", styles: ["/*\n * Run History tab styles.\n *\n * The host (AutotaggingPipelineResourceComponent) uses ViewEncapsulation.None,\n * so its `.at-*` rules are global and already style this tab's markup while it\n * renders inside the host shell. Tab-specific rules live here as the shared CSS\n * is partitioned during the host-slim step.\n */\n"] }]
504
+ args: [{ standalone: false, selector: 'classify-history-tab', template: "<mj-page-header-interior\n Title=\"Run History\"\n Subtitle=\"Pipeline execution history and per-source run detail\">\n <div actions>\n <button mjButton variant=\"secondary\" size=\"sm\" (click)=\"Refresh()\" [disabled]=\"IsLoading\">\n @if (IsLoading) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> <span class=\"mj-action-label\">Refreshing\u2026</span>\n } @else {\n <i class=\"fa-solid fa-arrows-rotate\"></i> <span class=\"mj-action-label\">Refresh</span>\n }\n </button>\n </div>\n <div toolbar>\n <mj-filter-popover\n [ActiveCount]=\"historyActiveFilterCount\"\n [ShowClearAll]=\"historyActiveFilterCount > 0\"\n (ClearAllRequested)=\"onHistoryFilterReset()\">\n <mj-filter-panel\n [Fields]=\"historyFilterFields\"\n [Values]=\"historyFilterValues\"\n (ValuesChange)=\"onHistoryFilterChange($event)\"\n (Reset)=\"onHistoryFilterReset()\">\n </mj-filter-panel>\n </mj-filter-popover>\n </div>\n</mj-page-header-interior>\n\n<mj-page-body-interior [Padding]=\"false\" [Flex]=\"true\">\n <div class=\"at-main-area\">\n <div class=\"at-page-body\">\n <div class=\"at-card\">\n <div class=\"at-card-body\" style=\"max-height: 600px; overflow-y: auto;\">\n <table class=\"at-run-table\">\n <thead>\n <tr>\n <th>Status</th>\n <th>Source</th>\n <th>Started</th>\n <th>Duration</th>\n <th>Items</th>\n <th>Tags</th>\n <th>Errors</th>\n </tr>\n </thead>\n <tbody>\n @for (row of FilteredRunRows; track row.ID) {\n <tr class=\"at-run-row-clickable\"\n [class.at-run-row-selected]=\"SelectedRunID === row.ID\"\n (click)=\"OpenRunDetail(row.ID)\">\n <td>\n <span class=\"at-run-status-badge\" [class]=\"row.StatusClass\">\n @if (row.StatusClass === 'running') {\n <i class=\"fa-solid fa-spinner fa-spin\" style=\"font-size: 0.55rem\"></i>\n }\n {{ row.Status }}\n </span>\n </td>\n <td class=\"at-run-source-name\">{{ row.SourceName }}</td>\n <td>{{ row.StartedDisplay }}</td>\n <td class=\"at-run-duration\">{{ row.Duration }}</td>\n <td>{{ row.Items }}</td>\n <td>{{ row.Tags }}</td>\n <td [class]=\"row.ErrorClass\">{{ row.Errors }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n @if (TotalRunCount > 0) {\n <div class=\"at-load-more-bar\">\n <span class=\"at-load-more-count\">Showing {{ FilteredRunRows.length }} of {{ TotalRunCount }} runs</span>\n @if (HasMoreRuns) {\n <button mjButton variant=\"secondary\" size=\"sm\" (click)=\"onLoadMore()\" [disabled]=\"IsLoadingMore\">\n @if (IsLoadingMore) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Loading\u2026\n } @else {\n <i class=\"fa-solid fa-chevron-down\"></i> Load more\n }\n </button>\n }\n </div>\n }\n </div>\n\n <!-- Per-run detail panel -->\n @if (SelectedRunID) {\n <div class=\"at-card\" style=\"margin-top: 12px;\">\n <div class=\"at-card-header\">\n <span class=\"at-card-title\">\n <i class=\"fa-solid fa-magnifying-glass-chart\"></i>\n Run Detail: {{ SelectedRunID.slice(0, 14) }}...\n </span>\n <button class=\"at-action-btn at-secondary-btn\" style=\"font-size: 11px; padding: 3px 8px;\" (click)=\"CloseRunDetail()\">\n <i class=\"fa-solid fa-times\"></i> Close\n </button>\n </div>\n <div class=\"at-card-body\">\n @if (IsLoadingRunDetail) {\n <mj-loading text=\"Loading run details...\" size=\"small\"></mj-loading>\n } @else if (RunDetailRows.length > 0) {\n <table class=\"at-run-table\">\n <thead>\n <tr>\n <th>Source</th>\n <th>Source Type</th>\n <th>Status</th>\n <th>Items</th>\n <th>Tagged</th>\n <th>Vectorized</th>\n <th>Errors</th>\n <th>Tokens</th>\n <th>Cost</th>\n <th>Duration</th>\n </tr>\n </thead>\n <tbody>\n @for (detail of RunDetailRows; track detail.SourceName) {\n <tr>\n <td class=\"at-run-source-name\">{{ detail.SourceName }}</td>\n <td>{{ detail.SourceType }}</td>\n <td>\n <span class=\"at-run-status-badge\" [class]=\"detail.StatusClass\">{{ detail.Status }}</span>\n </td>\n <td>{{ detail.ItemsProcessed }}</td>\n <td>{{ detail.ItemsTagged }}</td>\n <td>{{ detail.ItemsVectorized }}</td>\n <td [class.run-error-text]=\"detail.ErrorCount > 0\">{{ detail.ErrorCount }}</td>\n <td>{{ FormatTokenCount(detail.TotalTokens) }}</td>\n <td>{{ detail.TotalCost > 0 ? '$' + detail.TotalCost.toFixed(4) : '$0.00' }}</td>\n <td class=\"at-run-duration\">{{ detail.Duration }}</td>\n </tr>\n }\n </tbody>\n </table>\n } @else {\n <div class=\"at-empty-state\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <p>No per-source detail records found for this run.</p>\n </div>\n }\n\n <!-- Phase 4: content items processed in this run -->\n <div class=\"at-run-items-section\">\n <div class=\"at-card-header\" style=\"padding-left: 0; padding-right: 0;\">\n <span class=\"at-card-title\">\n <i class=\"fa-solid fa-list-check\"></i> Items in this run\n </span>\n </div>\n <classify-item-grid\n [RunID]=\"SelectedRunID\"\n [Provider]=\"Provider\"\n (ItemSelected)=\"onItemSelected($event)\"></classify-item-grid>\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n</mj-page-body-interior>\n", styles: ["/*\n * Run History tab styles.\n *\n * The host (AutotaggingPipelineResourceComponent) uses ViewEncapsulation.None,\n * so its `.at-*` rules are global and already style this tab's markup while it\n * renders inside the host shell. Tab-specific rules live here as the shared CSS\n * is partitioned during the host-slim step.\n */\n\n.at-run-items-section {\n margin-top: 16px;\n border-top: 1px solid var(--mj-border-subtle);\n padding-top: 12px;\n}\n"] }]
398
505
  }], null, { Runs: [{
399
506
  type: Input
507
+ }], TotalRunCount: [{
508
+ type: Input
509
+ }], IsLoadingMore: [{
510
+ type: Input
511
+ }], LoadMoreRequested: [{
512
+ type: Output
513
+ }], ItemSelected: [{
514
+ type: Output
515
+ }], RefreshRequested: [{
516
+ type: Output
400
517
  }] }); })();
401
518
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ClassifyHistoryTabComponent, { className: "ClassifyHistoryTabComponent", filePath: "src/AI/components/autotagging/tabs/history-tab.component.ts", lineNumber: 22 }); })();
402
519
  //# sourceMappingURL=history-tab.component.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"history-tab.component.js","sourceRoot":"","sources":["../../../../../src/AI/components/autotagging/tabs/history-tab.component.ts","../../../../../src/AI/components/autotagging/tabs/history-tab.component.html"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Classify · Run History tab.\n *\n * Self-contained sub-page: owns its header-interior, the run table, filters,\n * and the per-run detail panel. Receives the shared raw run list from the host\n * via `[Runs]` (the host is the data orchestrator); loads per-run detail rows\n * on demand itself. Cross-tab navigation (none today) would bubble via @Output.\n */\nimport { Component, ChangeDetectorRef, Input, inject } from '@angular/core';\nimport { RunView } from '@memberjunction/core';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { FilterFieldConfig } from '@memberjunction/ng-ui-components';\nimport { RunHistoryRow, RunDetailRow } from '../shared/classify.types';\nimport { formatNumber, formatDate, computeDuration, displayStatus, formatTokenCount, mapRunDetailRecords } from '../shared/classify.format';\n\n@Component({\n standalone: false,\n selector: 'classify-history-tab',\n templateUrl: './history-tab.component.html',\n styleUrls: ['./history-tab.component.css']\n})\nexport class ClassifyHistoryTabComponent extends BaseAngularComponent {\n private cdr = inject(ChangeDetectorRef);\n\n /** Shared raw `MJ: Content Process Runs` rows, supplied by the host orchestrator. */\n private _runs: Record<string, unknown>[] = [];\n @Input()\n set Runs(value: Record<string, unknown>[]) {\n this._runs = value ?? [];\n this.buildRunHistoryRows();\n this.buildHistorySourceOptions();\n this.FilterRunHistory();\n }\n get Runs(): Record<string, unknown>[] {\n return this._runs;\n }\n\n public RunHistoryRows: RunHistoryRow[] = [];\n public FilteredRunRows: RunHistoryRow[] = [];\n public HistorySourceFilter = '';\n public HistoryStatusFilter = '';\n public HistorySourceOptions: string[] = [];\n\n // Per-run detail panel\n public SelectedRunID: string | null = null;\n public RunDetailRows: RunDetailRow[] = [];\n public IsLoadingRunDetail = false;\n\n // Template-facing formatters\n public readonly FormatTokenCount = formatTokenCount;\n\n private buildRunHistoryRows(): void {\n this.RunHistoryRows = this._runs.map(run => {\n const status = (run['Status'] as string) ?? 'Unknown';\n const startTime = run['StartTime'] as string | null;\n const endTime = run['EndTime'] as string | null;\n const duration = computeDuration(startTime, endTime);\n const processedItems = run['ProcessedItems'] as number | null;\n const errorCount = run['ErrorCount'] as number | null;\n const statusLower = status.toLowerCase();\n const isFailed = statusLower === 'error' || statusLower === 'failed';\n const isRunning = statusLower === 'running' || statusLower === 'processing';\n const hasErrors = (errorCount ?? 0) > 0;\n\n return {\n ID: run['ID'] as string,\n Status: displayStatus(status),\n StatusClass: isFailed ? 'failed' : isRunning ? 'running' : 'complete',\n SourceName: (run['Source'] as string) ?? 'Unknown',\n StartedDisplay: startTime ? formatDate(startTime) : '—',\n Duration: duration,\n Items: processedItems != null ? formatNumber(processedItems) : '—',\n Tags: '—',\n Errors: hasErrors ? formatNumber(errorCount!) : (isFailed ? status : '0'),\n ErrorClass: isFailed || hasErrors ? 'run-error-text' : ''\n };\n });\n }\n\n private buildHistorySourceOptions(): void {\n const sources = new Set<string>();\n for (const run of this._runs) {\n const s = run['Source'] as string;\n if (s) sources.add(s);\n }\n this.HistorySourceOptions = Array.from(sources).sort();\n }\n\n public FilterRunHistory(): void {\n this.FilteredRunRows = this.RunHistoryRows.filter(row => {\n if (this.HistorySourceFilter && row.SourceName !== this.HistorySourceFilter) return false;\n if (this.HistoryStatusFilter && row.StatusClass !== this.HistoryStatusFilter) return false;\n return true;\n });\n this.cdr.detectChanges();\n }\n\n /**\n * Filter fields for the Run History section, rendered inside an\n * `<mj-filter-popover>` (many values, single-select → popover with dropdown).\n */\n public get historyFilterFields(): FilterFieldConfig[] {\n return [\n {\n key: 'source',\n type: 'dropdown',\n label: 'Source',\n placeholder: 'All Sources',\n filterable: this.HistorySourceOptions.length > 10,\n options: [\n { text: 'All Sources', value: '' },\n ...this.HistorySourceOptions.map(s => ({ text: s, value: s }))\n ]\n },\n {\n key: 'status',\n type: 'dropdown',\n label: 'Status',\n placeholder: 'All Status',\n options: [\n { text: 'All Status', value: '' },\n { text: 'Complete', value: 'complete' },\n { text: 'Failed', value: 'failed' },\n { text: 'Running', value: 'running' }\n ]\n }\n ];\n }\n\n public get historyFilterValues(): Record<string, unknown> {\n return { source: this.HistorySourceFilter, status: this.HistoryStatusFilter };\n }\n\n public get historyActiveFilterCount(): number {\n return (this.HistorySourceFilter ? 1 : 0) + (this.HistoryStatusFilter ? 1 : 0);\n }\n\n public onHistoryFilterChange(values: Record<string, unknown>): void {\n this.HistorySourceFilter = (values['source'] as string) ?? '';\n this.HistoryStatusFilter = (values['status'] as string) ?? '';\n this.FilterRunHistory();\n }\n\n public onHistoryFilterReset(): void {\n this.HistorySourceFilter = '';\n this.HistoryStatusFilter = '';\n this.FilterRunHistory();\n }\n\n /** Open (or toggle closed) the detail view for a run, loading its per-source detail rows. */\n public async OpenRunDetail(runID: string): Promise<void> {\n if (this.SelectedRunID === runID) {\n this.CloseRunDetail();\n return;\n }\n this.SelectedRunID = runID;\n this.IsLoadingRunDetail = true;\n this.RunDetailRows = [];\n this.cdr.detectChanges();\n\n await this.loadRunDetailRows(runID);\n\n this.IsLoadingRunDetail = false;\n this.cdr.detectChanges();\n }\n\n public CloseRunDetail(): void {\n this.SelectedRunID = null;\n this.RunDetailRows = [];\n this.IsLoadingRunDetail = false;\n this.cdr.detectChanges();\n }\n\n private async loadRunDetailRows(runID: string): Promise<void> {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView({\n EntityName: 'MJ: Content Process Run Details',\n ExtraFilter: `ContentProcessRunID='${runID}'`,\n OrderBy: 'ContentSource',\n ResultType: 'simple',\n });\n if (result.Success) {\n this.RunDetailRows = mapRunDetailRecords(result.Results);\n }\n }\n}\n","<mj-page-header-interior\n Title=\"Run History\"\n Subtitle=\"Pipeline execution history and per-source run detail\">\n <div toolbar>\n <mj-filter-popover\n [ActiveCount]=\"historyActiveFilterCount\"\n [ShowClearAll]=\"historyActiveFilterCount > 0\"\n (ClearAllRequested)=\"onHistoryFilterReset()\">\n <mj-filter-panel\n [Fields]=\"historyFilterFields\"\n [Values]=\"historyFilterValues\"\n (ValuesChange)=\"onHistoryFilterChange($event)\"\n (Reset)=\"onHistoryFilterReset()\">\n </mj-filter-panel>\n </mj-filter-popover>\n </div>\n</mj-page-header-interior>\n\n<mj-page-body-interior [Padding]=\"false\" [Flex]=\"true\">\n <div class=\"at-main-area\">\n <div class=\"at-page-body\">\n <div class=\"at-card\">\n <div class=\"at-card-body\" style=\"max-height: 600px; overflow-y: auto;\">\n <table class=\"at-run-table\">\n <thead>\n <tr>\n <th>Status</th>\n <th>Source</th>\n <th>Started</th>\n <th>Duration</th>\n <th>Items</th>\n <th>Tags</th>\n <th>Errors</th>\n </tr>\n </thead>\n <tbody>\n @for (row of FilteredRunRows; track row.ID) {\n <tr class=\"at-run-row-clickable\"\n [class.at-run-row-selected]=\"SelectedRunID === row.ID\"\n (click)=\"OpenRunDetail(row.ID)\">\n <td>\n <span class=\"at-run-status-badge\" [class]=\"row.StatusClass\">\n @if (row.StatusClass === 'running') {\n <i class=\"fa-solid fa-spinner fa-spin\" style=\"font-size: 0.55rem\"></i>\n }\n {{ row.Status }}\n </span>\n </td>\n <td class=\"at-run-source-name\">{{ row.SourceName }}</td>\n <td>{{ row.StartedDisplay }}</td>\n <td class=\"at-run-duration\">{{ row.Duration }}</td>\n <td>{{ row.Items }}</td>\n <td>{{ row.Tags }}</td>\n <td [class]=\"row.ErrorClass\">{{ row.Errors }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </div>\n\n <!-- Per-run detail panel -->\n @if (SelectedRunID) {\n <div class=\"at-card\" style=\"margin-top: 12px;\">\n <div class=\"at-card-header\">\n <span class=\"at-card-title\">\n <i class=\"fa-solid fa-magnifying-glass-chart\"></i>\n Run Detail: {{ SelectedRunID.slice(0, 14) }}...\n </span>\n <button class=\"at-action-btn at-secondary-btn\" style=\"font-size: 11px; padding: 3px 8px;\" (click)=\"CloseRunDetail()\">\n <i class=\"fa-solid fa-times\"></i> Close\n </button>\n </div>\n <div class=\"at-card-body\">\n @if (IsLoadingRunDetail) {\n <mj-loading text=\"Loading run details...\" size=\"small\"></mj-loading>\n } @else if (RunDetailRows.length > 0) {\n <table class=\"at-run-table\">\n <thead>\n <tr>\n <th>Source</th>\n <th>Source Type</th>\n <th>Status</th>\n <th>Items</th>\n <th>Tagged</th>\n <th>Vectorized</th>\n <th>Errors</th>\n <th>Tokens</th>\n <th>Cost</th>\n <th>Duration</th>\n </tr>\n </thead>\n <tbody>\n @for (detail of RunDetailRows; track detail.SourceName) {\n <tr>\n <td class=\"at-run-source-name\">{{ detail.SourceName }}</td>\n <td>{{ detail.SourceType }}</td>\n <td>\n <span class=\"at-run-status-badge\" [class]=\"detail.StatusClass\">{{ detail.Status }}</span>\n </td>\n <td>{{ detail.ItemsProcessed }}</td>\n <td>{{ detail.ItemsTagged }}</td>\n <td>{{ detail.ItemsVectorized }}</td>\n <td [class.run-error-text]=\"detail.ErrorCount > 0\">{{ detail.ErrorCount }}</td>\n <td>{{ FormatTokenCount(detail.TotalTokens) }}</td>\n <td>{{ detail.TotalCost > 0 ? '$' + detail.TotalCost.toFixed(4) : '$0.00' }}</td>\n <td class=\"at-run-duration\">{{ detail.Duration }}</td>\n </tr>\n }\n </tbody>\n </table>\n } @else {\n <div class=\"at-empty-state\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <p>No per-source detail records found for this run.</p>\n </div>\n }\n </div>\n </div>\n }\n </div>\n </div>\n</mj-page-body-interior>\n"]}
1
+ {"version":3,"file":"history-tab.component.js","sourceRoot":"","sources":["../../../../../src/AI/components/autotagging/tabs/history-tab.component.ts","../../../../../src/AI/components/autotagging/tabs/history-tab.component.html"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Classify · Run History tab.\n *\n * Self-contained sub-page: owns its header-interior, the run table, filters,\n * and the per-run detail panel. Receives the shared raw run list from the host\n * via `[Runs]` (the host is the data orchestrator); loads per-run detail rows\n * on demand itself. Cross-tab navigation (none today) would bubble via @Output.\n */\nimport { Component, ChangeDetectorRef, EventEmitter, Input, Output, inject } from '@angular/core';\nimport { RunView } from '@memberjunction/core';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { FilterFieldConfig } from '@memberjunction/ng-ui-components';\nimport { RunHistoryRow, RunDetailRow } from '../shared/classify.types';\nimport { formatNumber, formatDate, computeDuration, displayStatus, formatTokenCount, mapRunDetailRecords } from '../shared/classify.format';\n\n@Component({\n standalone: false,\n selector: 'classify-history-tab',\n templateUrl: './history-tab.component.html',\n styleUrls: ['./history-tab.component.css']\n})\nexport class ClassifyHistoryTabComponent extends BaseAngularComponent {\n private cdr = inject(ChangeDetectorRef);\n\n /** Shared raw `MJ: Content Process Runs` rows, supplied by the host orchestrator. */\n private _runs: Record<string, unknown>[] = [];\n @Input()\n set Runs(value: Record<string, unknown>[]) {\n this._runs = value ?? [];\n this.buildRunHistoryRows();\n this.buildHistorySourceOptions();\n this.FilterRunHistory();\n // A fresh Runs binding (from the host reload) ends any in-flight refresh.\n this.IsLoading = false;\n this.cdr.detectChanges();\n }\n get Runs(): Record<string, unknown>[] {\n return this._runs;\n }\n\n /** Total run count in the DB (from TotalRowCount) — drives the \"Showing X of Y\" line. */\n @Input() TotalRunCount = 0;\n\n /** True while the host is fetching the next page in response to LoadMoreRequested. */\n @Input() IsLoadingMore = false;\n\n /** Bubble a \"load more\" request to the host, which widens the loaded window. */\n @Output() LoadMoreRequested = new EventEmitter<void>();\n\n /**\n * Bubble a content-item selection (from the per-run item grid) up to the host,\n * which owns NavigationService + the drilldown slide-in.\n */\n @Output() ItemSelected = new EventEmitter<string>();\n\n public onItemSelected(itemID: string): void {\n this.ItemSelected.emit(itemID);\n }\n\n /** Whether more runs exist in the DB than are currently loaded. */\n public get HasMoreRuns(): boolean {\n return this.TotalRunCount > this._runs.length;\n }\n\n public onLoadMore(): void {\n this.LoadMoreRequested.emit();\n }\n\n /** Shown while the host reloads the run list in response to RefreshRequested. */\n public IsLoading = false;\n\n /**\n * Bubble a refresh request up to the host, which owns the run-history data\n * (`MJ: Content Process Runs`). The host reloads and re-binds `[Runs]`, whose\n * setter rebuilds the rows; the host also clears IsLoading via [Loading].\n */\n @Output() RefreshRequested = new EventEmitter<void>();\n\n public RunHistoryRows: RunHistoryRow[] = [];\n public FilteredRunRows: RunHistoryRow[] = [];\n public HistorySourceFilter = '';\n public HistoryStatusFilter = '';\n public HistorySourceOptions: string[] = [];\n\n // Per-run detail panel\n public SelectedRunID: string | null = null;\n public RunDetailRows: RunDetailRow[] = [];\n public IsLoadingRunDetail = false;\n\n // Template-facing formatters\n public readonly FormatTokenCount = formatTokenCount;\n\n /**\n * Ask the host to reload the run history. Data is host-owned, so we surface a\n * loading state and emit; the new `[Runs]` binding clears IsLoading.\n */\n public Refresh(): void {\n this.IsLoading = true;\n this.cdr.detectChanges();\n this.RefreshRequested.emit();\n }\n\n private buildRunHistoryRows(): void {\n this.RunHistoryRows = this._runs.map(run => {\n const status = (run['Status'] as string) ?? 'Unknown';\n const startTime = run['StartTime'] as string | null;\n const endTime = run['EndTime'] as string | null;\n const duration = computeDuration(startTime, endTime);\n const processedItems = run['ProcessedItems'] as number | null;\n const errorCount = run['ErrorCount'] as number | null;\n const statusLower = status.toLowerCase();\n const isFailed = statusLower === 'error' || statusLower === 'failed';\n const isRunning = statusLower === 'running' || statusLower === 'processing';\n const hasErrors = (errorCount ?? 0) > 0;\n\n return {\n ID: run['ID'] as string,\n Status: displayStatus(status),\n StatusClass: isFailed ? 'failed' : isRunning ? 'running' : 'complete',\n SourceName: (run['Source'] as string) ?? 'Unknown',\n StartedDisplay: startTime ? formatDate(startTime) : '—',\n Duration: duration,\n Items: processedItems != null ? formatNumber(processedItems) : '—',\n Tags: '—',\n Errors: hasErrors ? formatNumber(errorCount!) : (isFailed ? status : '0'),\n ErrorClass: isFailed || hasErrors ? 'run-error-text' : ''\n };\n });\n }\n\n private buildHistorySourceOptions(): void {\n const sources = new Set<string>();\n for (const run of this._runs) {\n const s = run['Source'] as string;\n if (s) sources.add(s);\n }\n this.HistorySourceOptions = Array.from(sources).sort();\n }\n\n public FilterRunHistory(): void {\n this.FilteredRunRows = this.RunHistoryRows.filter(row => {\n if (this.HistorySourceFilter && row.SourceName !== this.HistorySourceFilter) return false;\n if (this.HistoryStatusFilter && row.StatusClass !== this.HistoryStatusFilter) return false;\n return true;\n });\n this.cdr.detectChanges();\n }\n\n /**\n * Filter fields for the Run History section, rendered inside an\n * `<mj-filter-popover>` (many values, single-select → popover with dropdown).\n */\n public get historyFilterFields(): FilterFieldConfig[] {\n return [\n {\n key: 'source',\n type: 'dropdown',\n label: 'Source',\n placeholder: 'All Sources',\n filterable: this.HistorySourceOptions.length > 10,\n options: [\n { text: 'All Sources', value: '' },\n ...this.HistorySourceOptions.map(s => ({ text: s, value: s }))\n ]\n },\n {\n key: 'status',\n type: 'dropdown',\n label: 'Status',\n placeholder: 'All Status',\n options: [\n { text: 'All Status', value: '' },\n { text: 'Complete', value: 'complete' },\n { text: 'Failed', value: 'failed' },\n { text: 'Running', value: 'running' }\n ]\n }\n ];\n }\n\n public get historyFilterValues(): Record<string, unknown> {\n return { source: this.HistorySourceFilter, status: this.HistoryStatusFilter };\n }\n\n public get historyActiveFilterCount(): number {\n return (this.HistorySourceFilter ? 1 : 0) + (this.HistoryStatusFilter ? 1 : 0);\n }\n\n public onHistoryFilterChange(values: Record<string, unknown>): void {\n this.HistorySourceFilter = (values['source'] as string) ?? '';\n this.HistoryStatusFilter = (values['status'] as string) ?? '';\n this.FilterRunHistory();\n }\n\n public onHistoryFilterReset(): void {\n this.HistorySourceFilter = '';\n this.HistoryStatusFilter = '';\n this.FilterRunHistory();\n }\n\n /** Open (or toggle closed) the detail view for a run, loading its per-source detail rows. */\n public async OpenRunDetail(runID: string): Promise<void> {\n if (this.SelectedRunID === runID) {\n this.CloseRunDetail();\n return;\n }\n this.SelectedRunID = runID;\n this.IsLoadingRunDetail = true;\n this.RunDetailRows = [];\n this.cdr.detectChanges();\n\n await this.loadRunDetailRows(runID);\n\n this.IsLoadingRunDetail = false;\n this.cdr.detectChanges();\n }\n\n public CloseRunDetail(): void {\n this.SelectedRunID = null;\n this.RunDetailRows = [];\n this.IsLoadingRunDetail = false;\n this.cdr.detectChanges();\n }\n\n private async loadRunDetailRows(runID: string): Promise<void> {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView({\n EntityName: 'MJ: Content Process Run Details',\n ExtraFilter: `ContentProcessRunID='${runID}'`,\n OrderBy: 'ContentSource',\n ResultType: 'simple',\n });\n if (result.Success) {\n this.RunDetailRows = mapRunDetailRecords(result.Results);\n }\n }\n}\n","<mj-page-header-interior\n Title=\"Run History\"\n Subtitle=\"Pipeline execution history and per-source run detail\">\n <div actions>\n <button mjButton variant=\"secondary\" size=\"sm\" (click)=\"Refresh()\" [disabled]=\"IsLoading\">\n @if (IsLoading) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> <span class=\"mj-action-label\">Refreshing…</span>\n } @else {\n <i class=\"fa-solid fa-arrows-rotate\"></i> <span class=\"mj-action-label\">Refresh</span>\n }\n </button>\n </div>\n <div toolbar>\n <mj-filter-popover\n [ActiveCount]=\"historyActiveFilterCount\"\n [ShowClearAll]=\"historyActiveFilterCount > 0\"\n (ClearAllRequested)=\"onHistoryFilterReset()\">\n <mj-filter-panel\n [Fields]=\"historyFilterFields\"\n [Values]=\"historyFilterValues\"\n (ValuesChange)=\"onHistoryFilterChange($event)\"\n (Reset)=\"onHistoryFilterReset()\">\n </mj-filter-panel>\n </mj-filter-popover>\n </div>\n</mj-page-header-interior>\n\n<mj-page-body-interior [Padding]=\"false\" [Flex]=\"true\">\n <div class=\"at-main-area\">\n <div class=\"at-page-body\">\n <div class=\"at-card\">\n <div class=\"at-card-body\" style=\"max-height: 600px; overflow-y: auto;\">\n <table class=\"at-run-table\">\n <thead>\n <tr>\n <th>Status</th>\n <th>Source</th>\n <th>Started</th>\n <th>Duration</th>\n <th>Items</th>\n <th>Tags</th>\n <th>Errors</th>\n </tr>\n </thead>\n <tbody>\n @for (row of FilteredRunRows; track row.ID) {\n <tr class=\"at-run-row-clickable\"\n [class.at-run-row-selected]=\"SelectedRunID === row.ID\"\n (click)=\"OpenRunDetail(row.ID)\">\n <td>\n <span class=\"at-run-status-badge\" [class]=\"row.StatusClass\">\n @if (row.StatusClass === 'running') {\n <i class=\"fa-solid fa-spinner fa-spin\" style=\"font-size: 0.55rem\"></i>\n }\n {{ row.Status }}\n </span>\n </td>\n <td class=\"at-run-source-name\">{{ row.SourceName }}</td>\n <td>{{ row.StartedDisplay }}</td>\n <td class=\"at-run-duration\">{{ row.Duration }}</td>\n <td>{{ row.Items }}</td>\n <td>{{ row.Tags }}</td>\n <td [class]=\"row.ErrorClass\">{{ row.Errors }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n @if (TotalRunCount > 0) {\n <div class=\"at-load-more-bar\">\n <span class=\"at-load-more-count\">Showing {{ FilteredRunRows.length }} of {{ TotalRunCount }} runs</span>\n @if (HasMoreRuns) {\n <button mjButton variant=\"secondary\" size=\"sm\" (click)=\"onLoadMore()\" [disabled]=\"IsLoadingMore\">\n @if (IsLoadingMore) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Loading…\n } @else {\n <i class=\"fa-solid fa-chevron-down\"></i> Load more\n }\n </button>\n }\n </div>\n }\n </div>\n\n <!-- Per-run detail panel -->\n @if (SelectedRunID) {\n <div class=\"at-card\" style=\"margin-top: 12px;\">\n <div class=\"at-card-header\">\n <span class=\"at-card-title\">\n <i class=\"fa-solid fa-magnifying-glass-chart\"></i>\n Run Detail: {{ SelectedRunID.slice(0, 14) }}...\n </span>\n <button class=\"at-action-btn at-secondary-btn\" style=\"font-size: 11px; padding: 3px 8px;\" (click)=\"CloseRunDetail()\">\n <i class=\"fa-solid fa-times\"></i> Close\n </button>\n </div>\n <div class=\"at-card-body\">\n @if (IsLoadingRunDetail) {\n <mj-loading text=\"Loading run details...\" size=\"small\"></mj-loading>\n } @else if (RunDetailRows.length > 0) {\n <table class=\"at-run-table\">\n <thead>\n <tr>\n <th>Source</th>\n <th>Source Type</th>\n <th>Status</th>\n <th>Items</th>\n <th>Tagged</th>\n <th>Vectorized</th>\n <th>Errors</th>\n <th>Tokens</th>\n <th>Cost</th>\n <th>Duration</th>\n </tr>\n </thead>\n <tbody>\n @for (detail of RunDetailRows; track detail.SourceName) {\n <tr>\n <td class=\"at-run-source-name\">{{ detail.SourceName }}</td>\n <td>{{ detail.SourceType }}</td>\n <td>\n <span class=\"at-run-status-badge\" [class]=\"detail.StatusClass\">{{ detail.Status }}</span>\n </td>\n <td>{{ detail.ItemsProcessed }}</td>\n <td>{{ detail.ItemsTagged }}</td>\n <td>{{ detail.ItemsVectorized }}</td>\n <td [class.run-error-text]=\"detail.ErrorCount > 0\">{{ detail.ErrorCount }}</td>\n <td>{{ FormatTokenCount(detail.TotalTokens) }}</td>\n <td>{{ detail.TotalCost > 0 ? '$' + detail.TotalCost.toFixed(4) : '$0.00' }}</td>\n <td class=\"at-run-duration\">{{ detail.Duration }}</td>\n </tr>\n }\n </tbody>\n </table>\n } @else {\n <div class=\"at-empty-state\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <p>No per-source detail records found for this run.</p>\n </div>\n }\n\n <!-- Phase 4: content items processed in this run -->\n <div class=\"at-run-items-section\">\n <div class=\"at-card-header\" style=\"padding-left: 0; padding-right: 0;\">\n <span class=\"at-card-title\">\n <i class=\"fa-solid fa-list-check\"></i> Items in this run\n </span>\n </div>\n <classify-item-grid\n [RunID]=\"SelectedRunID\"\n [Provider]=\"Provider\"\n (ItemSelected)=\"onItemSelected($event)\"></classify-item-grid>\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n</mj-page-body-interior>\n"]}
@@ -55,6 +55,10 @@ export declare class ClassifyPipelineTabComponent extends BaseAngularComponent {
55
55
  TrendingTags: TagCloudItem[];
56
56
  /** Per-source live-run detail rows (shown during an active run). */
57
57
  LiveRunDetailRows: RunDetailRow[];
58
+ /** Total content-item count in the DB (from TotalRowCount) — drives the "Showing X of Y" line. */
59
+ TotalItemCount: number;
60
+ /** True while the host is loading the next page of content items. */
61
+ IsLoadingMoreItems: boolean;
58
62
  IsRunning: boolean;
59
63
  IsPaused: boolean;
60
64
  RunProgress: number;
@@ -93,6 +97,11 @@ export declare class ClassifyPipelineTabComponent extends BaseAngularComponent {
93
97
  FeedItemClicked: EventEmitter<number>;
94
98
  /** Toggle the config panel → host `TogglePipelineConfig()` (persists + reports to agent). */
95
99
  ConfigToggled: EventEmitter<void>;
100
+ /** Request the host load the next page of content items (no silent truncation). */
101
+ LoadMoreItemsRequested: EventEmitter<void>;
102
+ /** Whether more content items exist in the DB than are currently loaded into the feed. */
103
+ get HasMoreItems(): boolean;
104
+ onLoadMoreItems(): void;
96
105
  /** Feed items filtered by search query and sorted. */
97
106
  get FilteredFeedItems(): FeedItem[];
98
107
  /** Paginated feed items for the current page. */
@@ -117,6 +126,6 @@ export declare class ClassifyPipelineTabComponent extends BaseAngularComponent {
117
126
  onFeedItemClick(originalIndex: number): void;
118
127
  onToggleConfig(): void;
119
128
  static ɵfac: i0.ɵɵFactoryDeclaration<ClassifyPipelineTabComponent, never>;
120
- static ɵcmp: i0.ɵɵComponentDeclaration<ClassifyPipelineTabComponent, "classify-pipeline-tab", never, { "KPIMetrics": { "alias": "KPIMetrics"; "required": false; }; "PipelineStages": { "alias": "PipelineStages"; "required": false; }; "FeedItems": { "alias": "FeedItems"; "required": false; }; "SourceMinis": { "alias": "SourceMinis"; "required": false; }; "TrendingTags": { "alias": "TrendingTags"; "required": false; }; "LiveRunDetailRows": { "alias": "LiveRunDetailRows"; "required": false; }; "IsRunning": { "alias": "IsRunning"; "required": false; }; "IsPaused": { "alias": "IsPaused"; "required": false; }; "RunProgress": { "alias": "RunProgress"; "required": false; }; "RunStage": { "alias": "RunStage"; "required": false; }; "RunCurrentItem": { "alias": "RunCurrentItem"; "required": false; }; "CurrentProcessRunID": { "alias": "CurrentProcessRunID"; "required": false; }; "PipelineConfig": { "alias": "PipelineConfig"; "required": false; }; "ShowPipelineConfig": { "alias": "ShowPipelineConfig"; "required": false; }; }, { "RefreshRequested": "RefreshRequested"; "PauseRequested": "PauseRequested"; "ResumeRequested": "ResumeRequested"; "CancelRequested": "CancelRequested"; "LoadLiveRunDetailsRequested": "LoadLiveRunDetailsRequested"; "FeedItemClicked": "FeedItemClicked"; "ConfigToggled": "ConfigToggled"; }, never, never, false, never>;
129
+ static ɵcmp: i0.ɵɵComponentDeclaration<ClassifyPipelineTabComponent, "classify-pipeline-tab", never, { "KPIMetrics": { "alias": "KPIMetrics"; "required": false; }; "PipelineStages": { "alias": "PipelineStages"; "required": false; }; "FeedItems": { "alias": "FeedItems"; "required": false; }; "SourceMinis": { "alias": "SourceMinis"; "required": false; }; "TrendingTags": { "alias": "TrendingTags"; "required": false; }; "LiveRunDetailRows": { "alias": "LiveRunDetailRows"; "required": false; }; "TotalItemCount": { "alias": "TotalItemCount"; "required": false; }; "IsLoadingMoreItems": { "alias": "IsLoadingMoreItems"; "required": false; }; "IsRunning": { "alias": "IsRunning"; "required": false; }; "IsPaused": { "alias": "IsPaused"; "required": false; }; "RunProgress": { "alias": "RunProgress"; "required": false; }; "RunStage": { "alias": "RunStage"; "required": false; }; "RunCurrentItem": { "alias": "RunCurrentItem"; "required": false; }; "CurrentProcessRunID": { "alias": "CurrentProcessRunID"; "required": false; }; "PipelineConfig": { "alias": "PipelineConfig"; "required": false; }; "ShowPipelineConfig": { "alias": "ShowPipelineConfig"; "required": false; }; }, { "RefreshRequested": "RefreshRequested"; "PauseRequested": "PauseRequested"; "ResumeRequested": "ResumeRequested"; "CancelRequested": "CancelRequested"; "LoadLiveRunDetailsRequested": "LoadLiveRunDetailsRequested"; "FeedItemClicked": "FeedItemClicked"; "ConfigToggled": "ConfigToggled"; "LoadMoreItemsRequested": "LoadMoreItemsRequested"; }, never, never, false, never>;
121
130
  }
122
131
  //# sourceMappingURL=pipeline-tab.component.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pipeline-tab.component.d.ts","sourceRoot":"","sources":["../../../../../src/AI/components/autotagging/tabs/pipeline-tab.component.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pipeline-tab.component.d.ts","sourceRoot":"","sources":["../../../../../src/AI/components/autotagging/tabs/pipeline-tab.component.ts"],"names":[],"mappings":"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"}