@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
@@ -0,0 +1,81 @@
1
+ /**
2
+ * @fileoverview Knowledge Hub Tag Cloud (Visualize > Tag Cloud mode)
3
+ *
4
+ * Renders a weighted tag cloud via `@memberjunction/ng-word-cloud`'s
5
+ * `MJWordCloudComponent`, driven by `TagCloudEngine.Instance.GetTagCloud(...)`.
6
+ *
7
+ * Provides a scope picker (Content Source / Content Type / Tag root) plus a
8
+ * sizing control. Loads on init and whenever the scope changes. Emits a
9
+ * `TagSelected` intent up to the host so the shared record-drilldown panel can
10
+ * be populated by the host (this component never touches NavigationService).
11
+ */
12
+ import { EventEmitter, OnInit } from '@angular/core';
13
+ import { IMetadataProvider } from '@memberjunction/core';
14
+ import { BaseAngularComponent } from '@memberjunction/ng-base-types';
15
+ import { TagCloudScope } from '@memberjunction/tag-engine-base';
16
+ import { WordCloudItem, WordCloudItemEvent } from '@memberjunction/ng-word-cloud';
17
+ import * as i0 from "@angular/core";
18
+ /** A selectable scope option (content source / content type / tag root). */
19
+ interface ScopeOption {
20
+ ID: string;
21
+ Name: string;
22
+ }
23
+ /**
24
+ * Emitted when the user clicks a tag word. The host resolves this into the
25
+ * shared drilldown panel (records carrying the tag).
26
+ */
27
+ export interface TagCloudSelection {
28
+ /** The clicked tag's text. */
29
+ Tag: string;
30
+ /** Raw frequency count carried from TagCloudItem. */
31
+ Count: number;
32
+ /** The scope currently applied (so the host can scope the drilldown query). */
33
+ Scope: TagCloudScope;
34
+ }
35
+ export declare class TagCloudComponent extends BaseAngularComponent implements OnInit {
36
+ private cdr;
37
+ /** Re-declared so the host can bind `[Provider]` and we thread it through. */
38
+ Provider: IMetadataProvider | null;
39
+ /** Emitted when a tag word is clicked. */
40
+ TagSelected: EventEmitter<TagCloudSelection>;
41
+ IsLoading: boolean;
42
+ Items: WordCloudItem[];
43
+ /** Scope picker options. */
44
+ ContentSourceOptions: ScopeOption[];
45
+ ContentTypeOptions: ScopeOption[];
46
+ TagRootOptions: ScopeOption[];
47
+ /** Current scope selections (empty string = "All"). */
48
+ SelectedContentSourceID: string;
49
+ SelectedContentTypeID: string;
50
+ SelectedTagRootID: string;
51
+ /** Sizing: maximum font size driven by weight. */
52
+ MaxFontSize: number;
53
+ MinFontSize: number;
54
+ /** Color mode passed to the word cloud. */
55
+ ColorMode: 'brand' | 'categorical' | 'weight-gradient';
56
+ ngOnInit(): Promise<void>;
57
+ /** Re-load the cloud for the current scope. Called on init + scope change. */
58
+ LoadCloud(): Promise<void>;
59
+ /** Reload after any scope dropdown change. */
60
+ OnScopeChanged(): void;
61
+ /** Apply a new max font size (sizing-by-weight control). */
62
+ OnSizeChanged(value: number): void;
63
+ /** Clear all scope filters and reload. */
64
+ ClearScope(): void;
65
+ get HasActiveScope(): boolean;
66
+ get HasItems(): boolean;
67
+ /** Word-cloud click handler — emits a selection up to the host. */
68
+ OnWordClicked(event: WordCloudItemEvent): void;
69
+ /** Build the current TagCloudScope from the picker selections. */
70
+ BuildScope(): TagCloudScope;
71
+ /** Map an engine TagCloudItem to a word-cloud WordCloudItem (Count → Metadata). */
72
+ private toWordCloudItem;
73
+ /** Populate scope-picker options from the KH + Tag engines. */
74
+ private loadScopeOptions;
75
+ static ɵfac: i0.ɵɵFactoryDeclaration<TagCloudComponent, never>;
76
+ static ɵcmp: i0.ɵɵComponentDeclaration<TagCloudComponent, "app-kh-tag-cloud", never, { "Provider": { "alias": "Provider"; "required": false; }; }, { "TagSelected": "TagSelected"; }, never, never, false, never>;
77
+ }
78
+ /** Tree-shaking prevention */
79
+ export declare function LoadTagCloudComponent(): void;
80
+ export {};
81
+ //# sourceMappingURL=tag-cloud.component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tag-cloud.component.d.ts","sourceRoot":"","sources":["../../../../../src/KnowledgeHub/components/visualize/tag-cloud/tag-cloud.component.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAIH,YAAY,EAEZ,MAAM,EAET,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAEH,aAAa,EAEhB,MAAM,iCAAiC,CAAC;AAGzC,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;;AAElF,4EAA4E;AAC5E,UAAU,WAAW;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAC9B,8BAA8B;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,qDAAqD;IACrD,KAAK,EAAE,MAAM,CAAC;IACd,+EAA+E;IAC/E,KAAK,EAAE,aAAa,CAAC;CACxB;AAED,qBAMa,iBAAkB,SAAQ,oBAAqB,YAAW,MAAM;IACzE,OAAO,CAAC,GAAG,CAA6B;IAExC,8EAA8E;IAC5D,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAAQ;IAE5D,0CAA0C;IAChC,WAAW,kCAAyC;IAMvD,SAAS,UAAQ;IACjB,KAAK,EAAE,aAAa,EAAE,CAAM;IAEnC,4BAA4B;IACrB,oBAAoB,EAAE,WAAW,EAAE,CAAM;IACzC,kBAAkB,EAAE,WAAW,EAAE,CAAM;IACvC,cAAc,EAAE,WAAW,EAAE,CAAM;IAE1C,uDAAuD;IAChD,uBAAuB,SAAM;IAC7B,qBAAqB,SAAM;IAC3B,iBAAiB,SAAM;IAE9B,kDAAkD;IAC3C,WAAW,SAAM;IACjB,WAAW,SAAM;IAExB,2CAA2C;IACpC,SAAS,EAAE,OAAO,GAAG,aAAa,GAAG,iBAAiB,CAAqB;IAM5E,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAS/B,8EAA8E;IACjE,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAuBvC,8CAA8C;IACvC,cAAc,IAAI,IAAI;IAI7B,4DAA4D;IACrD,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAKzC,0CAA0C;IACnC,UAAU,IAAI,IAAI;IAOzB,IAAW,cAAc,IAAI,OAAO,CAEnC;IAED,IAAW,QAAQ,IAAI,OAAO,CAE7B;IAED,mEAAmE;IAC5D,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI;IASrD,kEAAkE;IAC3D,UAAU,IAAI,aAAa;IAkBlC,mFAAmF;IACnF,OAAO,CAAC,eAAe;IAQvB,+DAA+D;YACjD,gBAAgB;yCAxIrB,iBAAiB;2CAAjB,iBAAiB;CAiK7B;AAED,8BAA8B;AAC9B,wBAAgB,qBAAqB,IAAI,IAAI,CAE5C"}
@@ -0,0 +1,308 @@
1
+ /**
2
+ * @fileoverview Knowledge Hub Tag Cloud (Visualize > Tag Cloud mode)
3
+ *
4
+ * Renders a weighted tag cloud via `@memberjunction/ng-word-cloud`'s
5
+ * `MJWordCloudComponent`, driven by `TagCloudEngine.Instance.GetTagCloud(...)`.
6
+ *
7
+ * Provides a scope picker (Content Source / Content Type / Tag root) plus a
8
+ * sizing control. Loads on init and whenever the scope changes. Emits a
9
+ * `TagSelected` intent up to the host so the shared record-drilldown panel can
10
+ * be populated by the host (this component never touches NavigationService).
11
+ */
12
+ import { Component, Input, Output, EventEmitter, ChangeDetectorRef, inject, } from '@angular/core';
13
+ import { BaseAngularComponent } from '@memberjunction/ng-base-types';
14
+ import { TagCloudEngine, } from '@memberjunction/tag-engine-base';
15
+ import { TagEngineBase } from '@memberjunction/tag-engine-base';
16
+ import { KnowledgeHubMetadataEngine } from '@memberjunction/core-entities';
17
+ import * as i0 from "@angular/core";
18
+ import * as i1 from "@angular/forms";
19
+ import * as i2 from "@memberjunction/ng-shared-generic";
20
+ import * as i3 from "@memberjunction/ng-ui-components";
21
+ import * as i4 from "@memberjunction/ng-word-cloud";
22
+ const _forTrack0 = ($index, $item) => $item.ID;
23
+ function TagCloudComponent_For_9_Template(rf, ctx) { if (rf & 1) {
24
+ i0.ɵɵelementStart(0, "option", 5);
25
+ i0.ɵɵtext(1);
26
+ i0.ɵɵelementEnd();
27
+ } if (rf & 2) {
28
+ const opt_r1 = ctx.$implicit;
29
+ i0.ɵɵproperty("value", opt_r1.ID);
30
+ i0.ɵɵadvance();
31
+ i0.ɵɵtextInterpolate(opt_r1.Name);
32
+ } }
33
+ function TagCloudComponent_For_17_Template(rf, ctx) { if (rf & 1) {
34
+ i0.ɵɵelementStart(0, "option", 5);
35
+ i0.ɵɵtext(1);
36
+ i0.ɵɵelementEnd();
37
+ } if (rf & 2) {
38
+ const opt_r2 = ctx.$implicit;
39
+ i0.ɵɵproperty("value", opt_r2.ID);
40
+ i0.ɵɵadvance();
41
+ i0.ɵɵtextInterpolate(opt_r2.Name);
42
+ } }
43
+ function TagCloudComponent_For_25_Template(rf, ctx) { if (rf & 1) {
44
+ i0.ɵɵelementStart(0, "option", 5);
45
+ i0.ɵɵtext(1);
46
+ i0.ɵɵelementEnd();
47
+ } if (rf & 2) {
48
+ const opt_r3 = ctx.$implicit;
49
+ i0.ɵɵproperty("value", opt_r3.ID);
50
+ i0.ɵɵadvance();
51
+ i0.ɵɵtextInterpolate(opt_r3.Name);
52
+ } }
53
+ function TagCloudComponent_Conditional_30_Template(rf, ctx) { if (rf & 1) {
54
+ const _r4 = i0.ɵɵgetCurrentView();
55
+ i0.ɵɵelementStart(0, "button", 13);
56
+ i0.ɵɵlistener("click", function TagCloudComponent_Conditional_30_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r4); const ctx_r4 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r4.ClearScope()); });
57
+ i0.ɵɵelement(1, "i", 14);
58
+ i0.ɵɵtext(2, " Clear ");
59
+ i0.ɵɵelementEnd();
60
+ } }
61
+ function TagCloudComponent_Conditional_32_Template(rf, ctx) { if (rf & 1) {
62
+ i0.ɵɵelement(0, "mj-loading", 10);
63
+ } }
64
+ function TagCloudComponent_Conditional_33_Conditional_4_Template(rf, ctx) { if (rf & 1) {
65
+ const _r6 = i0.ɵɵgetCurrentView();
66
+ i0.ɵɵelementStart(0, "button", 17);
67
+ i0.ɵɵlistener("click", function TagCloudComponent_Conditional_33_Conditional_4_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r6); const ctx_r4 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r4.ClearScope()); });
68
+ i0.ɵɵtext(1, "Clear filters");
69
+ i0.ɵɵelementEnd();
70
+ } }
71
+ function TagCloudComponent_Conditional_33_Template(rf, ctx) { if (rf & 1) {
72
+ i0.ɵɵelementStart(0, "div", 11);
73
+ i0.ɵɵelement(1, "i", 15);
74
+ i0.ɵɵelementStart(2, "p");
75
+ i0.ɵɵtext(3, "No tags found for the current scope");
76
+ i0.ɵɵelementEnd();
77
+ i0.ɵɵconditionalCreate(4, TagCloudComponent_Conditional_33_Conditional_4_Template, 2, 0, "button", 16);
78
+ i0.ɵɵelementEnd();
79
+ } if (rf & 2) {
80
+ const ctx_r4 = i0.ɵɵnextContext();
81
+ i0.ɵɵadvance(4);
82
+ i0.ɵɵconditional(ctx_r4.HasActiveScope ? 4 : -1);
83
+ } }
84
+ function TagCloudComponent_Conditional_34_Template(rf, ctx) { if (rf & 1) {
85
+ const _r7 = i0.ɵɵgetCurrentView();
86
+ i0.ɵɵelementStart(0, "mj-word-cloud", 18);
87
+ i0.ɵɵlistener("ItemClick", function TagCloudComponent_Conditional_34_Template_mj_word_cloud_ItemClick_0_listener($event) { i0.ɵɵrestoreView(_r7); const ctx_r4 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r4.OnWordClicked($event)); });
88
+ i0.ɵɵelementEnd();
89
+ } if (rf & 2) {
90
+ const ctx_r4 = i0.ɵɵnextContext();
91
+ i0.ɵɵproperty("Items", ctx_r4.Items)("MinFontSize", ctx_r4.MinFontSize)("MaxFontSize", ctx_r4.MaxFontSize)("ColorMode", ctx_r4.ColorMode)("Interactive", true);
92
+ } }
93
+ export class TagCloudComponent extends BaseAngularComponent {
94
+ cdr = inject(ChangeDetectorRef);
95
+ /** Re-declared so the host can bind `[Provider]` and we thread it through. */
96
+ Provider = null;
97
+ /** Emitted when a tag word is clicked. */
98
+ TagSelected = new EventEmitter();
99
+ // ================================================================
100
+ // State
101
+ // ================================================================
102
+ IsLoading = true;
103
+ Items = [];
104
+ /** Scope picker options. */
105
+ ContentSourceOptions = [];
106
+ ContentTypeOptions = [];
107
+ TagRootOptions = [];
108
+ /** Current scope selections (empty string = "All"). */
109
+ SelectedContentSourceID = '';
110
+ SelectedContentTypeID = '';
111
+ SelectedTagRootID = '';
112
+ /** Sizing: maximum font size driven by weight. */
113
+ MaxFontSize = 56;
114
+ MinFontSize = 14;
115
+ /** Color mode passed to the word cloud. */
116
+ ColorMode = 'weight-gradient';
117
+ // ================================================================
118
+ // Lifecycle
119
+ // ================================================================
120
+ async ngOnInit() {
121
+ await this.loadScopeOptions();
122
+ await this.LoadCloud();
123
+ }
124
+ // ================================================================
125
+ // Public Methods
126
+ // ================================================================
127
+ /** Re-load the cloud for the current scope. Called on init + scope change. */
128
+ async LoadCloud() {
129
+ this.IsLoading = true;
130
+ this.cdr.detectChanges();
131
+ try {
132
+ const scope = this.BuildScope();
133
+ const provider = this.ProviderToUse;
134
+ const items = await TagCloudEngine.Instance.GetTagCloud(scope, { Limit: 150, MinWeight: 0 }, provider.CurrentUser, provider);
135
+ this.Items = items.map(item => this.toWordCloudItem(item));
136
+ }
137
+ catch (error) {
138
+ console.error('[TagCloud] Error loading tag cloud:', error);
139
+ this.Items = [];
140
+ }
141
+ finally {
142
+ this.IsLoading = false;
143
+ this.cdr.detectChanges();
144
+ }
145
+ }
146
+ /** Reload after any scope dropdown change. */
147
+ OnScopeChanged() {
148
+ void this.LoadCloud();
149
+ }
150
+ /** Apply a new max font size (sizing-by-weight control). */
151
+ OnSizeChanged(value) {
152
+ this.MaxFontSize = value;
153
+ this.cdr.detectChanges();
154
+ }
155
+ /** Clear all scope filters and reload. */
156
+ ClearScope() {
157
+ this.SelectedContentSourceID = '';
158
+ this.SelectedContentTypeID = '';
159
+ this.SelectedTagRootID = '';
160
+ void this.LoadCloud();
161
+ }
162
+ get HasActiveScope() {
163
+ return !!(this.SelectedContentSourceID || this.SelectedContentTypeID || this.SelectedTagRootID);
164
+ }
165
+ get HasItems() {
166
+ return this.Items.length > 0;
167
+ }
168
+ /** Word-cloud click handler — emits a selection up to the host. */
169
+ OnWordClicked(event) {
170
+ const count = Number(event.Item.Metadata?.['Count'] ?? 0);
171
+ this.TagSelected.emit({
172
+ Tag: event.Item.Text,
173
+ Count: count,
174
+ Scope: this.BuildScope(),
175
+ });
176
+ }
177
+ /** Build the current TagCloudScope from the picker selections. */
178
+ BuildScope() {
179
+ const scope = {};
180
+ if (this.SelectedContentSourceID) {
181
+ scope.ContentSourceIDs = [this.SelectedContentSourceID];
182
+ }
183
+ if (this.SelectedContentTypeID) {
184
+ scope.ContentTypeIDs = [this.SelectedContentTypeID];
185
+ }
186
+ if (this.SelectedTagRootID) {
187
+ scope.TagRootIDs = [this.SelectedTagRootID];
188
+ }
189
+ return scope;
190
+ }
191
+ // ================================================================
192
+ // Private Methods
193
+ // ================================================================
194
+ /** Map an engine TagCloudItem to a word-cloud WordCloudItem (Count → Metadata). */
195
+ toWordCloudItem(item) {
196
+ return {
197
+ Text: item.Text,
198
+ Weight: item.Weight,
199
+ Metadata: { Count: item.Count },
200
+ };
201
+ }
202
+ /** Populate scope-picker options from the KH + Tag engines. */
203
+ async loadScopeOptions() {
204
+ try {
205
+ const provider = this.ProviderToUse;
206
+ const khEngine = KnowledgeHubMetadataEngine.Instance;
207
+ await khEngine.Config(false, provider.CurrentUser, provider);
208
+ this.ContentSourceOptions = khEngine.ContentSources
209
+ .map(s => ({ ID: s.ID, Name: s.Name ?? 'Untitled' }))
210
+ .sort((a, b) => a.Name.localeCompare(b.Name));
211
+ this.ContentTypeOptions = khEngine.ContentTypes
212
+ .map(t => ({ ID: t.ID, Name: t.Name ?? 'Untitled' }))
213
+ .sort((a, b) => a.Name.localeCompare(b.Name));
214
+ const tagEngine = TagEngineBase.Instance;
215
+ await tagEngine.Config(false, provider.CurrentUser, provider);
216
+ this.TagRootOptions = tagEngine.Tags
217
+ .filter(t => !t.ParentID)
218
+ .map(t => ({ ID: t.ID, Name: t.DisplayName || t.Name }))
219
+ .sort((a, b) => a.Name.localeCompare(b.Name));
220
+ }
221
+ catch (error) {
222
+ console.warn('[TagCloud] Error loading scope options:', error);
223
+ }
224
+ this.cdr.detectChanges();
225
+ }
226
+ static ɵfac = /*@__PURE__*/ (() => { let ɵTagCloudComponent_BaseFactory; return function TagCloudComponent_Factory(__ngFactoryType__) { return (ɵTagCloudComponent_BaseFactory || (ɵTagCloudComponent_BaseFactory = i0.ɵɵgetInheritedFactory(TagCloudComponent)))(__ngFactoryType__ || TagCloudComponent); }; })();
227
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: TagCloudComponent, selectors: [["app-kh-tag-cloud"]], inputs: { Provider: "Provider" }, outputs: { TagSelected: "TagSelected" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 35, vars: 7, consts: [[1, "tag-cloud-container"], [1, "tag-cloud-toolbar"], [1, "scope-field"], [1, "mj-input", 3, "ngModelChange", "ngModel"], ["value", ""], [3, "value"], [1, "scope-field", "size-field"], ["type", "range", "min", "28", "max", "96", "step", "4", 3, "input", "value"], ["mjButton", "", "variant", "flat", "size", "sm"], [1, "tag-cloud-area"], ["text", "Building tag cloud..."], [1, "tag-cloud-empty"], [3, "Items", "MinFontSize", "MaxFontSize", "ColorMode", "Interactive"], ["mjButton", "", "variant", "flat", "size", "sm", 3, "click"], [1, "fa-solid", "fa-filter-circle-xmark"], [1, "fa-solid", "fa-tags"], ["mjButton", "", "variant", "outline", "size", "sm"], ["mjButton", "", "variant", "outline", "size", "sm", 3, "click"], [3, "ItemClick", "Items", "MinFontSize", "MaxFontSize", "ColorMode", "Interactive"]], template: function TagCloudComponent_Template(rf, ctx) { if (rf & 1) {
228
+ i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "div", 2)(3, "label");
229
+ i0.ɵɵtext(4, "Content Source");
230
+ i0.ɵɵelementEnd();
231
+ i0.ɵɵelementStart(5, "select", 3);
232
+ i0.ɵɵtwoWayListener("ngModelChange", function TagCloudComponent_Template_select_ngModelChange_5_listener($event) { i0.ɵɵtwoWayBindingSet(ctx.SelectedContentSourceID, $event) || (ctx.SelectedContentSourceID = $event); return $event; });
233
+ i0.ɵɵlistener("ngModelChange", function TagCloudComponent_Template_select_ngModelChange_5_listener() { return ctx.OnScopeChanged(); });
234
+ i0.ɵɵelementStart(6, "option", 4);
235
+ i0.ɵɵtext(7, "All Sources");
236
+ i0.ɵɵelementEnd();
237
+ i0.ɵɵrepeaterCreate(8, TagCloudComponent_For_9_Template, 2, 2, "option", 5, _forTrack0);
238
+ i0.ɵɵelementEnd()();
239
+ i0.ɵɵelementStart(10, "div", 2)(11, "label");
240
+ i0.ɵɵtext(12, "Content Type");
241
+ i0.ɵɵelementEnd();
242
+ i0.ɵɵelementStart(13, "select", 3);
243
+ i0.ɵɵtwoWayListener("ngModelChange", function TagCloudComponent_Template_select_ngModelChange_13_listener($event) { i0.ɵɵtwoWayBindingSet(ctx.SelectedContentTypeID, $event) || (ctx.SelectedContentTypeID = $event); return $event; });
244
+ i0.ɵɵlistener("ngModelChange", function TagCloudComponent_Template_select_ngModelChange_13_listener() { return ctx.OnScopeChanged(); });
245
+ i0.ɵɵelementStart(14, "option", 4);
246
+ i0.ɵɵtext(15, "All Types");
247
+ i0.ɵɵelementEnd();
248
+ i0.ɵɵrepeaterCreate(16, TagCloudComponent_For_17_Template, 2, 2, "option", 5, _forTrack0);
249
+ i0.ɵɵelementEnd()();
250
+ i0.ɵɵelementStart(18, "div", 2)(19, "label");
251
+ i0.ɵɵtext(20, "Tag Root");
252
+ i0.ɵɵelementEnd();
253
+ i0.ɵɵelementStart(21, "select", 3);
254
+ i0.ɵɵtwoWayListener("ngModelChange", function TagCloudComponent_Template_select_ngModelChange_21_listener($event) { i0.ɵɵtwoWayBindingSet(ctx.SelectedTagRootID, $event) || (ctx.SelectedTagRootID = $event); return $event; });
255
+ i0.ɵɵlistener("ngModelChange", function TagCloudComponent_Template_select_ngModelChange_21_listener() { return ctx.OnScopeChanged(); });
256
+ i0.ɵɵelementStart(22, "option", 4);
257
+ i0.ɵɵtext(23, "All Tags");
258
+ i0.ɵɵelementEnd();
259
+ i0.ɵɵrepeaterCreate(24, TagCloudComponent_For_25_Template, 2, 2, "option", 5, _forTrack0);
260
+ i0.ɵɵelementEnd()();
261
+ i0.ɵɵelementStart(26, "div", 6)(27, "label");
262
+ i0.ɵɵtext(28);
263
+ i0.ɵɵelementEnd();
264
+ i0.ɵɵelementStart(29, "input", 7);
265
+ i0.ɵɵlistener("input", function TagCloudComponent_Template_input_input_29_listener($event) { return ctx.OnSizeChanged($event.target.valueAsNumber); });
266
+ i0.ɵɵelementEnd()();
267
+ i0.ɵɵconditionalCreate(30, TagCloudComponent_Conditional_30_Template, 3, 0, "button", 8);
268
+ i0.ɵɵelementEnd();
269
+ i0.ɵɵelementStart(31, "div", 9);
270
+ i0.ɵɵconditionalCreate(32, TagCloudComponent_Conditional_32_Template, 1, 0, "mj-loading", 10)(33, TagCloudComponent_Conditional_33_Template, 5, 1, "div", 11)(34, TagCloudComponent_Conditional_34_Template, 1, 5, "mj-word-cloud", 12);
271
+ i0.ɵɵelementEnd()();
272
+ } if (rf & 2) {
273
+ i0.ɵɵadvance(5);
274
+ i0.ɵɵtwoWayProperty("ngModel", ctx.SelectedContentSourceID);
275
+ i0.ɵɵadvance(3);
276
+ i0.ɵɵrepeater(ctx.ContentSourceOptions);
277
+ i0.ɵɵadvance(5);
278
+ i0.ɵɵtwoWayProperty("ngModel", ctx.SelectedContentTypeID);
279
+ i0.ɵɵadvance(3);
280
+ i0.ɵɵrepeater(ctx.ContentTypeOptions);
281
+ i0.ɵɵadvance(5);
282
+ i0.ɵɵtwoWayProperty("ngModel", ctx.SelectedTagRootID);
283
+ i0.ɵɵadvance(3);
284
+ i0.ɵɵrepeater(ctx.TagRootOptions);
285
+ i0.ɵɵadvance(4);
286
+ i0.ɵɵtextInterpolate1("Max Size: ", ctx.MaxFontSize, "px");
287
+ i0.ɵɵadvance();
288
+ i0.ɵɵproperty("value", ctx.MaxFontSize);
289
+ i0.ɵɵadvance();
290
+ i0.ɵɵconditional(ctx.HasActiveScope ? 30 : -1);
291
+ i0.ɵɵadvance(2);
292
+ i0.ɵɵconditional(ctx.IsLoading ? 32 : !ctx.HasItems ? 33 : 34);
293
+ } }, dependencies: [i1.NgSelectOption, i1.ɵNgSelectMultipleOption, i1.SelectControlValueAccessor, i1.NgControlStatus, i1.NgModel, i2.LoadingComponent, i3.MJButtonDirective, i4.MJWordCloudComponent], styles: ["[_nghost-%COMP%] {\n display: block;\n height: 100%;\n}\n\n.tag-cloud-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n min-height: 0;\n}\n\n.tag-cloud-toolbar[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-end;\n flex-wrap: wrap;\n gap: 16px;\n padding: 12px 16px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n}\n\n.scope-field[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 4px;\n min-width: 160px;\n}\n\n.scope-field[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.scope-field[_ngcontent-%COMP%] select[_ngcontent-%COMP%] {\n min-width: 160px;\n}\n\n.size-field[_ngcontent-%COMP%] {\n min-width: 180px;\n}\n\n.size-field[_ngcontent-%COMP%] input[type=\"range\"][_ngcontent-%COMP%] {\n width: 100%;\n accent-color: var(--mj-brand-primary);\n}\n\n.tag-cloud-area[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 24px;\n overflow: hidden;\n}\n\n.tag-cloud-area[_ngcontent-%COMP%] mj-word-cloud[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n}\n\n.tag-cloud-empty[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 12px;\n color: var(--mj-text-muted);\n text-align: center;\n}\n\n.tag-cloud-empty[_ngcontent-%COMP%] > i[_ngcontent-%COMP%] {\n font-size: 40px;\n opacity: 0.5;\n}"] });
294
+ }
295
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(TagCloudComponent, [{
296
+ type: Component,
297
+ args: [{ standalone: false, selector: 'app-kh-tag-cloud', template: "<div class=\"tag-cloud-container\">\n <!-- Scope picker / sizing toolbar -->\n <div class=\"tag-cloud-toolbar\">\n <div class=\"scope-field\">\n <label>Content Source</label>\n <select class=\"mj-input\" [(ngModel)]=\"SelectedContentSourceID\" (ngModelChange)=\"OnScopeChanged()\">\n <option value=\"\">All Sources</option>\n @for (opt of ContentSourceOptions; track opt.ID) {\n <option [value]=\"opt.ID\">{{ opt.Name }}</option>\n }\n </select>\n </div>\n\n <div class=\"scope-field\">\n <label>Content Type</label>\n <select class=\"mj-input\" [(ngModel)]=\"SelectedContentTypeID\" (ngModelChange)=\"OnScopeChanged()\">\n <option value=\"\">All Types</option>\n @for (opt of ContentTypeOptions; track opt.ID) {\n <option [value]=\"opt.ID\">{{ opt.Name }}</option>\n }\n </select>\n </div>\n\n <div class=\"scope-field\">\n <label>Tag Root</label>\n <select class=\"mj-input\" [(ngModel)]=\"SelectedTagRootID\" (ngModelChange)=\"OnScopeChanged()\">\n <option value=\"\">All Tags</option>\n @for (opt of TagRootOptions; track opt.ID) {\n <option [value]=\"opt.ID\">{{ opt.Name }}</option>\n }\n </select>\n </div>\n\n <div class=\"scope-field size-field\">\n <label>Max Size: {{ MaxFontSize }}px</label>\n <input type=\"range\" min=\"28\" max=\"96\" step=\"4\"\n [value]=\"MaxFontSize\"\n (input)=\"OnSizeChanged($any($event.target).valueAsNumber)\" />\n </div>\n\n @if (HasActiveScope) {\n <button mjButton variant=\"flat\" size=\"sm\" (click)=\"ClearScope()\">\n <i class=\"fa-solid fa-filter-circle-xmark\"></i> Clear\n </button>\n }\n </div>\n\n <!-- Cloud area -->\n <div class=\"tag-cloud-area\">\n @if (IsLoading) {\n <mj-loading text=\"Building tag cloud...\"></mj-loading>\n } @else if (!HasItems) {\n <div class=\"tag-cloud-empty\">\n <i class=\"fa-solid fa-tags\"></i>\n <p>No tags found for the current scope</p>\n @if (HasActiveScope) {\n <button mjButton variant=\"outline\" size=\"sm\" (click)=\"ClearScope()\">Clear filters</button>\n }\n </div>\n } @else {\n <mj-word-cloud\n [Items]=\"Items\"\n [MinFontSize]=\"MinFontSize\"\n [MaxFontSize]=\"MaxFontSize\"\n [ColorMode]=\"ColorMode\"\n [Interactive]=\"true\"\n (ItemClick)=\"OnWordClicked($event)\">\n </mj-word-cloud>\n }\n </div>\n</div>\n", styles: [":host {\n display: block;\n height: 100%;\n}\n\n.tag-cloud-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n min-height: 0;\n}\n\n.tag-cloud-toolbar {\n display: flex;\n align-items: flex-end;\n flex-wrap: wrap;\n gap: 16px;\n padding: 12px 16px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n}\n\n.scope-field {\n display: flex;\n flex-direction: column;\n gap: 4px;\n min-width: 160px;\n}\n\n.scope-field label {\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.scope-field select {\n min-width: 160px;\n}\n\n.size-field {\n min-width: 180px;\n}\n\n.size-field input[type=\"range\"] {\n width: 100%;\n accent-color: var(--mj-brand-primary);\n}\n\n.tag-cloud-area {\n flex: 1;\n min-height: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 24px;\n overflow: hidden;\n}\n\n.tag-cloud-area mj-word-cloud {\n width: 100%;\n height: 100%;\n}\n\n.tag-cloud-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 12px;\n color: var(--mj-text-muted);\n text-align: center;\n}\n\n.tag-cloud-empty > i {\n font-size: 40px;\n opacity: 0.5;\n}\n"] }]
298
+ }], null, { Provider: [{
299
+ type: Input
300
+ }], TagSelected: [{
301
+ type: Output
302
+ }] }); })();
303
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TagCloudComponent, { className: "TagCloudComponent", filePath: "src/KnowledgeHub/components/visualize/tag-cloud/tag-cloud.component.ts", lineNumber: 58 }); })();
304
+ /** Tree-shaking prevention */
305
+ export function LoadTagCloudComponent() {
306
+ // Prevents tree-shaking of the component
307
+ }
308
+ //# sourceMappingURL=tag-cloud.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tag-cloud.component.js","sourceRoot":"","sources":["../../../../../src/KnowledgeHub/components/visualize/tag-cloud/tag-cloud.component.ts","../../../../../src/KnowledgeHub/components/visualize/tag-cloud/tag-cloud.component.html"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Knowledge Hub Tag Cloud (Visualize > Tag Cloud mode)\n *\n * Renders a weighted tag cloud via `@memberjunction/ng-word-cloud`'s\n * `MJWordCloudComponent`, driven by `TagCloudEngine.Instance.GetTagCloud(...)`.\n *\n * Provides a scope picker (Content Source / Content Type / Tag root) plus a\n * sizing control. Loads on init and whenever the scope changes. Emits a\n * `TagSelected` intent up to the host so the shared record-drilldown panel can\n * be populated by the host (this component never touches NavigationService).\n */\n\nimport {\n Component,\n Input,\n Output,\n EventEmitter,\n ChangeDetectorRef,\n OnInit,\n inject,\n} from '@angular/core';\nimport { IMetadataProvider } from '@memberjunction/core';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport {\n TagCloudEngine,\n TagCloudScope,\n TagCloudItem,\n} from '@memberjunction/tag-engine-base';\nimport { TagEngineBase } from '@memberjunction/tag-engine-base';\nimport { KnowledgeHubMetadataEngine } from '@memberjunction/core-entities';\nimport { WordCloudItem, WordCloudItemEvent } from '@memberjunction/ng-word-cloud';\n\n/** A selectable scope option (content source / content type / tag root). */\ninterface ScopeOption {\n ID: string;\n Name: string;\n}\n\n/**\n * Emitted when the user clicks a tag word. The host resolves this into the\n * shared drilldown panel (records carrying the tag).\n */\nexport interface TagCloudSelection {\n /** The clicked tag's text. */\n Tag: string;\n /** Raw frequency count carried from TagCloudItem. */\n Count: number;\n /** The scope currently applied (so the host can scope the drilldown query). */\n Scope: TagCloudScope;\n}\n\n@Component({\n standalone: false,\n selector: 'app-kh-tag-cloud',\n templateUrl: './tag-cloud.component.html',\n styleUrls: ['./tag-cloud.component.css'],\n})\nexport class TagCloudComponent extends BaseAngularComponent implements OnInit {\n private cdr = inject(ChangeDetectorRef);\n\n /** Re-declared so the host can bind `[Provider]` and we thread it through. */\n @Input() override Provider: IMetadataProvider | null = null;\n\n /** Emitted when a tag word is clicked. */\n @Output() TagSelected = new EventEmitter<TagCloudSelection>();\n\n // ================================================================\n // State\n // ================================================================\n\n public IsLoading = true;\n public Items: WordCloudItem[] = [];\n\n /** Scope picker options. */\n public ContentSourceOptions: ScopeOption[] = [];\n public ContentTypeOptions: ScopeOption[] = [];\n public TagRootOptions: ScopeOption[] = [];\n\n /** Current scope selections (empty string = \"All\"). */\n public SelectedContentSourceID = '';\n public SelectedContentTypeID = '';\n public SelectedTagRootID = '';\n\n /** Sizing: maximum font size driven by weight. */\n public MaxFontSize = 56;\n public MinFontSize = 14;\n\n /** Color mode passed to the word cloud. */\n public ColorMode: 'brand' | 'categorical' | 'weight-gradient' = 'weight-gradient';\n\n // ================================================================\n // Lifecycle\n // ================================================================\n\n async ngOnInit(): Promise<void> {\n await this.loadScopeOptions();\n await this.LoadCloud();\n }\n\n // ================================================================\n // Public Methods\n // ================================================================\n\n /** Re-load the cloud for the current scope. Called on init + scope change. */\n public async LoadCloud(): Promise<void> {\n this.IsLoading = true;\n this.cdr.detectChanges();\n\n try {\n const scope = this.BuildScope();\n const provider = this.ProviderToUse;\n const items: TagCloudItem[] = await TagCloudEngine.Instance.GetTagCloud(\n scope,\n { Limit: 150, MinWeight: 0 },\n provider.CurrentUser,\n provider,\n );\n this.Items = items.map(item => this.toWordCloudItem(item));\n } catch (error) {\n console.error('[TagCloud] Error loading tag cloud:', error);\n this.Items = [];\n } finally {\n this.IsLoading = false;\n this.cdr.detectChanges();\n }\n }\n\n /** Reload after any scope dropdown change. */\n public OnScopeChanged(): void {\n void this.LoadCloud();\n }\n\n /** Apply a new max font size (sizing-by-weight control). */\n public OnSizeChanged(value: number): void {\n this.MaxFontSize = value;\n this.cdr.detectChanges();\n }\n\n /** Clear all scope filters and reload. */\n public ClearScope(): void {\n this.SelectedContentSourceID = '';\n this.SelectedContentTypeID = '';\n this.SelectedTagRootID = '';\n void this.LoadCloud();\n }\n\n public get HasActiveScope(): boolean {\n return !!(this.SelectedContentSourceID || this.SelectedContentTypeID || this.SelectedTagRootID);\n }\n\n public get HasItems(): boolean {\n return this.Items.length > 0;\n }\n\n /** Word-cloud click handler — emits a selection up to the host. */\n public OnWordClicked(event: WordCloudItemEvent): void {\n const count = Number(event.Item.Metadata?.['Count'] ?? 0);\n this.TagSelected.emit({\n Tag: event.Item.Text,\n Count: count,\n Scope: this.BuildScope(),\n });\n }\n\n /** Build the current TagCloudScope from the picker selections. */\n public BuildScope(): TagCloudScope {\n const scope: TagCloudScope = {};\n if (this.SelectedContentSourceID) {\n scope.ContentSourceIDs = [this.SelectedContentSourceID];\n }\n if (this.SelectedContentTypeID) {\n scope.ContentTypeIDs = [this.SelectedContentTypeID];\n }\n if (this.SelectedTagRootID) {\n scope.TagRootIDs = [this.SelectedTagRootID];\n }\n return scope;\n }\n\n // ================================================================\n // Private Methods\n // ================================================================\n\n /** Map an engine TagCloudItem to a word-cloud WordCloudItem (Count → Metadata). */\n private toWordCloudItem(item: TagCloudItem): WordCloudItem {\n return {\n Text: item.Text,\n Weight: item.Weight,\n Metadata: { Count: item.Count },\n };\n }\n\n /** Populate scope-picker options from the KH + Tag engines. */\n private async loadScopeOptions(): Promise<void> {\n try {\n const provider = this.ProviderToUse;\n const khEngine = KnowledgeHubMetadataEngine.Instance;\n await khEngine.Config(false, provider.CurrentUser, provider);\n\n this.ContentSourceOptions = khEngine.ContentSources\n .map(s => ({ ID: s.ID, Name: s.Name ?? 'Untitled' }))\n .sort((a, b) => a.Name.localeCompare(b.Name));\n\n this.ContentTypeOptions = khEngine.ContentTypes\n .map(t => ({ ID: t.ID, Name: t.Name ?? 'Untitled' }))\n .sort((a, b) => a.Name.localeCompare(b.Name));\n\n const tagEngine = TagEngineBase.Instance;\n await tagEngine.Config(false, provider.CurrentUser, provider);\n this.TagRootOptions = tagEngine.Tags\n .filter(t => !t.ParentID)\n .map(t => ({ ID: t.ID, Name: t.DisplayName || t.Name }))\n .sort((a, b) => a.Name.localeCompare(b.Name));\n } catch (error) {\n console.warn('[TagCloud] Error loading scope options:', error);\n }\n this.cdr.detectChanges();\n }\n}\n\n/** Tree-shaking prevention */\nexport function LoadTagCloudComponent(): void {\n // Prevents tree-shaking of the component\n}\n","<div class=\"tag-cloud-container\">\n <!-- Scope picker / sizing toolbar -->\n <div class=\"tag-cloud-toolbar\">\n <div class=\"scope-field\">\n <label>Content Source</label>\n <select class=\"mj-input\" [(ngModel)]=\"SelectedContentSourceID\" (ngModelChange)=\"OnScopeChanged()\">\n <option value=\"\">All Sources</option>\n @for (opt of ContentSourceOptions; track opt.ID) {\n <option [value]=\"opt.ID\">{{ opt.Name }}</option>\n }\n </select>\n </div>\n\n <div class=\"scope-field\">\n <label>Content Type</label>\n <select class=\"mj-input\" [(ngModel)]=\"SelectedContentTypeID\" (ngModelChange)=\"OnScopeChanged()\">\n <option value=\"\">All Types</option>\n @for (opt of ContentTypeOptions; track opt.ID) {\n <option [value]=\"opt.ID\">{{ opt.Name }}</option>\n }\n </select>\n </div>\n\n <div class=\"scope-field\">\n <label>Tag Root</label>\n <select class=\"mj-input\" [(ngModel)]=\"SelectedTagRootID\" (ngModelChange)=\"OnScopeChanged()\">\n <option value=\"\">All Tags</option>\n @for (opt of TagRootOptions; track opt.ID) {\n <option [value]=\"opt.ID\">{{ opt.Name }}</option>\n }\n </select>\n </div>\n\n <div class=\"scope-field size-field\">\n <label>Max Size: {{ MaxFontSize }}px</label>\n <input type=\"range\" min=\"28\" max=\"96\" step=\"4\"\n [value]=\"MaxFontSize\"\n (input)=\"OnSizeChanged($any($event.target).valueAsNumber)\" />\n </div>\n\n @if (HasActiveScope) {\n <button mjButton variant=\"flat\" size=\"sm\" (click)=\"ClearScope()\">\n <i class=\"fa-solid fa-filter-circle-xmark\"></i> Clear\n </button>\n }\n </div>\n\n <!-- Cloud area -->\n <div class=\"tag-cloud-area\">\n @if (IsLoading) {\n <mj-loading text=\"Building tag cloud...\"></mj-loading>\n } @else if (!HasItems) {\n <div class=\"tag-cloud-empty\">\n <i class=\"fa-solid fa-tags\"></i>\n <p>No tags found for the current scope</p>\n @if (HasActiveScope) {\n <button mjButton variant=\"outline\" size=\"sm\" (click)=\"ClearScope()\">Clear filters</button>\n }\n </div>\n } @else {\n <mj-word-cloud\n [Items]=\"Items\"\n [MinFontSize]=\"MinFontSize\"\n [MaxFontSize]=\"MaxFontSize\"\n [ColorMode]=\"ColorMode\"\n [Interactive]=\"true\"\n (ItemClick)=\"OnWordClicked($event)\">\n </mj-word-cloud>\n }\n </div>\n</div>\n"]}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * @fileoverview Knowledge Hub "Visualize" Resource (host surface)
3
+ *
4
+ * Phase 5 host surface that replaces the standalone "Clusters" tab. It hosts two
5
+ * visualization modes behind an internal segmented control:
6
+ * - "Clusters" — the existing cluster scatter visualization (embedded child).
7
+ * - "Tag Cloud" — a weighted tag cloud driven by TagCloudEngine.
8
+ *
9
+ * Both modes feed ONE shared record-drilldown panel:
10
+ * - cluster point selection → a single record opened/listed.
11
+ * - tag-cloud word selection → the records carrying that tag (via RunView).
12
+ *
13
+ * The host owns the resource lifecycle (NotifyLoadComplete), agent context
14
+ * (ActiveVisualizationMode), and all navigation — the embedded children emit
15
+ * open-record intents up to here.
16
+ */
17
+ import { OnDestroy, AfterViewInit } from '@angular/core';
18
+ import { Subject } from 'rxjs';
19
+ import { ResourceData } from '@memberjunction/core-entities';
20
+ import { BaseResourceComponent, NavigationService } from '@memberjunction/ng-shared';
21
+ import { TagCloudComponent, TagCloudSelection } from './tag-cloud/tag-cloud.component';
22
+ import { DrilldownRecord, DrilldownOpenRequest } from './record-drilldown/record-drilldown.component';
23
+ import * as i0 from "@angular/core";
24
+ /** Visualization modes hosted by this surface. */
25
+ export type VisualizationMode = 'clusters' | 'tagcloud';
26
+ interface ModeOption {
27
+ ID: VisualizationMode;
28
+ Label: string;
29
+ Icon: string;
30
+ }
31
+ export declare class VisualizeResourceComponent extends BaseResourceComponent implements AfterViewInit, OnDestroy {
32
+ tagCloud?: TagCloudComponent;
33
+ private cdr;
34
+ protected navigationService: NavigationService;
35
+ protected destroy$: Subject<void>;
36
+ GetResourceDisplayName(_data: ResourceData): Promise<string>;
37
+ GetResourceIconClass(_data: ResourceData): Promise<string>;
38
+ Modes: ModeOption[];
39
+ ActiveMode: VisualizationMode;
40
+ DrilldownVisible: boolean;
41
+ DrilldownTitle: string;
42
+ DrilldownSubtitle: string;
43
+ DrilldownIcon: string;
44
+ DrilldownLoading: boolean;
45
+ DrilldownRecords: DrilldownRecord[];
46
+ /** Current preference key for the active mode. */
47
+ private static readonly PREFS_KEY;
48
+ /** Legacy key (pre-rename) — read for back-compat only. */
49
+ private static readonly LEGACY_PREFS_KEY;
50
+ ngAfterViewInit(): Promise<void>;
51
+ ngOnDestroy(): void;
52
+ SelectMode(mode: VisualizationMode): void;
53
+ IsActiveMode(mode: VisualizationMode): boolean;
54
+ TrackByMode(_index: number, mode: ModeOption): string;
55
+ /** Cluster mode: open the underlying entity record directly. */
56
+ OnClusterOpenRecord(request: {
57
+ EntityName: string;
58
+ RecordID: string;
59
+ }): void;
60
+ /** Tag-cloud mode: list the records carrying the clicked tag in the drilldown. */
61
+ OnTagSelected(selection: TagCloudSelection): Promise<void>;
62
+ /** Drilldown open-record intent (from the shared panel). */
63
+ OnDrilldownOpenRecord(request: DrilldownOpenRequest): void;
64
+ CloseDrilldown(): void;
65
+ /**
66
+ * Load the content-item records carrying a given tag, scoped to the same
67
+ * content-source / content-type the cloud was built with. Each returned row
68
+ * is a `MJ: Content Items` record the user can open.
69
+ */
70
+ private loadRecordsForTag;
71
+ /** Build the `MJ: Content Items` filter: ID IN (...) plus optional scope. */
72
+ private buildItemFilter;
73
+ /** Open an entity record via NavigationService (single navigation path). */
74
+ private openEntityRecord;
75
+ private emitAgentContext;
76
+ private registerAgentTools;
77
+ private persistModePreference;
78
+ private loadModePreference;
79
+ static ɵfac: i0.ɵɵFactoryDeclaration<VisualizeResourceComponent, never>;
80
+ static ɵcmp: i0.ɵɵComponentDeclaration<VisualizeResourceComponent, "app-visualize-resource", never, {}, {}, never, never, false, never>;
81
+ }
82
+ /** Tree-shaking prevention */
83
+ export declare function LoadVisualizeResource(): void;
84
+ export {};
85
+ //# sourceMappingURL=visualize-resource.component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"visualize-resource.component.d.ts","sourceRoot":"","sources":["../../../../src/KnowledgeHub/components/visualize/visualize-resource.component.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAgC,SAAS,EAAE,aAAa,EAAqB,MAAM,eAAe,CAAC;AAC1G,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAE/B,OAAO,EAAE,YAAY,EAAkB,MAAM,+BAA+B,CAAC;AAE7E,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAErF,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACvF,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,+CAA+C,CAAC;;AAEtG,kDAAkD;AAClD,MAAM,MAAM,iBAAiB,GAAG,UAAU,GAAG,UAAU,CAAC;AAExD,UAAU,UAAU;IAChB,EAAE,EAAE,iBAAiB,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CAChB;AAED,qBAOa,0BAA2B,SAAQ,qBAAsB,YAAW,aAAa,EAAE,SAAS;IAC9E,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAEpD,OAAO,CAAC,GAAG,CAA6B;IACxC,UAAmB,iBAAiB,oBAA6B;IACjE,UAAmB,QAAQ,gBAAuB;IAM5C,sBAAsB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAI5D,oBAAoB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAQzD,KAAK,EAAE,UAAU,EAAE,CAGxB;IAEK,UAAU,EAAE,iBAAiB,CAAc;IAM3C,gBAAgB,UAAS;IACzB,cAAc,SAAM;IACpB,iBAAiB,SAAM;IACvB,aAAa,SAAsB;IACnC,gBAAgB,UAAS;IACzB,gBAAgB,EAAE,eAAe,EAAE,CAAM;IAMhD,kDAAkD;IAClD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAuB;IACxD,2DAA2D;IAC3D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAA2B;IAM7D,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAatC,WAAW,IAAI,IAAI;IAUZ,UAAU,CAAC,IAAI,EAAE,iBAAiB,GAAG,IAAI;IAWzC,YAAY,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO;IAI9C,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,MAAM;IAQ5D,gEAAgE;IACzD,mBAAmB,CAAC,OAAO,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAInF,kFAAkF;IACrE,aAAa,CAAC,SAAS,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBvE,4DAA4D;IACrD,qBAAqB,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI;IAI1D,cAAc,IAAI,IAAI;IAW7B;;;;OAIG;YACW,iBAAiB;IAyD/B,6EAA6E;IAC7E,OAAO,CAAC,eAAe;IAiBvB,4EAA4E;IAC5E,OAAO,CAAC,gBAAgB;IAmBxB,OAAO,CAAC,gBAAgB;IAMxB,OAAO,CAAC,kBAAkB;IA0B1B,OAAO,CAAC,qBAAqB;IAI7B,OAAO,CAAC,kBAAkB;yCAtRjB,0BAA0B;2CAA1B,0BAA0B;CA8RtC;AAED,8BAA8B;AAC9B,wBAAgB,qBAAqB,IAAI,IAAI,CAE5C"}