@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
@@ -11,32 +11,50 @@
11
11
  import { Component, ChangeDetectorRef, EventEmitter, Input, Output, inject } from '@angular/core';
12
12
  import { NormalizeUUID } from '@memberjunction/global';
13
13
  import { BaseAngularComponent } from '@memberjunction/ng-base-types';
14
- import { formatWeight, tagFontSize, formatShortDate } from '../shared/classify.format';
14
+ import { formatWeight, tagFontSize, formatShortDate, deriveDisplayName } from '../shared/classify.format';
15
15
  import * as i0 from "@angular/core";
16
16
  import * as i1 from "@angular/forms";
17
- import * as i2 from "@memberjunction/ng-ui-components";
18
- import * as i3 from "@memberjunction/ng-word-cloud";
17
+ import * as i2 from "@memberjunction/ng-shared-generic";
18
+ import * as i3 from "@memberjunction/ng-ui-components";
19
+ import * as i4 from "@memberjunction/ng-word-cloud";
19
20
  const _forTrack0 = ($index, $item) => $item.Tag;
20
21
  const _forTrack1 = ($index, $item) => $item.SourceName;
21
22
  const _forTrack2 = ($index, $item) => $item.ID;
22
- function ClassifyTagsTabComponent_For_27_Template(rf, ctx) { if (rf & 1) {
23
+ function ClassifyTagsTabComponent_Conditional_3_Template(rf, ctx) { if (rf & 1) {
24
+ i0.ɵɵelement(0, "i", 27);
25
+ i0.ɵɵelementStart(1, "span", 28);
26
+ i0.ɵɵtext(2, "Refreshing\u2026");
27
+ i0.ɵɵelementEnd();
28
+ } }
29
+ function ClassifyTagsTabComponent_Conditional_4_Template(rf, ctx) { if (rf & 1) {
30
+ i0.ɵɵelement(0, "i", 29);
31
+ i0.ɵɵelementStart(1, "span", 28);
32
+ i0.ɵɵtext(2, "Refresh");
33
+ i0.ɵɵelementEnd();
34
+ } }
35
+ function ClassifyTagsTabComponent_Conditional_9_Template(rf, ctx) { if (rf & 1) {
36
+ i0.ɵɵelementStart(0, "div", 7);
37
+ i0.ɵɵelement(1, "mj-loading", 30);
38
+ i0.ɵɵelementEnd();
39
+ } }
40
+ function ClassifyTagsTabComponent_For_32_Template(rf, ctx) { if (rf & 1) {
23
41
  const _r1 = i0.ɵɵgetCurrentView();
24
- i0.ɵɵelementStart(0, "tr", 24);
25
- i0.ɵɵlistener("click", function ClassifyTagsTabComponent_For_27_Template_tr_click_0_listener() { const row_r2 = i0.ɵɵrestoreView(_r1).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.DrillDownTag(row_r2.Tag)); });
26
- i0.ɵɵelementStart(1, "td", 25);
42
+ i0.ɵɵelementStart(0, "tr", 31);
43
+ i0.ɵɵlistener("click", function ClassifyTagsTabComponent_For_32_Template_tr_click_0_listener() { const row_r2 = i0.ɵɵrestoreView(_r1).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.DrillDownTag(row_r2.Tag)); });
44
+ i0.ɵɵelementStart(1, "td", 32);
27
45
  i0.ɵɵtext(2);
28
46
  i0.ɵɵelementEnd();
29
47
  i0.ɵɵelementStart(3, "td");
30
48
  i0.ɵɵtext(4);
31
49
  i0.ɵɵelementEnd();
32
- i0.ɵɵelementStart(5, "td")(6, "div", 26)(7, "div", 27);
33
- i0.ɵɵelement(8, "div", 28);
50
+ i0.ɵɵelementStart(5, "td")(6, "div", 33)(7, "div", 34);
51
+ i0.ɵɵelement(8, "div", 35);
34
52
  i0.ɵɵelementEnd();
35
- i0.ɵɵelementStart(9, "span", 29);
53
+ i0.ɵɵelementStart(9, "span", 36);
36
54
  i0.ɵɵtext(10);
37
55
  i0.ɵɵelementEnd()()();
38
- i0.ɵɵelementStart(11, "td")(12, "div", 30);
39
- i0.ɵɵelement(13, "div", 31);
56
+ i0.ɵɵelementStart(11, "td")(12, "div", 37);
57
+ i0.ɵɵelement(13, "div", 38);
40
58
  i0.ɵɵelementEnd()();
41
59
  i0.ɵɵelementStart(14, "td");
42
60
  i0.ɵɵtext(15);
@@ -64,15 +82,15 @@ function ClassifyTagsTabComponent_For_27_Template(rf, ctx) { if (rf & 1) {
64
82
  i0.ɵɵadvance(2);
65
83
  i0.ɵɵtextInterpolate(row_r2.FirstSeen);
66
84
  } }
67
- function ClassifyTagsTabComponent_Conditional_28_Conditional_8_Template(rf, ctx) { if (rf & 1) {
68
- i0.ɵɵelementStart(0, "div", 38)(1, "p");
85
+ function ClassifyTagsTabComponent_Conditional_33_Conditional_8_Template(rf, ctx) { if (rf & 1) {
86
+ i0.ɵɵelementStart(0, "div", 45)(1, "p");
69
87
  i0.ɵɵtext(2, "No content items found for this tag.");
70
88
  i0.ɵɵelementEnd()();
71
89
  } }
72
- function ClassifyTagsTabComponent_Conditional_28_Conditional_9_For_13_Template(rf, ctx) { if (rf & 1) {
90
+ function ClassifyTagsTabComponent_Conditional_33_Conditional_9_For_13_Template(rf, ctx) { if (rf & 1) {
73
91
  const _r5 = i0.ɵɵgetCurrentView();
74
- i0.ɵɵelementStart(0, "tr", 24);
75
- i0.ɵɵlistener("click", function ClassifyTagsTabComponent_Conditional_28_Conditional_9_For_13_Template_tr_click_0_listener() { const di_r6 = i0.ɵɵrestoreView(_r5).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onOpenItemDetail(di_r6.ID)); });
92
+ i0.ɵɵelementStart(0, "tr", 31);
93
+ i0.ɵɵlistener("click", function ClassifyTagsTabComponent_Conditional_33_Conditional_9_For_13_Template_tr_click_0_listener() { const di_r6 = i0.ɵɵrestoreView(_r5).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.onOpenItemDetail(di_r6.ID)); });
76
94
  i0.ɵɵelementStart(1, "td");
77
95
  i0.ɵɵtext(2);
78
96
  i0.ɵɵelementEnd();
@@ -97,8 +115,8 @@ function ClassifyTagsTabComponent_Conditional_28_Conditional_9_For_13_Template(r
97
115
  i0.ɵɵadvance(2);
98
116
  i0.ɵɵtextInterpolate(di_r6.UpdatedAt);
99
117
  } }
100
- function ClassifyTagsTabComponent_Conditional_28_Conditional_9_Template(rf, ctx) { if (rf & 1) {
101
- i0.ɵɵelementStart(0, "table", 10)(1, "thead")(2, "tr")(3, "th");
118
+ function ClassifyTagsTabComponent_Conditional_33_Conditional_9_Template(rf, ctx) { if (rf & 1) {
119
+ i0.ɵɵelementStart(0, "table", 13)(1, "thead")(2, "tr")(3, "th");
102
120
  i0.ɵɵtext(4, "Name");
103
121
  i0.ɵɵelementEnd();
104
122
  i0.ɵɵelementStart(5, "th");
@@ -111,25 +129,25 @@ function ClassifyTagsTabComponent_Conditional_28_Conditional_9_Template(rf, ctx)
111
129
  i0.ɵɵtext(10, "Updated");
112
130
  i0.ɵɵelementEnd()()();
113
131
  i0.ɵɵelementStart(11, "tbody");
114
- i0.ɵɵrepeaterCreate(12, ClassifyTagsTabComponent_Conditional_28_Conditional_9_For_13_Template, 9, 4, "tr", 39, _forTrack2);
132
+ i0.ɵɵrepeaterCreate(12, ClassifyTagsTabComponent_Conditional_33_Conditional_9_For_13_Template, 9, 4, "tr", 46, _forTrack2);
115
133
  i0.ɵɵelementEnd()();
116
134
  } if (rf & 2) {
117
135
  const ctx_r2 = i0.ɵɵnextContext(2);
118
136
  i0.ɵɵadvance(12);
119
137
  i0.ɵɵrepeater(ctx_r2.TagDrillDownItems);
120
138
  } }
121
- function ClassifyTagsTabComponent_Conditional_28_Template(rf, ctx) { if (rf & 1) {
139
+ function ClassifyTagsTabComponent_Conditional_33_Template(rf, ctx) { if (rf & 1) {
122
140
  const _r4 = i0.ɵɵgetCurrentView();
123
- i0.ɵɵelementStart(0, "div", 12)(1, "div", 32)(2, "span", 33);
124
- i0.ɵɵelement(3, "i", 34);
141
+ i0.ɵɵelementStart(0, "div", 15)(1, "div", 39)(2, "span", 40);
142
+ i0.ɵɵelement(3, "i", 41);
125
143
  i0.ɵɵtext(4);
126
144
  i0.ɵɵelementEnd();
127
- i0.ɵɵelementStart(5, "button", 35);
128
- i0.ɵɵlistener("click", function ClassifyTagsTabComponent_Conditional_28_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.CloseDrillDownTag()); });
129
- i0.ɵɵelement(6, "i", 36);
145
+ i0.ɵɵelementStart(5, "button", 42);
146
+ i0.ɵɵlistener("click", function ClassifyTagsTabComponent_Conditional_33_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.CloseDrillDownTag()); });
147
+ i0.ɵɵelement(6, "i", 43);
130
148
  i0.ɵɵelementEnd()();
131
- i0.ɵɵelementStart(7, "div", 37);
132
- i0.ɵɵconditionalCreate(8, ClassifyTagsTabComponent_Conditional_28_Conditional_8_Template, 3, 0, "div", 38)(9, ClassifyTagsTabComponent_Conditional_28_Conditional_9_Template, 14, 0, "table", 10);
149
+ i0.ɵɵelementStart(7, "div", 44);
150
+ i0.ɵɵconditionalCreate(8, ClassifyTagsTabComponent_Conditional_33_Conditional_8_Template, 3, 0, "div", 45)(9, ClassifyTagsTabComponent_Conditional_33_Conditional_9_Template, 14, 0, "table", 13);
133
151
  i0.ɵɵelementEnd()();
134
152
  } if (rf & 2) {
135
153
  const ctx_r2 = i0.ɵɵnextContext();
@@ -138,19 +156,19 @@ function ClassifyTagsTabComponent_Conditional_28_Template(rf, ctx) { if (rf & 1)
138
156
  i0.ɵɵadvance(4);
139
157
  i0.ɵɵconditional(ctx_r2.TagDrillDownItems.length === 0 ? 8 : 9);
140
158
  } }
141
- function ClassifyTagsTabComponent_Conditional_34_Template(rf, ctx) { if (rf & 1) {
142
- i0.ɵɵelement(0, "mj-word-cloud", 17);
159
+ function ClassifyTagsTabComponent_Conditional_39_Template(rf, ctx) { if (rf & 1) {
160
+ i0.ɵɵelement(0, "mj-word-cloud", 20);
143
161
  } if (rf & 2) {
144
162
  const ctx_r2 = i0.ɵɵnextContext();
145
163
  i0.ɵɵproperty("Items", ctx_r2.TagCloudWordItems)("MaxFontSize", 40)("MinFontSize", 12)("MaxItems", 20)("Interactive", true)("Animate", true);
146
164
  } }
147
- function ClassifyTagsTabComponent_Conditional_35_Template(rf, ctx) { if (rf & 1) {
148
- i0.ɵɵelementStart(0, "div", 18);
165
+ function ClassifyTagsTabComponent_Conditional_40_Template(rf, ctx) { if (rf & 1) {
166
+ i0.ɵɵelementStart(0, "div", 21);
149
167
  i0.ɵɵtext(1, "No tags yet");
150
168
  i0.ɵɵelementEnd();
151
169
  } }
152
- function ClassifyTagsTabComponent_For_42_Template(rf, ctx) { if (rf & 1) {
153
- i0.ɵɵelementStart(0, "div", 23)(1, "span");
170
+ function ClassifyTagsTabComponent_For_47_Template(rf, ctx) { if (rf & 1) {
171
+ i0.ɵɵelementStart(0, "div", 26)(1, "span");
154
172
  i0.ɵɵtext(2);
155
173
  i0.ɵɵelementEnd();
156
174
  i0.ɵɵelementStart(3, "strong");
@@ -183,6 +201,8 @@ export class ClassifyTagsTabComponent extends BaseAngularComponent {
183
201
  get ContentItems() {
184
202
  return this._contentItems;
185
203
  }
204
+ /** Shown while a manual Refresh() rebuilds the tag view models. */
205
+ IsLoading = false;
186
206
  TagRows = [];
187
207
  FilteredTagRows = [];
188
208
  TagCloudWordItems = [];
@@ -209,6 +229,18 @@ export class ClassifyTagsTabComponent extends BaseAngularComponent {
209
229
  this.buildTagsBySource();
210
230
  this.FilterTags();
211
231
  }
232
+ /**
233
+ * Rebuild the tag view models from the current host-supplied inputs. The tag
234
+ * data is host-owned (flows in via [ContentTags]/[ContentItems]); Refresh
235
+ * recomputes the rows/cloud/breakdown and surfaces a brief loading state.
236
+ */
237
+ async Refresh() {
238
+ this.IsLoading = true;
239
+ this.cdr.detectChanges();
240
+ this.rebuild();
241
+ this.IsLoading = false;
242
+ this.cdr.detectChanges();
243
+ }
212
244
  // ── External control surface (host deep-link + agent tool) ──
213
245
  /** Apply a search query programmatically (used by the agent tool + deep link). Returns the match count. */
214
246
  ApplySearch(query) {
@@ -292,7 +324,7 @@ export class ClassifyTagsTabComponent extends BaseAngularComponent {
292
324
  if (weight !== undefined) {
293
325
  this.TagDrillDownItems.push({
294
326
  ID: item['ID'],
295
- Name: item['Name'] ?? 'Unnamed',
327
+ Name: deriveDisplayName({ Name: item['Name'], Description: item['Description'] }),
296
328
  SourceName: item['ContentSource'] ?? 'Unknown',
297
329
  Weight: weight,
298
330
  UpdatedAt: formatShortDate(item['__mj_UpdatedAt'] ?? ''),
@@ -377,66 +409,78 @@ export class ClassifyTagsTabComponent extends BaseAngularComponent {
377
409
  return result;
378
410
  }
379
411
  static ɵfac = /*@__PURE__*/ (() => { let ɵClassifyTagsTabComponent_BaseFactory; return function ClassifyTagsTabComponent_Factory(__ngFactoryType__) { return (ɵClassifyTagsTabComponent_BaseFactory || (ɵClassifyTagsTabComponent_BaseFactory = i0.ɵɵgetInheritedFactory(ClassifyTagsTabComponent)))(__ngFactoryType__ || ClassifyTagsTabComponent); }; })();
380
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ClassifyTagsTabComponent, selectors: [["classify-tags-tab"]], inputs: { ContentTags: "ContentTags", ContentItems: "ContentItems" }, outputs: { OpenItemDetailRequested: "OpenItemDetailRequested" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 43, vars: 6, consts: [["Title", "Tag Library", 3, "Subtitle"], ["toolbar", ""], ["type", "text", "placeholder", "Search tags...", 1, "at-search-input", 3, "ngModelChange", "input", "ngModel"], [3, "Padding", "Flex"], [1, "at-main-area"], [1, "at-page-body"], [1, "at-tag-lib-layout"], [1, "at-tag-lib-main"], [1, "at-card"], [1, "at-card-body", 2, "max-height", "500px", "overflow-y", "auto"], [1, "at-tag-table"], [1, "at-tag-row-clickable", 3, "at-tag-row-selected"], [1, "at-card", 2, "margin-top", "12px"], [1, "at-tag-lib-sidebar"], [1, "at-card", "at-tag-cloud-card"], [1, "at-card-title", 2, "margin-bottom", "12px"], [1, "fa-solid", "fa-cloud"], ["Layout", "spiral", "ColorMode", "weight-gradient", 3, "Items", "MaxFontSize", "MinFontSize", "MaxItems", "Interactive", "Animate"], [1, "at-tag-cloud-empty"], [1, "at-card", 2, "padding", "16px", "margin-top", "12px"], [1, "at-card-title", 2, "margin-bottom", "10px"], [1, "fa-solid", "fa-chart-pie"], [1, "at-tags-by-source"], [1, "at-tag-source-row"], [1, "at-tag-row-clickable", 3, "click"], [1, "at-tag-name-cell"], [1, "at-weight-indicator"], [1, "at-weight-bar"], [1, "at-weight-bar-fill"], [1, "at-weight-value"], [1, "at-tag-bar"], [1, "at-tag-bar-fill"], [1, "at-card-header"], [1, "at-card-title"], [1, "fa-solid", "fa-tag"], ["aria-label", "Close", 1, "at-slide-close", 2, "background", "none", "border", "none", "cursor", "pointer", "color", "var(--mj-text-muted)", 3, "click"], [1, "fa-solid", "fa-times"], [1, "at-card-body", 2, "max-height", "300px", "overflow-y", "auto"], [1, "at-empty-state"], [1, "at-tag-row-clickable"]], template: function ClassifyTagsTabComponent_Template(rf, ctx) { if (rf & 1) {
381
- i0.ɵɵelementStart(0, "mj-page-header-interior", 0)(1, "div", 1)(2, "input", 2);
382
- i0.ɵɵtwoWayListener("ngModelChange", function ClassifyTagsTabComponent_Template_input_ngModelChange_2_listener($event) { i0.ɵɵtwoWayBindingSet(ctx.TagSearchQuery, $event) || (ctx.TagSearchQuery = $event); return $event; });
383
- i0.ɵɵlistener("input", function ClassifyTagsTabComponent_Template_input_input_2_listener() { return ctx.FilterTags(); });
412
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ClassifyTagsTabComponent, selectors: [["classify-tags-tab"]], inputs: { ContentTags: "ContentTags", ContentItems: "ContentItems" }, outputs: { OpenItemDetailRequested: "OpenItemDetailRequested" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 48, vars: 9, consts: [["Title", "Tag Library", 3, "Subtitle"], ["actions", ""], ["mjButton", "", "variant", "secondary", "size", "sm", 3, "click", "disabled"], ["toolbar", ""], ["type", "text", "placeholder", "Search tags...", 1, "at-search-input", 3, "ngModelChange", "input", "ngModel"], [3, "Padding", "Flex"], [1, "at-main-area"], [1, "at-loading-overlay"], [1, "at-page-body"], [1, "at-tag-lib-layout"], [1, "at-tag-lib-main"], [1, "at-card"], [1, "at-card-body", 2, "max-height", "500px", "overflow-y", "auto"], [1, "at-tag-table"], [1, "at-tag-row-clickable", 3, "at-tag-row-selected"], [1, "at-card", 2, "margin-top", "12px"], [1, "at-tag-lib-sidebar"], [1, "at-card", "at-tag-cloud-card"], [1, "at-card-title", 2, "margin-bottom", "12px"], [1, "fa-solid", "fa-cloud"], ["Layout", "spiral", "ColorMode", "weight-gradient", 3, "Items", "MaxFontSize", "MinFontSize", "MaxItems", "Interactive", "Animate"], [1, "at-tag-cloud-empty"], [1, "at-card", 2, "padding", "16px", "margin-top", "12px"], [1, "at-card-title", 2, "margin-bottom", "10px"], [1, "fa-solid", "fa-chart-pie"], [1, "at-tags-by-source"], [1, "at-tag-source-row"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "mj-action-label"], [1, "fa-solid", "fa-arrows-rotate"], ["text", "Refreshing tags\u2026"], [1, "at-tag-row-clickable", 3, "click"], [1, "at-tag-name-cell"], [1, "at-weight-indicator"], [1, "at-weight-bar"], [1, "at-weight-bar-fill"], [1, "at-weight-value"], [1, "at-tag-bar"], [1, "at-tag-bar-fill"], [1, "at-card-header"], [1, "at-card-title"], [1, "fa-solid", "fa-tag"], ["aria-label", "Close", 1, "at-slide-close", 2, "background", "none", "border", "none", "cursor", "pointer", "color", "var(--mj-text-muted)", 3, "click"], [1, "fa-solid", "fa-times"], [1, "at-card-body", 2, "max-height", "300px", "overflow-y", "auto"], [1, "at-empty-state"], [1, "at-tag-row-clickable"]], template: function ClassifyTagsTabComponent_Template(rf, ctx) { if (rf & 1) {
413
+ i0.ɵɵelementStart(0, "mj-page-header-interior", 0)(1, "div", 1)(2, "button", 2);
414
+ i0.ɵɵlistener("click", function ClassifyTagsTabComponent_Template_button_click_2_listener() { return ctx.Refresh(); });
415
+ i0.ɵɵconditionalCreate(3, ClassifyTagsTabComponent_Conditional_3_Template, 3, 0)(4, ClassifyTagsTabComponent_Conditional_4_Template, 3, 0);
416
+ i0.ɵɵelementEnd()();
417
+ i0.ɵɵelementStart(5, "div", 3)(6, "input", 4);
418
+ i0.ɵɵtwoWayListener("ngModelChange", function ClassifyTagsTabComponent_Template_input_ngModelChange_6_listener($event) { i0.ɵɵtwoWayBindingSet(ctx.TagSearchQuery, $event) || (ctx.TagSearchQuery = $event); return $event; });
419
+ i0.ɵɵlistener("input", function ClassifyTagsTabComponent_Template_input_input_6_listener() { return ctx.FilterTags(); });
384
420
  i0.ɵɵelementEnd()()();
385
- i0.ɵɵelementStart(3, "mj-page-body-interior", 3)(4, "div", 4)(5, "div", 5)(6, "div", 6)(7, "div", 7)(8, "div", 8)(9, "div", 9)(10, "table", 10)(11, "thead")(12, "tr")(13, "th");
386
- i0.ɵɵtext(14, "Tag");
421
+ i0.ɵɵelementStart(7, "mj-page-body-interior", 5)(8, "div", 6);
422
+ i0.ɵɵconditionalCreate(9, ClassifyTagsTabComponent_Conditional_9_Template, 2, 0, "div", 7);
423
+ i0.ɵɵelementStart(10, "div", 8)(11, "div", 9)(12, "div", 10)(13, "div", 11)(14, "div", 12)(15, "table", 13)(16, "thead")(17, "tr")(18, "th");
424
+ i0.ɵɵtext(19, "Tag");
387
425
  i0.ɵɵelementEnd();
388
- i0.ɵɵelementStart(15, "th");
389
- i0.ɵɵtext(16, "Count");
426
+ i0.ɵɵelementStart(20, "th");
427
+ i0.ɵɵtext(21, "Count");
390
428
  i0.ɵɵelementEnd();
391
- i0.ɵɵelementStart(17, "th");
392
- i0.ɵɵtext(18, "Avg Weight");
429
+ i0.ɵɵelementStart(22, "th");
430
+ i0.ɵɵtext(23, "Avg Weight");
393
431
  i0.ɵɵelementEnd();
394
- i0.ɵɵelementStart(19, "th");
395
- i0.ɵɵtext(20, "Distribution");
432
+ i0.ɵɵelementStart(24, "th");
433
+ i0.ɵɵtext(25, "Distribution");
396
434
  i0.ɵɵelementEnd();
397
- i0.ɵɵelementStart(21, "th");
398
- i0.ɵɵtext(22, "Top Source");
435
+ i0.ɵɵelementStart(26, "th");
436
+ i0.ɵɵtext(27, "Top Source");
399
437
  i0.ɵɵelementEnd();
400
- i0.ɵɵelementStart(23, "th");
401
- i0.ɵɵtext(24, "First Seen");
438
+ i0.ɵɵelementStart(28, "th");
439
+ i0.ɵɵtext(29, "First Seen");
402
440
  i0.ɵɵelementEnd()()();
403
- i0.ɵɵelementStart(25, "tbody");
404
- i0.ɵɵrepeaterCreate(26, ClassifyTagsTabComponent_For_27_Template, 18, 17, "tr", 11, _forTrack0);
441
+ i0.ɵɵelementStart(30, "tbody");
442
+ i0.ɵɵrepeaterCreate(31, ClassifyTagsTabComponent_For_32_Template, 18, 17, "tr", 14, _forTrack0);
405
443
  i0.ɵɵelementEnd()()()();
406
- i0.ɵɵconditionalCreate(28, ClassifyTagsTabComponent_Conditional_28_Template, 10, 3, "div", 12);
444
+ i0.ɵɵconditionalCreate(33, ClassifyTagsTabComponent_Conditional_33_Template, 10, 3, "div", 15);
407
445
  i0.ɵɵelementEnd();
408
- i0.ɵɵelementStart(29, "div", 13)(30, "div", 14)(31, "div", 15);
409
- i0.ɵɵelement(32, "i", 16);
410
- i0.ɵɵtext(33, " Tag Cloud");
446
+ i0.ɵɵelementStart(34, "div", 16)(35, "div", 17)(36, "div", 18);
447
+ i0.ɵɵelement(37, "i", 19);
448
+ i0.ɵɵtext(38, " Tag Cloud");
411
449
  i0.ɵɵelementEnd();
412
- i0.ɵɵconditionalCreate(34, ClassifyTagsTabComponent_Conditional_34_Template, 1, 6, "mj-word-cloud", 17)(35, ClassifyTagsTabComponent_Conditional_35_Template, 2, 0, "div", 18);
450
+ i0.ɵɵconditionalCreate(39, ClassifyTagsTabComponent_Conditional_39_Template, 1, 6, "mj-word-cloud", 20)(40, ClassifyTagsTabComponent_Conditional_40_Template, 2, 0, "div", 21);
413
451
  i0.ɵɵelementEnd();
414
- i0.ɵɵelementStart(36, "div", 19)(37, "div", 20);
415
- i0.ɵɵelement(38, "i", 21);
416
- i0.ɵɵtext(39, " By Source");
452
+ i0.ɵɵelementStart(41, "div", 22)(42, "div", 23);
453
+ i0.ɵɵelement(43, "i", 24);
454
+ i0.ɵɵtext(44, " By Source");
417
455
  i0.ɵɵelementEnd();
418
- i0.ɵɵelementStart(40, "div", 22);
419
- i0.ɵɵrepeaterCreate(41, ClassifyTagsTabComponent_For_42_Template, 5, 2, "div", 23, _forTrack1);
456
+ i0.ɵɵelementStart(45, "div", 25);
457
+ i0.ɵɵrepeaterCreate(46, ClassifyTagsTabComponent_For_47_Template, 5, 2, "div", 26, _forTrack1);
420
458
  i0.ɵɵelementEnd()()()()()()();
421
459
  } if (rf & 2) {
422
460
  i0.ɵɵproperty("Subtitle", ctx.Subtitle);
423
461
  i0.ɵɵadvance(2);
462
+ i0.ɵɵproperty("disabled", ctx.IsLoading);
463
+ i0.ɵɵadvance();
464
+ i0.ɵɵconditional(ctx.IsLoading ? 3 : 4);
465
+ i0.ɵɵadvance(3);
424
466
  i0.ɵɵtwoWayProperty("ngModel", ctx.TagSearchQuery);
425
467
  i0.ɵɵadvance();
426
468
  i0.ɵɵproperty("Padding", false)("Flex", true);
427
- i0.ɵɵadvance(23);
469
+ i0.ɵɵadvance(2);
470
+ i0.ɵɵconditional(ctx.IsLoading ? 9 : -1);
471
+ i0.ɵɵadvance(22);
428
472
  i0.ɵɵrepeater(ctx.FilteredTagRows);
429
473
  i0.ɵɵadvance(2);
430
- i0.ɵɵconditional(ctx.SelectedDrillDownTag ? 28 : -1);
474
+ i0.ɵɵconditional(ctx.SelectedDrillDownTag ? 33 : -1);
431
475
  i0.ɵɵadvance(6);
432
- i0.ɵɵconditional(ctx.TagCloudWordItems.length > 0 ? 34 : 35);
476
+ i0.ɵɵconditional(ctx.TagCloudWordItems.length > 0 ? 39 : 40);
433
477
  i0.ɵɵadvance(7);
434
478
  i0.ɵɵrepeater(ctx.TagsBySource);
435
- } }, dependencies: [i1.DefaultValueAccessor, i1.NgControlStatus, i1.NgModel, i2.MJPageHeaderInteriorComponent, i2.MJPageBodyInteriorComponent, i3.MJWordCloudComponent], encapsulation: 2 });
479
+ } }, dependencies: [i1.DefaultValueAccessor, i1.NgControlStatus, i1.NgModel, i2.LoadingComponent, i3.MJButtonDirective, i3.MJPageHeaderInteriorComponent, i3.MJPageBodyInteriorComponent, i4.MJWordCloudComponent], encapsulation: 2 });
436
480
  }
437
481
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ClassifyTagsTabComponent, [{
438
482
  type: Component,
439
- args: [{ standalone: false, selector: 'classify-tags-tab', template: "<mj-page-header-interior\n Title=\"Tag Library\"\n [Subtitle]=\"Subtitle\">\n <div toolbar>\n <input type=\"text\" class=\"at-search-input\" placeholder=\"Search tags...\"\n [(ngModel)]=\"TagSearchQuery\" (input)=\"FilterTags()\">\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-tag-lib-layout\">\n <div class=\"at-tag-lib-main\">\n <div class=\"at-card\">\n <div class=\"at-card-body\" style=\"max-height: 500px; overflow-y: auto;\">\n <table class=\"at-tag-table\">\n <thead>\n <tr>\n <th>Tag</th>\n <th>Count</th>\n <th>Avg Weight</th>\n <th>Distribution</th>\n <th>Top Source</th>\n <th>First Seen</th>\n </tr>\n </thead>\n <tbody>\n @for (row of FilteredTagRows; track row.Tag) {\n <tr class=\"at-tag-row-clickable\" (click)=\"DrillDownTag(row.Tag)\"\n [class.at-tag-row-selected]=\"SelectedDrillDownTag === row.Tag\">\n <td class=\"at-tag-name-cell\">{{ row.Tag }}</td>\n <td>{{ row.UsageCount }}</td>\n <td>\n <div class=\"at-weight-indicator\">\n <div class=\"at-weight-bar\">\n <div class=\"at-weight-bar-fill\" [style.width.%]=\"row.AvgWeight * 100\"\n [class.at-weight-high]=\"row.AvgWeight >= 0.7\"\n [class.at-weight-medium]=\"row.AvgWeight >= 0.4 && row.AvgWeight < 0.7\"\n [class.at-weight-low]=\"row.AvgWeight < 0.4\"></div>\n </div>\n <span class=\"at-weight-value\">{{ row.AvgWeight.toFixed(2) }}</span>\n </div>\n </td>\n <td>\n <div class=\"at-tag-bar\">\n <div class=\"at-tag-bar-fill\" [style.width.%]=\"row.BarWidthPct\"></div>\n </div>\n </td>\n <td>{{ row.TopSource }}</td>\n <td>{{ row.FirstSeen }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </div>\n\n <!-- Tag drill-down: content items matching selected tag -->\n @if (SelectedDrillDownTag) {\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-tag\"></i>\n Content items tagged \"{{ SelectedDrillDownTag }}\"\n ({{ TagDrillDownItems.length }})\n </span>\n <button class=\"at-slide-close\" (click)=\"CloseDrillDownTag()\" style=\"background:none;border:none;cursor:pointer;color:var(--mj-text-muted)\" aria-label=\"Close\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n <div class=\"at-card-body\" style=\"max-height: 300px; overflow-y: auto;\">\n @if (TagDrillDownItems.length === 0) {\n <div class=\"at-empty-state\"><p>No content items found for this tag.</p></div>\n } @else {\n <table class=\"at-tag-table\">\n <thead>\n <tr>\n <th>Name</th>\n <th>Source</th>\n <th>Weight</th>\n <th>Updated</th>\n </tr>\n </thead>\n <tbody>\n @for (di of TagDrillDownItems; track di.ID) {\n <tr class=\"at-tag-row-clickable\" (click)=\"onOpenItemDetail(di.ID)\">\n <td>{{ di.Name }}</td>\n <td>{{ di.SourceName }}</td>\n <td>{{ FormatWeight(di.Weight) }}</td>\n <td>{{ di.UpdatedAt }}</td>\n </tr>\n }\n </tbody>\n </table>\n }\n </div>\n </div>\n }\n </div>\n <div class=\"at-tag-lib-sidebar\">\n <div class=\"at-card at-tag-cloud-card\">\n <div class=\"at-card-title\" style=\"margin-bottom: 12px;\"><i class=\"fa-solid fa-cloud\"></i> Tag Cloud</div>\n @if (TagCloudWordItems.length > 0) {\n <mj-word-cloud\n [Items]=\"TagCloudWordItems\"\n [MaxFontSize]=\"40\"\n [MinFontSize]=\"12\"\n [MaxItems]=\"20\"\n Layout=\"spiral\"\n ColorMode=\"weight-gradient\"\n [Interactive]=\"true\"\n [Animate]=\"true\">\n </mj-word-cloud>\n } @else {\n <div class=\"at-tag-cloud-empty\">No tags yet</div>\n }\n </div>\n <div class=\"at-card\" style=\"padding: 16px; margin-top: 12px;\">\n <div class=\"at-card-title\" style=\"margin-bottom: 10px;\"><i class=\"fa-solid fa-chart-pie\"></i> By Source</div>\n <div class=\"at-tags-by-source\">\n @for (s of TagsBySource; track s.SourceName) {\n <div class=\"at-tag-source-row\">\n <span>{{ s.SourceName }}</span>\n <strong>{{ s.Count }}</strong>\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n</mj-page-body-interior>\n", styles: ["/*\n * Tag Library 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"] }]
483
+ args: [{ standalone: false, selector: 'classify-tags-tab', template: "<mj-page-header-interior\n Title=\"Tag Library\"\n [Subtitle]=\"Subtitle\">\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 <input type=\"text\" class=\"at-search-input\" placeholder=\"Search tags...\"\n [(ngModel)]=\"TagSearchQuery\" (input)=\"FilterTags()\">\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 tags\u2026\"></mj-loading>\n </div>\n }\n <div class=\"at-page-body\">\n <div class=\"at-tag-lib-layout\">\n <div class=\"at-tag-lib-main\">\n <div class=\"at-card\">\n <div class=\"at-card-body\" style=\"max-height: 500px; overflow-y: auto;\">\n <table class=\"at-tag-table\">\n <thead>\n <tr>\n <th>Tag</th>\n <th>Count</th>\n <th>Avg Weight</th>\n <th>Distribution</th>\n <th>Top Source</th>\n <th>First Seen</th>\n </tr>\n </thead>\n <tbody>\n @for (row of FilteredTagRows; track row.Tag) {\n <tr class=\"at-tag-row-clickable\" (click)=\"DrillDownTag(row.Tag)\"\n [class.at-tag-row-selected]=\"SelectedDrillDownTag === row.Tag\">\n <td class=\"at-tag-name-cell\">{{ row.Tag }}</td>\n <td>{{ row.UsageCount }}</td>\n <td>\n <div class=\"at-weight-indicator\">\n <div class=\"at-weight-bar\">\n <div class=\"at-weight-bar-fill\" [style.width.%]=\"row.AvgWeight * 100\"\n [class.at-weight-high]=\"row.AvgWeight >= 0.7\"\n [class.at-weight-medium]=\"row.AvgWeight >= 0.4 && row.AvgWeight < 0.7\"\n [class.at-weight-low]=\"row.AvgWeight < 0.4\"></div>\n </div>\n <span class=\"at-weight-value\">{{ row.AvgWeight.toFixed(2) }}</span>\n </div>\n </td>\n <td>\n <div class=\"at-tag-bar\">\n <div class=\"at-tag-bar-fill\" [style.width.%]=\"row.BarWidthPct\"></div>\n </div>\n </td>\n <td>{{ row.TopSource }}</td>\n <td>{{ row.FirstSeen }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </div>\n\n <!-- Tag drill-down: content items matching selected tag -->\n @if (SelectedDrillDownTag) {\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-tag\"></i>\n Content items tagged \"{{ SelectedDrillDownTag }}\"\n ({{ TagDrillDownItems.length }})\n </span>\n <button class=\"at-slide-close\" (click)=\"CloseDrillDownTag()\" style=\"background:none;border:none;cursor:pointer;color:var(--mj-text-muted)\" aria-label=\"Close\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n <div class=\"at-card-body\" style=\"max-height: 300px; overflow-y: auto;\">\n @if (TagDrillDownItems.length === 0) {\n <div class=\"at-empty-state\"><p>No content items found for this tag.</p></div>\n } @else {\n <table class=\"at-tag-table\">\n <thead>\n <tr>\n <th>Name</th>\n <th>Source</th>\n <th>Weight</th>\n <th>Updated</th>\n </tr>\n </thead>\n <tbody>\n @for (di of TagDrillDownItems; track di.ID) {\n <tr class=\"at-tag-row-clickable\" (click)=\"onOpenItemDetail(di.ID)\">\n <td>{{ di.Name }}</td>\n <td>{{ di.SourceName }}</td>\n <td>{{ FormatWeight(di.Weight) }}</td>\n <td>{{ di.UpdatedAt }}</td>\n </tr>\n }\n </tbody>\n </table>\n }\n </div>\n </div>\n }\n </div>\n <div class=\"at-tag-lib-sidebar\">\n <div class=\"at-card at-tag-cloud-card\">\n <div class=\"at-card-title\" style=\"margin-bottom: 12px;\"><i class=\"fa-solid fa-cloud\"></i> Tag Cloud</div>\n @if (TagCloudWordItems.length > 0) {\n <mj-word-cloud\n [Items]=\"TagCloudWordItems\"\n [MaxFontSize]=\"40\"\n [MinFontSize]=\"12\"\n [MaxItems]=\"20\"\n Layout=\"spiral\"\n ColorMode=\"weight-gradient\"\n [Interactive]=\"true\"\n [Animate]=\"true\">\n </mj-word-cloud>\n } @else {\n <div class=\"at-tag-cloud-empty\">No tags yet</div>\n }\n </div>\n <div class=\"at-card\" style=\"padding: 16px; margin-top: 12px;\">\n <div class=\"at-card-title\" style=\"margin-bottom: 10px;\"><i class=\"fa-solid fa-chart-pie\"></i> By Source</div>\n <div class=\"at-tags-by-source\">\n @for (s of TagsBySource; track s.SourceName) {\n <div class=\"at-tag-source-row\">\n <span>{{ s.SourceName }}</span>\n <strong>{{ s.Count }}</strong>\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n</mj-page-body-interior>\n", styles: ["/*\n * Tag Library 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"] }]
440
484
  }], null, { ContentTags: [{
441
485
  type: Input
442
486
  }], ContentItems: [{
@@ -1 +1 @@
1
- {"version":3,"file":"tags-tab.component.js","sourceRoot":"","sources":["../../../../../src/AI/components/autotagging/tabs/tags-tab.component.ts","../../../../../src/AI/components/autotagging/tabs/tags-tab.component.html"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Classify · Tag Library tab.\n *\n * Self-contained sub-page: owns its header-interior (with the tag search box),\n * the tag rows table, the word cloud, the tags-by-source breakdown, and the\n * per-tag drill-down. Receives the shared raw tag + item rows from the host\n * orchestrator via `[ContentTags]`/`[ContentItems]` and rebuilds its view\n * models from them. Opening a content item from the drill-down is a cross-tab\n * concern owned by the host's slide-in, so it bubbles up via @Output.\n */\nimport { Component, ChangeDetectorRef, EventEmitter, Input, Output, inject } from '@angular/core';\nimport { NormalizeUUID } from '@memberjunction/global';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { WordCloudItem } from '@memberjunction/ng-word-cloud';\nimport { TagRow, TagBySource } from '../shared/classify.types';\nimport { formatWeight, tagFontSize, formatShortDate } from '../shared/classify.format';\n\n/** One row in the per-tag drill-down (content items carrying a given tag). */\ninterface TagDrillDownItem {\n ID: string;\n Name: string;\n SourceName: string;\n Weight: number;\n UpdatedAt: string;\n FeedIndex: number;\n}\n\n@Component({\n standalone: false,\n selector: 'classify-tags-tab',\n templateUrl: './tags-tab.component.html',\n styleUrls: ['./tags-tab.component.css']\n})\nexport class ClassifyTagsTabComponent extends BaseAngularComponent {\n private cdr = inject(ChangeDetectorRef);\n\n /** Shared raw `MJ: Content Item Tags` rows, supplied by the host orchestrator. */\n private _contentTags: Record<string, unknown>[] = [];\n @Input()\n set ContentTags(value: Record<string, unknown>[]) {\n this._contentTags = value ?? [];\n this.rebuild();\n }\n get ContentTags(): Record<string, unknown>[] {\n return this._contentTags;\n }\n\n /** Shared raw `MJ: Content Items` rows — used for source mapping and drill-down. */\n private _contentItems: Record<string, unknown>[] = [];\n @Input()\n set ContentItems(value: Record<string, unknown>[]) {\n this._contentItems = value ?? [];\n this.rebuild();\n }\n get ContentItems(): Record<string, unknown>[] {\n return this._contentItems;\n }\n\n public TagRows: TagRow[] = [];\n public FilteredTagRows: TagRow[] = [];\n public TagCloudWordItems: WordCloudItem[] = [];\n public TagsBySource: TagBySource[] = [];\n public TagSearchQuery = '';\n public SelectedDrillDownTag: string | null = null;\n public TagDrillDownItems: TagDrillDownItem[] = [];\n\n /** Subtitle reflects the live tag count, mirroring the former host subtitle. */\n public get Subtitle(): string {\n return `${this.TagRows.length} unique tags across all content sources`;\n }\n\n // Template-facing formatters (shared pure helpers exposed for the view).\n public readonly TagFontSize = tagFontSize;\n public readonly FormatWeight = formatWeight;\n\n /** Bubble a request to open a content item's detail slide-in (host-owned). */\n @Output() OpenItemDetailRequested = new EventEmitter<string>();\n\n public onOpenItemDetail(contentItemID: string): void {\n this.OpenItemDetailRequested.emit(contentItemID);\n }\n\n /** Rebuild all tag-tab view models from the current inputs. */\n private rebuild(): void {\n this.buildTagRows();\n this.buildTagCloud();\n this.buildTagsBySource();\n this.FilterTags();\n }\n\n // ── External control surface (host deep-link + agent tool) ──\n\n /** Apply a search query programmatically (used by the agent tool + deep link). Returns the match count. */\n public ApplySearch(query: string): number {\n this.TagSearchQuery = query;\n this.FilterTags();\n return this.FilteredTagRows.length;\n }\n\n // ── View-model building ──\n\n private buildTagRows(): void {\n const tagCounts = this.countAllTags();\n const avgWeights = this.computeAvgWeights();\n const tagSourceMap = this.getTopSourcePerTag();\n const tagFirstSeen = this.getFirstSeenPerTag();\n const sorted = Array.from(tagCounts.entries()).sort((a, b) => b[1] - a[1]);\n const maxCount = sorted.length > 0 ? sorted[0][1] : 1;\n\n this.TagRows = sorted.map(([tag, count]) => ({\n Tag: tag,\n UsageCount: count,\n AvgWeight: avgWeights.get(tag) ?? 1.0,\n BarWidthPct: Math.round((count / maxCount) * 100),\n TopSource: tagSourceMap.get(tag) ?? 'Unknown',\n FirstSeen: tagFirstSeen.get(tag) ?? ''\n }));\n }\n\n private buildTagCloud(): void {\n const tagCounts = this.countAllTags();\n const avgWeights = this.computeAvgWeights();\n // Sort by a combined score: usage count * avg weight (so high-weight, high-count tags bubble up)\n const scored = Array.from(tagCounts.entries()).map(([tag, count]) => {\n const weight = avgWeights.get(tag) ?? 1.0;\n return { tag, count, weight, score: count * weight };\n }).sort((a, b) => b.score - a.score).slice(0, 20);\n const maxScore = scored.length > 0 ? scored[0].score : 1;\n\n // Build WordCloudItem[] for the mj-word-cloud component\n this.TagCloudWordItems = scored.map(s => ({\n Text: s.tag,\n Weight: maxScore > 0 ? s.score / maxScore : 0,\n Metadata: { Count: s.count, AvgWeight: s.weight }\n }));\n }\n\n private buildTagsBySource(): void {\n const sourceTagCounts = new Map<string, number>();\n const itemSourceMap = new Map<string, string>();\n for (const item of this._contentItems) {\n itemSourceMap.set(item['ID'] as string, (item['ContentSource'] as string) ?? 'Unknown');\n }\n for (const tag of this._contentTags) {\n const source = itemSourceMap.get(tag['ItemID'] as string) ?? 'Unknown';\n sourceTagCounts.set(source, (sourceTagCounts.get(source) ?? 0) + 1);\n }\n this.TagsBySource = Array.from(sourceTagCounts.entries())\n .sort((a, b) => b[1] - a[1])\n .map(([name, count]) => ({ SourceName: name, Count: count }));\n }\n\n public FilterTags(): void {\n const q = this.TagSearchQuery.toLowerCase().trim();\n this.FilteredTagRows = q\n ? this.TagRows.filter(r => r.Tag.toLowerCase().includes(q))\n : this.TagRows;\n this.cdr.detectChanges();\n }\n\n /** Drill down into content items matching a specific tag. */\n public DrillDownTag(tagName: string): void {\n if (this.SelectedDrillDownTag === tagName) {\n this.CloseDrillDownTag();\n return;\n }\n this.SelectedDrillDownTag = tagName;\n\n // Find all content items that have this tag\n const matchingItemIDs = new Map<string, number>(); // itemID → weight\n for (const tag of this._contentTags) {\n if ((tag['Tag'] as string) === tagName) {\n matchingItemIDs.set(\n NormalizeUUID(tag['ItemID'] as string),\n Number(tag['Weight'] ?? 1)\n );\n }\n }\n\n this.TagDrillDownItems = [];\n for (let i = 0; i < this._contentItems.length; i++) {\n const item = this._contentItems[i];\n const normalizedID = NormalizeUUID(item['ID'] as string);\n const weight = matchingItemIDs.get(normalizedID);\n if (weight !== undefined) {\n this.TagDrillDownItems.push({\n ID: item['ID'] as string,\n Name: (item['Name'] as string) ?? 'Unnamed',\n SourceName: (item['ContentSource'] as string) ?? 'Unknown',\n Weight: weight,\n UpdatedAt: formatShortDate((item['__mj_UpdatedAt'] as string) ?? ''),\n FeedIndex: i,\n });\n }\n }\n\n // Sort by weight descending\n this.TagDrillDownItems.sort((a, b) => b.Weight - a.Weight);\n this.cdr.detectChanges();\n }\n\n public CloseDrillDownTag(): void {\n this.SelectedDrillDownTag = null;\n this.TagDrillDownItems = [];\n this.cdr.detectChanges();\n }\n\n // ── Aggregation utilities (read only the tag + item inputs) ──\n\n private countAllTags(): Map<string, number> {\n const counts = new Map<string, number>();\n for (const tag of this._contentTags) {\n const t = tag['Tag'] as string;\n if (t) counts.set(t, (counts.get(t) ?? 0) + 1);\n }\n return counts;\n }\n\n /** Compute average weight per tag across all occurrences. */\n private computeAvgWeights(): Map<string, number> {\n const sums = new Map<string, number>();\n const counts = new Map<string, number>();\n for (const tag of this._contentTags) {\n const t = tag['Tag'] as string;\n const w = Number(tag['Weight'] ?? 0.5);\n if (t) {\n sums.set(t, (sums.get(t) ?? 0) + w);\n counts.set(t, (counts.get(t) ?? 0) + 1);\n }\n }\n const avgs = new Map<string, number>();\n for (const [t, sum] of sums) {\n avgs.set(t, Math.round((sum / (counts.get(t) ?? 1)) * 100) / 100);\n }\n return avgs;\n }\n\n private getTopSourcePerTag(): Map<string, string> {\n const tagSourceCounts = new Map<string, Map<string, number>>();\n const itemSourceMap = new Map<string, string>();\n for (const item of this._contentItems) {\n itemSourceMap.set(item['ID'] as string, (item['ContentSource'] as string) ?? 'Unknown');\n }\n for (const tag of this._contentTags) {\n const t = tag['Tag'] as string;\n const source = itemSourceMap.get(tag['ItemID'] as string) ?? 'Unknown';\n if (!tagSourceCounts.has(t)) tagSourceCounts.set(t, new Map());\n const inner = tagSourceCounts.get(t)!;\n inner.set(source, (inner.get(source) ?? 0) + 1);\n }\n const result = new Map<string, string>();\n for (const [tag, sourceCounts] of tagSourceCounts) {\n let maxSource = 'Unknown';\n let maxCount = 0;\n for (const [source, count] of sourceCounts) {\n if (count > maxCount) { maxSource = source; maxCount = count; }\n }\n result.set(tag, maxSource);\n }\n return result;\n }\n\n private getFirstSeenPerTag(): Map<string, string> {\n const result = new Map<string, string>();\n for (const tag of this._contentTags) {\n const t = tag['Tag'] as string;\n if (t && !result.has(t)) {\n const date = tag['__mj_CreatedAt'] as string;\n result.set(t, date ? formatShortDate(date) : '');\n }\n }\n return result;\n }\n}\n","<mj-page-header-interior\n Title=\"Tag Library\"\n [Subtitle]=\"Subtitle\">\n <div toolbar>\n <input type=\"text\" class=\"at-search-input\" placeholder=\"Search tags...\"\n [(ngModel)]=\"TagSearchQuery\" (input)=\"FilterTags()\">\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-tag-lib-layout\">\n <div class=\"at-tag-lib-main\">\n <div class=\"at-card\">\n <div class=\"at-card-body\" style=\"max-height: 500px; overflow-y: auto;\">\n <table class=\"at-tag-table\">\n <thead>\n <tr>\n <th>Tag</th>\n <th>Count</th>\n <th>Avg Weight</th>\n <th>Distribution</th>\n <th>Top Source</th>\n <th>First Seen</th>\n </tr>\n </thead>\n <tbody>\n @for (row of FilteredTagRows; track row.Tag) {\n <tr class=\"at-tag-row-clickable\" (click)=\"DrillDownTag(row.Tag)\"\n [class.at-tag-row-selected]=\"SelectedDrillDownTag === row.Tag\">\n <td class=\"at-tag-name-cell\">{{ row.Tag }}</td>\n <td>{{ row.UsageCount }}</td>\n <td>\n <div class=\"at-weight-indicator\">\n <div class=\"at-weight-bar\">\n <div class=\"at-weight-bar-fill\" [style.width.%]=\"row.AvgWeight * 100\"\n [class.at-weight-high]=\"row.AvgWeight >= 0.7\"\n [class.at-weight-medium]=\"row.AvgWeight >= 0.4 && row.AvgWeight < 0.7\"\n [class.at-weight-low]=\"row.AvgWeight < 0.4\"></div>\n </div>\n <span class=\"at-weight-value\">{{ row.AvgWeight.toFixed(2) }}</span>\n </div>\n </td>\n <td>\n <div class=\"at-tag-bar\">\n <div class=\"at-tag-bar-fill\" [style.width.%]=\"row.BarWidthPct\"></div>\n </div>\n </td>\n <td>{{ row.TopSource }}</td>\n <td>{{ row.FirstSeen }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </div>\n\n <!-- Tag drill-down: content items matching selected tag -->\n @if (SelectedDrillDownTag) {\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-tag\"></i>\n Content items tagged \"{{ SelectedDrillDownTag }}\"\n ({{ TagDrillDownItems.length }})\n </span>\n <button class=\"at-slide-close\" (click)=\"CloseDrillDownTag()\" style=\"background:none;border:none;cursor:pointer;color:var(--mj-text-muted)\" aria-label=\"Close\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n <div class=\"at-card-body\" style=\"max-height: 300px; overflow-y: auto;\">\n @if (TagDrillDownItems.length === 0) {\n <div class=\"at-empty-state\"><p>No content items found for this tag.</p></div>\n } @else {\n <table class=\"at-tag-table\">\n <thead>\n <tr>\n <th>Name</th>\n <th>Source</th>\n <th>Weight</th>\n <th>Updated</th>\n </tr>\n </thead>\n <tbody>\n @for (di of TagDrillDownItems; track di.ID) {\n <tr class=\"at-tag-row-clickable\" (click)=\"onOpenItemDetail(di.ID)\">\n <td>{{ di.Name }}</td>\n <td>{{ di.SourceName }}</td>\n <td>{{ FormatWeight(di.Weight) }}</td>\n <td>{{ di.UpdatedAt }}</td>\n </tr>\n }\n </tbody>\n </table>\n }\n </div>\n </div>\n }\n </div>\n <div class=\"at-tag-lib-sidebar\">\n <div class=\"at-card at-tag-cloud-card\">\n <div class=\"at-card-title\" style=\"margin-bottom: 12px;\"><i class=\"fa-solid fa-cloud\"></i> Tag Cloud</div>\n @if (TagCloudWordItems.length > 0) {\n <mj-word-cloud\n [Items]=\"TagCloudWordItems\"\n [MaxFontSize]=\"40\"\n [MinFontSize]=\"12\"\n [MaxItems]=\"20\"\n Layout=\"spiral\"\n ColorMode=\"weight-gradient\"\n [Interactive]=\"true\"\n [Animate]=\"true\">\n </mj-word-cloud>\n } @else {\n <div class=\"at-tag-cloud-empty\">No tags yet</div>\n }\n </div>\n <div class=\"at-card\" style=\"padding: 16px; margin-top: 12px;\">\n <div class=\"at-card-title\" style=\"margin-bottom: 10px;\"><i class=\"fa-solid fa-chart-pie\"></i> By Source</div>\n <div class=\"at-tags-by-source\">\n @for (s of TagsBySource; track s.SourceName) {\n <div class=\"at-tag-source-row\">\n <span>{{ s.SourceName }}</span>\n <strong>{{ s.Count }}</strong>\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n</mj-page-body-interior>\n"]}
1
+ {"version":3,"file":"tags-tab.component.js","sourceRoot":"","sources":["../../../../../src/AI/components/autotagging/tabs/tags-tab.component.ts","../../../../../src/AI/components/autotagging/tabs/tags-tab.component.html"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Classify · Tag Library tab.\n *\n * Self-contained sub-page: owns its header-interior (with the tag search box),\n * the tag rows table, the word cloud, the tags-by-source breakdown, and the\n * per-tag drill-down. Receives the shared raw tag + item rows from the host\n * orchestrator via `[ContentTags]`/`[ContentItems]` and rebuilds its view\n * models from them. Opening a content item from the drill-down is a cross-tab\n * concern owned by the host's slide-in, so it bubbles up via @Output.\n */\nimport { Component, ChangeDetectorRef, EventEmitter, Input, Output, inject } from '@angular/core';\nimport { NormalizeUUID } from '@memberjunction/global';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { WordCloudItem } from '@memberjunction/ng-word-cloud';\nimport { TagRow, TagBySource } from '../shared/classify.types';\nimport { formatWeight, tagFontSize, formatShortDate, deriveDisplayName } from '../shared/classify.format';\n\n/** One row in the per-tag drill-down (content items carrying a given tag). */\ninterface TagDrillDownItem {\n ID: string;\n Name: string;\n SourceName: string;\n Weight: number;\n UpdatedAt: string;\n FeedIndex: number;\n}\n\n@Component({\n standalone: false,\n selector: 'classify-tags-tab',\n templateUrl: './tags-tab.component.html',\n styleUrls: ['./tags-tab.component.css']\n})\nexport class ClassifyTagsTabComponent extends BaseAngularComponent {\n private cdr = inject(ChangeDetectorRef);\n\n /** Shared raw `MJ: Content Item Tags` rows, supplied by the host orchestrator. */\n private _contentTags: Record<string, unknown>[] = [];\n @Input()\n set ContentTags(value: Record<string, unknown>[]) {\n this._contentTags = value ?? [];\n this.rebuild();\n }\n get ContentTags(): Record<string, unknown>[] {\n return this._contentTags;\n }\n\n /** Shared raw `MJ: Content Items` rows — used for source mapping and drill-down. */\n private _contentItems: Record<string, unknown>[] = [];\n @Input()\n set ContentItems(value: Record<string, unknown>[]) {\n this._contentItems = value ?? [];\n this.rebuild();\n }\n get ContentItems(): Record<string, unknown>[] {\n return this._contentItems;\n }\n\n /** Shown while a manual Refresh() rebuilds the tag view models. */\n public IsLoading = false;\n\n public TagRows: TagRow[] = [];\n public FilteredTagRows: TagRow[] = [];\n public TagCloudWordItems: WordCloudItem[] = [];\n public TagsBySource: TagBySource[] = [];\n public TagSearchQuery = '';\n public SelectedDrillDownTag: string | null = null;\n public TagDrillDownItems: TagDrillDownItem[] = [];\n\n /** Subtitle reflects the live tag count, mirroring the former host subtitle. */\n public get Subtitle(): string {\n return `${this.TagRows.length} unique tags across all content sources`;\n }\n\n // Template-facing formatters (shared pure helpers exposed for the view).\n public readonly TagFontSize = tagFontSize;\n public readonly FormatWeight = formatWeight;\n\n /** Bubble a request to open a content item's detail slide-in (host-owned). */\n @Output() OpenItemDetailRequested = new EventEmitter<string>();\n\n public onOpenItemDetail(contentItemID: string): void {\n this.OpenItemDetailRequested.emit(contentItemID);\n }\n\n /** Rebuild all tag-tab view models from the current inputs. */\n private rebuild(): void {\n this.buildTagRows();\n this.buildTagCloud();\n this.buildTagsBySource();\n this.FilterTags();\n }\n\n /**\n * Rebuild the tag view models from the current host-supplied inputs. The tag\n * data is host-owned (flows in via [ContentTags]/[ContentItems]); Refresh\n * recomputes the rows/cloud/breakdown and surfaces a brief loading state.\n */\n public async Refresh(): Promise<void> {\n this.IsLoading = true;\n this.cdr.detectChanges();\n this.rebuild();\n this.IsLoading = false;\n this.cdr.detectChanges();\n }\n\n // ── External control surface (host deep-link + agent tool) ──\n\n /** Apply a search query programmatically (used by the agent tool + deep link). Returns the match count. */\n public ApplySearch(query: string): number {\n this.TagSearchQuery = query;\n this.FilterTags();\n return this.FilteredTagRows.length;\n }\n\n // ── View-model building ──\n\n private buildTagRows(): void {\n const tagCounts = this.countAllTags();\n const avgWeights = this.computeAvgWeights();\n const tagSourceMap = this.getTopSourcePerTag();\n const tagFirstSeen = this.getFirstSeenPerTag();\n const sorted = Array.from(tagCounts.entries()).sort((a, b) => b[1] - a[1]);\n const maxCount = sorted.length > 0 ? sorted[0][1] : 1;\n\n this.TagRows = sorted.map(([tag, count]) => ({\n Tag: tag,\n UsageCount: count,\n AvgWeight: avgWeights.get(tag) ?? 1.0,\n BarWidthPct: Math.round((count / maxCount) * 100),\n TopSource: tagSourceMap.get(tag) ?? 'Unknown',\n FirstSeen: tagFirstSeen.get(tag) ?? ''\n }));\n }\n\n private buildTagCloud(): void {\n const tagCounts = this.countAllTags();\n const avgWeights = this.computeAvgWeights();\n // Sort by a combined score: usage count * avg weight (so high-weight, high-count tags bubble up)\n const scored = Array.from(tagCounts.entries()).map(([tag, count]) => {\n const weight = avgWeights.get(tag) ?? 1.0;\n return { tag, count, weight, score: count * weight };\n }).sort((a, b) => b.score - a.score).slice(0, 20);\n const maxScore = scored.length > 0 ? scored[0].score : 1;\n\n // Build WordCloudItem[] for the mj-word-cloud component\n this.TagCloudWordItems = scored.map(s => ({\n Text: s.tag,\n Weight: maxScore > 0 ? s.score / maxScore : 0,\n Metadata: { Count: s.count, AvgWeight: s.weight }\n }));\n }\n\n private buildTagsBySource(): void {\n const sourceTagCounts = new Map<string, number>();\n const itemSourceMap = new Map<string, string>();\n for (const item of this._contentItems) {\n itemSourceMap.set(item['ID'] as string, (item['ContentSource'] as string) ?? 'Unknown');\n }\n for (const tag of this._contentTags) {\n const source = itemSourceMap.get(tag['ItemID'] as string) ?? 'Unknown';\n sourceTagCounts.set(source, (sourceTagCounts.get(source) ?? 0) + 1);\n }\n this.TagsBySource = Array.from(sourceTagCounts.entries())\n .sort((a, b) => b[1] - a[1])\n .map(([name, count]) => ({ SourceName: name, Count: count }));\n }\n\n public FilterTags(): void {\n const q = this.TagSearchQuery.toLowerCase().trim();\n this.FilteredTagRows = q\n ? this.TagRows.filter(r => r.Tag.toLowerCase().includes(q))\n : this.TagRows;\n this.cdr.detectChanges();\n }\n\n /** Drill down into content items matching a specific tag. */\n public DrillDownTag(tagName: string): void {\n if (this.SelectedDrillDownTag === tagName) {\n this.CloseDrillDownTag();\n return;\n }\n this.SelectedDrillDownTag = tagName;\n\n // Find all content items that have this tag\n const matchingItemIDs = new Map<string, number>(); // itemID → weight\n for (const tag of this._contentTags) {\n if ((tag['Tag'] as string) === tagName) {\n matchingItemIDs.set(\n NormalizeUUID(tag['ItemID'] as string),\n Number(tag['Weight'] ?? 1)\n );\n }\n }\n\n this.TagDrillDownItems = [];\n for (let i = 0; i < this._contentItems.length; i++) {\n const item = this._contentItems[i];\n const normalizedID = NormalizeUUID(item['ID'] as string);\n const weight = matchingItemIDs.get(normalizedID);\n if (weight !== undefined) {\n this.TagDrillDownItems.push({\n ID: item['ID'] as string,\n Name: deriveDisplayName({ Name: item['Name'] as string | null, Description: item['Description'] as string | null }),\n SourceName: (item['ContentSource'] as string) ?? 'Unknown',\n Weight: weight,\n UpdatedAt: formatShortDate((item['__mj_UpdatedAt'] as string) ?? ''),\n FeedIndex: i,\n });\n }\n }\n\n // Sort by weight descending\n this.TagDrillDownItems.sort((a, b) => b.Weight - a.Weight);\n this.cdr.detectChanges();\n }\n\n public CloseDrillDownTag(): void {\n this.SelectedDrillDownTag = null;\n this.TagDrillDownItems = [];\n this.cdr.detectChanges();\n }\n\n // ── Aggregation utilities (read only the tag + item inputs) ──\n\n private countAllTags(): Map<string, number> {\n const counts = new Map<string, number>();\n for (const tag of this._contentTags) {\n const t = tag['Tag'] as string;\n if (t) counts.set(t, (counts.get(t) ?? 0) + 1);\n }\n return counts;\n }\n\n /** Compute average weight per tag across all occurrences. */\n private computeAvgWeights(): Map<string, number> {\n const sums = new Map<string, number>();\n const counts = new Map<string, number>();\n for (const tag of this._contentTags) {\n const t = tag['Tag'] as string;\n const w = Number(tag['Weight'] ?? 0.5);\n if (t) {\n sums.set(t, (sums.get(t) ?? 0) + w);\n counts.set(t, (counts.get(t) ?? 0) + 1);\n }\n }\n const avgs = new Map<string, number>();\n for (const [t, sum] of sums) {\n avgs.set(t, Math.round((sum / (counts.get(t) ?? 1)) * 100) / 100);\n }\n return avgs;\n }\n\n private getTopSourcePerTag(): Map<string, string> {\n const tagSourceCounts = new Map<string, Map<string, number>>();\n const itemSourceMap = new Map<string, string>();\n for (const item of this._contentItems) {\n itemSourceMap.set(item['ID'] as string, (item['ContentSource'] as string) ?? 'Unknown');\n }\n for (const tag of this._contentTags) {\n const t = tag['Tag'] as string;\n const source = itemSourceMap.get(tag['ItemID'] as string) ?? 'Unknown';\n if (!tagSourceCounts.has(t)) tagSourceCounts.set(t, new Map());\n const inner = tagSourceCounts.get(t)!;\n inner.set(source, (inner.get(source) ?? 0) + 1);\n }\n const result = new Map<string, string>();\n for (const [tag, sourceCounts] of tagSourceCounts) {\n let maxSource = 'Unknown';\n let maxCount = 0;\n for (const [source, count] of sourceCounts) {\n if (count > maxCount) { maxSource = source; maxCount = count; }\n }\n result.set(tag, maxSource);\n }\n return result;\n }\n\n private getFirstSeenPerTag(): Map<string, string> {\n const result = new Map<string, string>();\n for (const tag of this._contentTags) {\n const t = tag['Tag'] as string;\n if (t && !result.has(t)) {\n const date = tag['__mj_CreatedAt'] as string;\n result.set(t, date ? formatShortDate(date) : '');\n }\n }\n return result;\n }\n}\n","<mj-page-header-interior\n Title=\"Tag Library\"\n [Subtitle]=\"Subtitle\">\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 <input type=\"text\" class=\"at-search-input\" placeholder=\"Search tags...\"\n [(ngModel)]=\"TagSearchQuery\" (input)=\"FilterTags()\">\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 tags…\"></mj-loading>\n </div>\n }\n <div class=\"at-page-body\">\n <div class=\"at-tag-lib-layout\">\n <div class=\"at-tag-lib-main\">\n <div class=\"at-card\">\n <div class=\"at-card-body\" style=\"max-height: 500px; overflow-y: auto;\">\n <table class=\"at-tag-table\">\n <thead>\n <tr>\n <th>Tag</th>\n <th>Count</th>\n <th>Avg Weight</th>\n <th>Distribution</th>\n <th>Top Source</th>\n <th>First Seen</th>\n </tr>\n </thead>\n <tbody>\n @for (row of FilteredTagRows; track row.Tag) {\n <tr class=\"at-tag-row-clickable\" (click)=\"DrillDownTag(row.Tag)\"\n [class.at-tag-row-selected]=\"SelectedDrillDownTag === row.Tag\">\n <td class=\"at-tag-name-cell\">{{ row.Tag }}</td>\n <td>{{ row.UsageCount }}</td>\n <td>\n <div class=\"at-weight-indicator\">\n <div class=\"at-weight-bar\">\n <div class=\"at-weight-bar-fill\" [style.width.%]=\"row.AvgWeight * 100\"\n [class.at-weight-high]=\"row.AvgWeight >= 0.7\"\n [class.at-weight-medium]=\"row.AvgWeight >= 0.4 && row.AvgWeight < 0.7\"\n [class.at-weight-low]=\"row.AvgWeight < 0.4\"></div>\n </div>\n <span class=\"at-weight-value\">{{ row.AvgWeight.toFixed(2) }}</span>\n </div>\n </td>\n <td>\n <div class=\"at-tag-bar\">\n <div class=\"at-tag-bar-fill\" [style.width.%]=\"row.BarWidthPct\"></div>\n </div>\n </td>\n <td>{{ row.TopSource }}</td>\n <td>{{ row.FirstSeen }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </div>\n\n <!-- Tag drill-down: content items matching selected tag -->\n @if (SelectedDrillDownTag) {\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-tag\"></i>\n Content items tagged \"{{ SelectedDrillDownTag }}\"\n ({{ TagDrillDownItems.length }})\n </span>\n <button class=\"at-slide-close\" (click)=\"CloseDrillDownTag()\" style=\"background:none;border:none;cursor:pointer;color:var(--mj-text-muted)\" aria-label=\"Close\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n <div class=\"at-card-body\" style=\"max-height: 300px; overflow-y: auto;\">\n @if (TagDrillDownItems.length === 0) {\n <div class=\"at-empty-state\"><p>No content items found for this tag.</p></div>\n } @else {\n <table class=\"at-tag-table\">\n <thead>\n <tr>\n <th>Name</th>\n <th>Source</th>\n <th>Weight</th>\n <th>Updated</th>\n </tr>\n </thead>\n <tbody>\n @for (di of TagDrillDownItems; track di.ID) {\n <tr class=\"at-tag-row-clickable\" (click)=\"onOpenItemDetail(di.ID)\">\n <td>{{ di.Name }}</td>\n <td>{{ di.SourceName }}</td>\n <td>{{ FormatWeight(di.Weight) }}</td>\n <td>{{ di.UpdatedAt }}</td>\n </tr>\n }\n </tbody>\n </table>\n }\n </div>\n </div>\n }\n </div>\n <div class=\"at-tag-lib-sidebar\">\n <div class=\"at-card at-tag-cloud-card\">\n <div class=\"at-card-title\" style=\"margin-bottom: 12px;\"><i class=\"fa-solid fa-cloud\"></i> Tag Cloud</div>\n @if (TagCloudWordItems.length > 0) {\n <mj-word-cloud\n [Items]=\"TagCloudWordItems\"\n [MaxFontSize]=\"40\"\n [MinFontSize]=\"12\"\n [MaxItems]=\"20\"\n Layout=\"spiral\"\n ColorMode=\"weight-gradient\"\n [Interactive]=\"true\"\n [Animate]=\"true\">\n </mj-word-cloud>\n } @else {\n <div class=\"at-tag-cloud-empty\">No tags yet</div>\n }\n </div>\n <div class=\"at-card\" style=\"padding: 16px; margin-top: 12px;\">\n <div class=\"at-card-title\" style=\"margin-bottom: 10px;\"><i class=\"fa-solid fa-chart-pie\"></i> By Source</div>\n <div class=\"at-tags-by-source\">\n @for (s of TagsBySource; track s.SourceName) {\n <div class=\"at-tag-source-row\">\n <span>{{ s.SourceName }}</span>\n <strong>{{ s.Count }}</strong>\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n</mj-page-body-interior>\n"]}
@@ -13,6 +13,9 @@ import { ContentTypeCard } from '../shared/classify.types';
13
13
  import { formatNumber } from '../shared/classify.format';
14
14
  import * as i0 from "@angular/core";
15
15
  export declare class ClassifyTypesTabComponent extends BaseAngularComponent {
16
+ private cdr;
17
+ /** Shown while a manual Refresh() recomputes the content-type cards. */
18
+ IsLoading: boolean;
16
19
  /** Raw `MJ: Content Types` rows — the primary source for the cards. */
17
20
  private _contentTypes;
18
21
  set ContentTypes(value: Record<string, unknown>[]);
@@ -35,6 +38,12 @@ export declare class ClassifyTypesTabComponent extends BaseAngularComponent {
35
38
  /** Bubble Add/Edit intents to the host, which owns the slide-in CRUD form. */
36
39
  AddTypeRequested: EventEmitter<void>;
37
40
  EditTypeRequested: EventEmitter<ContentTypeCard>;
41
+ /**
42
+ * Recompute the content-type cards from the current host-supplied inputs. The
43
+ * data is host-owned (flows in via @Input); Refresh rebuilds the view models
44
+ * and surfaces a brief loading state for user feedback.
45
+ */
46
+ Refresh(): Promise<void>;
38
47
  onAddType(): void;
39
48
  onEditType(card: ContentTypeCard): void;
40
49
  /** Rebuild the card view models from the current inputs. */
@@ -1 +1 @@
1
- {"version":3,"file":"types-tab.component.d.ts","sourceRoot":"","sources":["../../../../../src/AI/components/autotagging/tabs/types-tab.component.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAa,YAAY,EAAiB,MAAM,eAAe,CAAC;AACvE,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;;AAEzD,qBAMa,yBAA0B,SAAQ,oBAAoB;IAC/D,uEAAuE;IACvE,OAAO,CAAC,aAAa,CAAiC;IACtD,IACI,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAGhD;IACD,IAAI,YAAY,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAE5C;IAED,+EAA+E;IAC/E,OAAO,CAAC,QAAQ,CAAiC;IACjD,IACI,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAG3C;IACD,IAAI,OAAO,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAEvC;IAED,2EAA2E;IAC3E,OAAO,CAAC,MAAM,CAAiC;IAC/C,IACI,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAGzC;IACD,IAAI,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAErC;IAED,6FAA6F;IAC7F,OAAO,CAAC,eAAe,CAAK;IAC5B,IACI,cAAc,CAAC,KAAK,EAAE,MAAM,EAG/B;IACD,IAAI,cAAc,IAAI,MAAM,CAE3B;IAEM,gBAAgB,EAAE,eAAe,EAAE,CAAM;IAEhD,uFAAuF;IACvF,SAAgB,YAAY,sBAAgB;IAE5C,8EAA8E;IACpE,gBAAgB,qBAA4B;IAC5C,iBAAiB,gCAAuC;IAE3D,SAAS,IAAI,IAAI;IAIjB,UAAU,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI;IAI9C,4DAA4D;IAC5D,OAAO,CAAC,OAAO;IA8Bf,OAAO,CAAC,yBAAyB;IASjC,OAAO,CAAC,uBAAuB;yCAtGtB,yBAAyB;2CAAzB,yBAAyB;CA8GrC"}
1
+ {"version":3,"file":"types-tab.component.d.ts","sourceRoot":"","sources":["../../../../../src/AI/components/autotagging/tabs/types-tab.component.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAgC,YAAY,EAAyB,MAAM,eAAe,CAAC;AAClG,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;;AAEzD,qBAMa,yBAA0B,SAAQ,oBAAoB;IAC/D,OAAO,CAAC,GAAG,CAA6B;IAExC,wEAAwE;IACjE,SAAS,UAAS;IAEzB,uEAAuE;IACvE,OAAO,CAAC,aAAa,CAAiC;IACtD,IACI,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAGhD;IACD,IAAI,YAAY,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAE5C;IAED,+EAA+E;IAC/E,OAAO,CAAC,QAAQ,CAAiC;IACjD,IACI,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAG3C;IACD,IAAI,OAAO,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAEvC;IAED,2EAA2E;IAC3E,OAAO,CAAC,MAAM,CAAiC;IAC/C,IACI,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAGzC;IACD,IAAI,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAErC;IAED,6FAA6F;IAC7F,OAAO,CAAC,eAAe,CAAK;IAC5B,IACI,cAAc,CAAC,KAAK,EAAE,MAAM,EAG/B;IACD,IAAI,cAAc,IAAI,MAAM,CAE3B;IAEM,gBAAgB,EAAE,eAAe,EAAE,CAAM;IAEhD,uFAAuF;IACvF,SAAgB,YAAY,sBAAgB;IAE5C,8EAA8E;IACpE,gBAAgB,qBAA4B;IAC5C,iBAAiB,gCAAuC;IAElE;;;;OAIG;IACU,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ9B,SAAS,IAAI,IAAI;IAIjB,UAAU,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI;IAI9C,4DAA4D;IAC5D,OAAO,CAAC,OAAO;IA8Bf,OAAO,CAAC,yBAAyB;IASjC,OAAO,CAAC,uBAAuB;yCAxHtB,yBAAyB;2CAAzB,yBAAyB;CAgIrC"}