@memberjunction/ng-dashboards 5.39.0 → 5.40.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts +128 -4
- package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts.map +1 -1
- package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js +548 -145
- package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js.map +1 -1
- package/dist/AI/components/autotagging/components/classify-item-drilldown.component.d.ts +56 -0
- package/dist/AI/components/autotagging/components/classify-item-drilldown.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/components/classify-item-drilldown.component.js +423 -0
- package/dist/AI/components/autotagging/components/classify-item-drilldown.component.js.map +1 -0
- package/dist/AI/components/autotagging/components/classify-item-grid.component.d.ts +70 -0
- package/dist/AI/components/autotagging/components/classify-item-grid.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/components/classify-item-grid.component.js +308 -0
- package/dist/AI/components/autotagging/components/classify-item-grid.component.js.map +1 -0
- package/dist/AI/components/autotagging/components/classify-org-context-editor.component.d.ts +29 -0
- package/dist/AI/components/autotagging/components/classify-org-context-editor.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/components/classify-org-context-editor.component.js +186 -0
- package/dist/AI/components/autotagging/components/classify-org-context-editor.component.js.map +1 -0
- package/dist/AI/components/autotagging/components/classify-overview-analytics.component.d.ts +69 -0
- package/dist/AI/components/autotagging/components/classify-overview-analytics.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/components/classify-overview-analytics.component.js +278 -0
- package/dist/AI/components/autotagging/components/classify-overview-analytics.component.js.map +1 -0
- package/dist/AI/components/autotagging/components/classify-seed-taxonomy.component.d.ts +73 -0
- package/dist/AI/components/autotagging/components/classify-seed-taxonomy.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/components/classify-seed-taxonomy.component.js +393 -0
- package/dist/AI/components/autotagging/components/classify-seed-taxonomy.component.js.map +1 -0
- package/dist/AI/components/autotagging/dialogs/classify-setup-wizard.component.d.ts +122 -0
- package/dist/AI/components/autotagging/dialogs/classify-setup-wizard.component.d.ts.map +1 -0
- package/dist/AI/components/autotagging/dialogs/classify-setup-wizard.component.js +908 -0
- package/dist/AI/components/autotagging/dialogs/classify-setup-wizard.component.js.map +1 -0
- package/dist/AI/components/autotagging/dialogs/source-type-form.dialog.component.d.ts +100 -2
- package/dist/AI/components/autotagging/dialogs/source-type-form.dialog.component.d.ts.map +1 -1
- package/dist/AI/components/autotagging/dialogs/source-type-form.dialog.component.js +603 -213
- package/dist/AI/components/autotagging/dialogs/source-type-form.dialog.component.js.map +1 -1
- package/dist/AI/components/autotagging/shared/classify.format.d.ts +15 -0
- package/dist/AI/components/autotagging/shared/classify.format.d.ts.map +1 -1
- package/dist/AI/components/autotagging/shared/classify.format.js +51 -0
- package/dist/AI/components/autotagging/shared/classify.format.js.map +1 -1
- package/dist/AI/components/autotagging/shared/classify.types.d.ts +43 -0
- package/dist/AI/components/autotagging/shared/classify.types.d.ts.map +1 -1
- package/dist/AI/components/autotagging/shared/classify.types.js.map +1 -1
- package/dist/AI/components/autotagging/tabs/history-tab.component.d.ts +38 -1
- package/dist/AI/components/autotagging/tabs/history-tab.component.d.ts.map +1 -1
- package/dist/AI/components/autotagging/tabs/history-tab.component.js +185 -68
- package/dist/AI/components/autotagging/tabs/history-tab.component.js.map +1 -1
- package/dist/AI/components/autotagging/tabs/pipeline-tab.component.d.ts +10 -1
- package/dist/AI/components/autotagging/tabs/pipeline-tab.component.d.ts.map +1 -1
- package/dist/AI/components/autotagging/tabs/pipeline-tab.component.js +249 -188
- package/dist/AI/components/autotagging/tabs/pipeline-tab.component.js.map +1 -1
- package/dist/AI/components/autotagging/tabs/sources-tab.component.d.ts +12 -1
- package/dist/AI/components/autotagging/tabs/sources-tab.component.d.ts.map +1 -1
- package/dist/AI/components/autotagging/tabs/sources-tab.component.js +377 -296
- package/dist/AI/components/autotagging/tabs/sources-tab.component.js.map +1 -1
- package/dist/AI/components/autotagging/tabs/tags-tab.component.d.ts +8 -0
- package/dist/AI/components/autotagging/tabs/tags-tab.component.d.ts.map +1 -1
- package/dist/AI/components/autotagging/tabs/tags-tab.component.js +112 -68
- package/dist/AI/components/autotagging/tabs/tags-tab.component.js.map +1 -1
- package/dist/AI/components/autotagging/tabs/types-tab.component.d.ts +9 -0
- package/dist/AI/components/autotagging/tabs/types-tab.component.d.ts.map +1 -1
- package/dist/AI/components/autotagging/tabs/types-tab.component.js +87 -36
- package/dist/AI/components/autotagging/tabs/types-tab.component.js.map +1 -1
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts +3 -0
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts.map +1 -1
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.js +15 -3
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.js.map +1 -1
- package/dist/AI/components/execution-monitoring.component.js +1 -1
- package/dist/AI/components/execution-monitoring.component.js.map +1 -1
- package/dist/AI/components/tags/tags-resource.component.d.ts +1 -0
- package/dist/AI/components/tags/tags-resource.component.d.ts.map +1 -1
- package/dist/AI/components/tags/tags-resource.component.js +28 -6
- package/dist/AI/components/tags/tags-resource.component.js.map +1 -1
- package/dist/AI/components/vectors/vector-management-resource.component.d.ts +3 -0
- package/dist/AI/components/vectors/vector-management-resource.component.d.ts.map +1 -1
- package/dist/AI/components/vectors/vector-management-resource.component.js +330 -302
- package/dist/AI/components/vectors/vector-management-resource.component.js.map +1 -1
- package/dist/APIKeys/api-applications-panel.component.js +2 -2
- package/dist/APIKeys/api-key-create-dialog.component.js +2 -2
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +31 -340
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.js +468 -1958
- package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
- package/dist/DataExplorer/data-explorer-resource.component.d.ts.map +1 -1
- package/dist/DataExplorer/data-explorer-resource.component.js +10 -0
- package/dist/DataExplorer/data-explorer-resource.component.js.map +1 -1
- package/dist/KnowledgeHub/components/analytics/analytics-resource.component.d.ts.map +1 -1
- package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js +12 -9
- package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js.map +1 -1
- package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.d.ts +27 -2
- package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.d.ts.map +1 -1
- package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js +244 -120
- package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js.map +1 -1
- package/dist/KnowledgeHub/components/visualize/record-drilldown/record-drilldown.component.d.ts +65 -0
- package/dist/KnowledgeHub/components/visualize/record-drilldown/record-drilldown.component.d.ts.map +1 -0
- package/dist/KnowledgeHub/components/visualize/record-drilldown/record-drilldown.component.js +176 -0
- package/dist/KnowledgeHub/components/visualize/record-drilldown/record-drilldown.component.js.map +1 -0
- package/dist/KnowledgeHub/components/visualize/tag-cloud/tag-cloud.component.d.ts +81 -0
- package/dist/KnowledgeHub/components/visualize/tag-cloud/tag-cloud.component.d.ts.map +1 -0
- package/dist/KnowledgeHub/components/visualize/tag-cloud/tag-cloud.component.js +308 -0
- package/dist/KnowledgeHub/components/visualize/tag-cloud/tag-cloud.component.js.map +1 -0
- package/dist/KnowledgeHub/components/visualize/visualize-resource.component.d.ts +85 -0
- package/dist/KnowledgeHub/components/visualize/visualize-resource.component.d.ts.map +1 -0
- package/dist/KnowledgeHub/components/visualize/visualize-resource.component.js +362 -0
- package/dist/KnowledgeHub/components/visualize/visualize-resource.component.js.map +1 -0
- package/dist/KnowledgeHub/index.d.ts +3 -0
- package/dist/KnowledgeHub/index.d.ts.map +1 -1
- package/dist/KnowledgeHub/index.js +3 -0
- package/dist/KnowledgeHub/index.js.map +1 -1
- package/dist/MCP/components/mcp-server-dialog.component.js +2 -2
- package/dist/QueryBrowser/query-browser-resource.component.js +1 -1
- package/dist/QueryBrowser/query-browser-resource.component.js.map +1 -1
- package/dist/ai-dashboards.module.d.ts +48 -38
- package/dist/ai-dashboards.module.d.ts.map +1 -1
- package/dist/ai-dashboards.module.js +41 -1
- package/dist/ai-dashboards.module.js.map +1 -1
- package/dist/data-explorer-dashboards.module.d.ts +12 -14
- package/dist/data-explorer-dashboards.module.d.ts.map +1 -1
- package/dist/data-explorer-dashboards.module.js +5 -14
- package/dist/data-explorer-dashboards.module.js.map +1 -1
- package/dist/public-api.d.ts +3 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +3 -0
- package/dist/public-api.js.map +1 -1
- package/package.json +57 -55
- package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.d.ts +0 -79
- package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.d.ts.map +0 -1
- package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.js +0 -195
- package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.js.map +0 -1
- package/dist/DataExplorer/components/view-selector/view-selector.component.d.ts +0 -226
- package/dist/DataExplorer/components/view-selector/view-selector.component.d.ts.map +0 -1
- package/dist/DataExplorer/components/view-selector/view-selector.component.js +0 -861
- package/dist/DataExplorer/components/view-selector/view-selector.component.js.map +0 -1
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Classify · Seed-taxonomy review.
|
|
3
|
+
*
|
|
4
|
+
* Calls the server-side `GenerateSeedTaxonomy` GraphQL mutation (which samples a
|
|
5
|
+
* source's content and proposes a tag tree), renders the proposal as a checkbox
|
|
6
|
+
* tree with inline rename, and — on Accept — persists the selected nodes as
|
|
7
|
+
* `MJ: Tags` (parent/child wired via ParentID). Used standalone on the Tags /
|
|
8
|
+
* Taxonomy area and embedded inside the setup wizard's Taxonomy step.
|
|
9
|
+
*
|
|
10
|
+
* The mutation is invoked through the first-class transport helper
|
|
11
|
+
* `GraphQLClassifyClient` (constructed from the threaded `ProviderToUse`,
|
|
12
|
+
* narrowed to the concrete `GraphQLDataProvider` it is at runtime), which
|
|
13
|
+
* returns a strongly-typed `SeedTaxonomyResult` — no inline GraphQL or manual
|
|
14
|
+
* JSON parsing in the component.
|
|
15
|
+
*/
|
|
16
|
+
import { Component, ChangeDetectorRef, EventEmitter, Input, Output, inject } from '@angular/core';
|
|
17
|
+
import { BaseAngularComponent } from '@memberjunction/ng-base-types';
|
|
18
|
+
import { MJNotificationService } from '@memberjunction/ng-notifications';
|
|
19
|
+
import { TagEngineBase } from '@memberjunction/tag-engine-base';
|
|
20
|
+
import { GraphQLClassifyClient, } from '@memberjunction/graphql-dataprovider';
|
|
21
|
+
import * as i0 from "@angular/core";
|
|
22
|
+
import * as i1 from "@memberjunction/ng-shared-generic";
|
|
23
|
+
import * as i2 from "@memberjunction/ng-ui-components";
|
|
24
|
+
const _forTrack0 = ($index, $item) => $item.Key;
|
|
25
|
+
function ClassifySeedTaxonomyComponent_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
26
|
+
i0.ɵɵelement(0, "i", 6);
|
|
27
|
+
i0.ɵɵtext(1, " Generating\u2026 ");
|
|
28
|
+
} }
|
|
29
|
+
function ClassifySeedTaxonomyComponent_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
30
|
+
i0.ɵɵelement(0, "i", 7);
|
|
31
|
+
i0.ɵɵtext(1, " Generate again ");
|
|
32
|
+
} }
|
|
33
|
+
function ClassifySeedTaxonomyComponent_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
34
|
+
i0.ɵɵelement(0, "i", 8);
|
|
35
|
+
i0.ɵɵtext(1, " Generate seed taxonomy ");
|
|
36
|
+
} }
|
|
37
|
+
function ClassifySeedTaxonomyComponent_Conditional_6_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
38
|
+
i0.ɵɵtext(0);
|
|
39
|
+
} if (rf & 2) {
|
|
40
|
+
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
41
|
+
i0.ɵɵtextInterpolate1(" \u00B7 ", ctx_r0.LastMethod, " ");
|
|
42
|
+
} }
|
|
43
|
+
function ClassifySeedTaxonomyComponent_Conditional_6_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
44
|
+
i0.ɵɵtext(0);
|
|
45
|
+
} if (rf & 2) {
|
|
46
|
+
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
47
|
+
i0.ɵɵtextInterpolate1(" \u00B7 sampled ", ctx_r0.LastSampleSize, " ");
|
|
48
|
+
} }
|
|
49
|
+
function ClassifySeedTaxonomyComponent_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
50
|
+
i0.ɵɵelementStart(0, "span", 4);
|
|
51
|
+
i0.ɵɵtext(1);
|
|
52
|
+
i0.ɵɵconditionalCreate(2, ClassifySeedTaxonomyComponent_Conditional_6_Conditional_2_Template, 1, 1);
|
|
53
|
+
i0.ɵɵconditionalCreate(3, ClassifySeedTaxonomyComponent_Conditional_6_Conditional_3_Template, 1, 1);
|
|
54
|
+
i0.ɵɵelementEnd();
|
|
55
|
+
} if (rf & 2) {
|
|
56
|
+
const ctx_r0 = i0.ɵɵnextContext();
|
|
57
|
+
i0.ɵɵadvance();
|
|
58
|
+
i0.ɵɵtextInterpolate1(" ", ctx_r0.SelectedCount, " selected ");
|
|
59
|
+
i0.ɵɵadvance();
|
|
60
|
+
i0.ɵɵconditional(ctx_r0.LastMethod ? 2 : -1);
|
|
61
|
+
i0.ɵɵadvance();
|
|
62
|
+
i0.ɵɵconditional(ctx_r0.LastSampleSize != null ? 3 : -1);
|
|
63
|
+
} }
|
|
64
|
+
function ClassifySeedTaxonomyComponent_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
65
|
+
i0.ɵɵelementStart(0, "div", 5);
|
|
66
|
+
i0.ɵɵelement(1, "mj-loading", 9);
|
|
67
|
+
i0.ɵɵelementEnd();
|
|
68
|
+
} }
|
|
69
|
+
function ClassifySeedTaxonomyComponent_Conditional_8_Conditional_0_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
70
|
+
i0.ɵɵelementStart(0, "div", 10);
|
|
71
|
+
i0.ɵɵelement(1, "i", 11);
|
|
72
|
+
i0.ɵɵtext(2, " No content sampled \u2014 this source has no ingested content items yet. Add content (crawl & vectorize the source) first, then generate a taxonomy, or skip this step and define the taxonomy later. ");
|
|
73
|
+
i0.ɵɵelementEnd();
|
|
74
|
+
} }
|
|
75
|
+
function ClassifySeedTaxonomyComponent_Conditional_8_Conditional_0_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
76
|
+
i0.ɵɵelementStart(0, "div", 10);
|
|
77
|
+
i0.ɵɵelement(1, "i", 12);
|
|
78
|
+
i0.ɵɵtext(2, " The model proposed no tags from the sampled content. Try generating again, or skip this step and define the taxonomy later. ");
|
|
79
|
+
i0.ɵɵelementEnd();
|
|
80
|
+
} }
|
|
81
|
+
function ClassifySeedTaxonomyComponent_Conditional_8_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
82
|
+
i0.ɵɵconditionalCreate(0, ClassifySeedTaxonomyComponent_Conditional_8_Conditional_0_Conditional_0_Template, 3, 0, "div", 10)(1, ClassifySeedTaxonomyComponent_Conditional_8_Conditional_0_Conditional_1_Template, 3, 0, "div", 10);
|
|
83
|
+
} if (rf & 2) {
|
|
84
|
+
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
85
|
+
i0.ɵɵconditional(ctx_r0.LastSampleSize === 0 ? 0 : 1);
|
|
86
|
+
} }
|
|
87
|
+
function ClassifySeedTaxonomyComponent_Conditional_8_Conditional_1_For_2_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
88
|
+
const _r5 = i0.ɵɵgetCurrentView();
|
|
89
|
+
i0.ɵɵelementStart(0, "input", 20, 0);
|
|
90
|
+
i0.ɵɵlistener("blur", function ClassifySeedTaxonomyComponent_Conditional_8_Conditional_1_For_2_Conditional_2_Template_input_blur_0_listener() { i0.ɵɵrestoreView(_r5); const renameInput_r6 = i0.ɵɵreference(1); const node_r4 = i0.ɵɵnextContext().$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.CommitRename(node_r4, renameInput_r6.value)); })("keyup.enter", function ClassifySeedTaxonomyComponent_Conditional_8_Conditional_1_For_2_Conditional_2_Template_input_keyup_enter_0_listener() { i0.ɵɵrestoreView(_r5); const renameInput_r6 = i0.ɵɵreference(1); const node_r4 = i0.ɵɵnextContext().$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.CommitRename(node_r4, renameInput_r6.value)); });
|
|
91
|
+
i0.ɵɵelementEnd();
|
|
92
|
+
} if (rf & 2) {
|
|
93
|
+
const node_r4 = i0.ɵɵnextContext().$implicit;
|
|
94
|
+
i0.ɵɵproperty("value", node_r4.Name);
|
|
95
|
+
} }
|
|
96
|
+
function ClassifySeedTaxonomyComponent_Conditional_8_Conditional_1_For_2_Conditional_3_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
97
|
+
i0.ɵɵelementStart(0, "span", 22);
|
|
98
|
+
i0.ɵɵtext(1);
|
|
99
|
+
i0.ɵɵelementEnd();
|
|
100
|
+
} if (rf & 2) {
|
|
101
|
+
const node_r4 = i0.ɵɵnextContext(2).$implicit;
|
|
102
|
+
i0.ɵɵadvance();
|
|
103
|
+
i0.ɵɵtextInterpolate(node_r4.MemberCount);
|
|
104
|
+
} }
|
|
105
|
+
function ClassifySeedTaxonomyComponent_Conditional_8_Conditional_1_For_2_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
106
|
+
const _r7 = i0.ɵɵgetCurrentView();
|
|
107
|
+
i0.ɵɵelementStart(0, "span", 21);
|
|
108
|
+
i0.ɵɵlistener("click", function ClassifySeedTaxonomyComponent_Conditional_8_Conditional_1_For_2_Conditional_3_Template_span_click_0_listener() { i0.ɵɵrestoreView(_r7); const node_r4 = i0.ɵɵnextContext().$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.StartRename(node_r4)); });
|
|
109
|
+
i0.ɵɵtext(1);
|
|
110
|
+
i0.ɵɵelementEnd();
|
|
111
|
+
i0.ɵɵconditionalCreate(2, ClassifySeedTaxonomyComponent_Conditional_8_Conditional_1_For_2_Conditional_3_Conditional_2_Template, 2, 1, "span", 22);
|
|
112
|
+
i0.ɵɵelementStart(3, "button", 23);
|
|
113
|
+
i0.ɵɵlistener("click", function ClassifySeedTaxonomyComponent_Conditional_8_Conditional_1_For_2_Conditional_3_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r7); const node_r4 = i0.ɵɵnextContext().$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.StartRename(node_r4)); });
|
|
114
|
+
i0.ɵɵelement(4, "i", 24);
|
|
115
|
+
i0.ɵɵelementEnd();
|
|
116
|
+
} if (rf & 2) {
|
|
117
|
+
const node_r4 = i0.ɵɵnextContext().$implicit;
|
|
118
|
+
i0.ɵɵadvance();
|
|
119
|
+
i0.ɵɵtextInterpolate(node_r4.Name);
|
|
120
|
+
i0.ɵɵadvance();
|
|
121
|
+
i0.ɵɵconditional(node_r4.MemberCount != null ? 2 : -1);
|
|
122
|
+
} }
|
|
123
|
+
function ClassifySeedTaxonomyComponent_Conditional_8_Conditional_1_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
124
|
+
const _r3 = i0.ɵɵgetCurrentView();
|
|
125
|
+
i0.ɵɵelementStart(0, "div", 17)(1, "input", 18);
|
|
126
|
+
i0.ɵɵlistener("change", function ClassifySeedTaxonomyComponent_Conditional_8_Conditional_1_For_2_Template_input_change_1_listener() { const node_r4 = i0.ɵɵrestoreView(_r3).$implicit; const ctx_r0 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r0.ToggleNode(node_r4)); });
|
|
127
|
+
i0.ɵɵelementEnd();
|
|
128
|
+
i0.ɵɵconditionalCreate(2, ClassifySeedTaxonomyComponent_Conditional_8_Conditional_1_For_2_Conditional_2_Template, 2, 1, "input", 19)(3, ClassifySeedTaxonomyComponent_Conditional_8_Conditional_1_For_2_Conditional_3_Template, 5, 2);
|
|
129
|
+
i0.ɵɵelementEnd();
|
|
130
|
+
} if (rf & 2) {
|
|
131
|
+
const node_r4 = ctx.$implicit;
|
|
132
|
+
i0.ɵɵstyleProp("padding-left", 12 + node_r4.Depth * 20, "px");
|
|
133
|
+
i0.ɵɵadvance();
|
|
134
|
+
i0.ɵɵproperty("checked", node_r4.Selected);
|
|
135
|
+
i0.ɵɵadvance();
|
|
136
|
+
i0.ɵɵconditional(node_r4.Renaming ? 2 : 3);
|
|
137
|
+
} }
|
|
138
|
+
function ClassifySeedTaxonomyComponent_Conditional_8_Conditional_1_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
139
|
+
i0.ɵɵelement(0, "i", 6);
|
|
140
|
+
i0.ɵɵtext(1, " Saving\u2026 ");
|
|
141
|
+
} }
|
|
142
|
+
function ClassifySeedTaxonomyComponent_Conditional_8_Conditional_1_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
143
|
+
i0.ɵɵelement(0, "i", 25);
|
|
144
|
+
i0.ɵɵtext(1);
|
|
145
|
+
} if (rf & 2) {
|
|
146
|
+
const ctx_r0 = i0.ɵɵnextContext(3);
|
|
147
|
+
i0.ɵɵadvance();
|
|
148
|
+
i0.ɵɵtextInterpolate1(" Accept selected (", ctx_r0.SelectedCount, ") ");
|
|
149
|
+
} }
|
|
150
|
+
function ClassifySeedTaxonomyComponent_Conditional_8_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
151
|
+
const _r2 = i0.ɵɵgetCurrentView();
|
|
152
|
+
i0.ɵɵelementStart(0, "div", 13);
|
|
153
|
+
i0.ɵɵrepeaterCreate(1, ClassifySeedTaxonomyComponent_Conditional_8_Conditional_1_For_2_Template, 4, 4, "div", 14, _forTrack0);
|
|
154
|
+
i0.ɵɵelementEnd();
|
|
155
|
+
i0.ɵɵelementStart(3, "div", 15)(4, "button", 3);
|
|
156
|
+
i0.ɵɵlistener("click", function ClassifySeedTaxonomyComponent_Conditional_8_Conditional_1_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.AcceptSelected()); });
|
|
157
|
+
i0.ɵɵconditionalCreate(5, ClassifySeedTaxonomyComponent_Conditional_8_Conditional_1_Conditional_5_Template, 2, 0)(6, ClassifySeedTaxonomyComponent_Conditional_8_Conditional_1_Conditional_6_Template, 2, 1);
|
|
158
|
+
i0.ɵɵelementEnd();
|
|
159
|
+
i0.ɵɵelementStart(7, "button", 16);
|
|
160
|
+
i0.ɵɵlistener("click", function ClassifySeedTaxonomyComponent_Conditional_8_Conditional_1_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.Generate()); });
|
|
161
|
+
i0.ɵɵelement(8, "i", 7);
|
|
162
|
+
i0.ɵɵtext(9, " Generate again ");
|
|
163
|
+
i0.ɵɵelementEnd()();
|
|
164
|
+
} if (rf & 2) {
|
|
165
|
+
const ctx_r0 = i0.ɵɵnextContext(2);
|
|
166
|
+
i0.ɵɵadvance();
|
|
167
|
+
i0.ɵɵrepeater(ctx_r0.FlatNodes);
|
|
168
|
+
i0.ɵɵadvance(3);
|
|
169
|
+
i0.ɵɵproperty("disabled", ctx_r0.IsAccepting || !ctx_r0.HasSelection);
|
|
170
|
+
i0.ɵɵadvance();
|
|
171
|
+
i0.ɵɵconditional(ctx_r0.IsAccepting ? 5 : 6);
|
|
172
|
+
i0.ɵɵadvance(2);
|
|
173
|
+
i0.ɵɵproperty("disabled", ctx_r0.IsGenerating);
|
|
174
|
+
} }
|
|
175
|
+
function ClassifySeedTaxonomyComponent_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
176
|
+
i0.ɵɵconditionalCreate(0, ClassifySeedTaxonomyComponent_Conditional_8_Conditional_0_Template, 2, 1)(1, ClassifySeedTaxonomyComponent_Conditional_8_Conditional_1_Template, 10, 3);
|
|
177
|
+
} if (rf & 2) {
|
|
178
|
+
const ctx_r0 = i0.ɵɵnextContext();
|
|
179
|
+
i0.ɵɵconditional(ctx_r0.FlatNodes.length === 0 ? 0 : 1);
|
|
180
|
+
} }
|
|
181
|
+
export class ClassifySeedTaxonomyComponent extends BaseAngularComponent {
|
|
182
|
+
cdr = inject(ChangeDetectorRef);
|
|
183
|
+
/** The content source to sample for the taxonomy proposal. */
|
|
184
|
+
SourceID = null;
|
|
185
|
+
/** How many items to sample (passed to the mutation). */
|
|
186
|
+
SampleSize = 50;
|
|
187
|
+
/** Optional parent tag ID under which accepted root nodes are created. */
|
|
188
|
+
ParentTagID = null;
|
|
189
|
+
/** Emitted after Accept persists tags, with the count created. */
|
|
190
|
+
Accepted = new EventEmitter();
|
|
191
|
+
IsGenerating = false;
|
|
192
|
+
IsAccepting = false;
|
|
193
|
+
ProposedNodes = [];
|
|
194
|
+
HasGenerated = false;
|
|
195
|
+
LastMethod = null;
|
|
196
|
+
LastSampleSize = null;
|
|
197
|
+
keySeq = 0;
|
|
198
|
+
/** True when at least one node is checked. */
|
|
199
|
+
get HasSelection() {
|
|
200
|
+
return this.countSelected(this.ProposedNodes) > 0;
|
|
201
|
+
}
|
|
202
|
+
/** Count of currently-selected nodes (template-facing). */
|
|
203
|
+
get SelectedCount() {
|
|
204
|
+
return this.countSelected(this.ProposedNodes);
|
|
205
|
+
}
|
|
206
|
+
countSelected(nodes) {
|
|
207
|
+
let n = 0;
|
|
208
|
+
for (const node of nodes) {
|
|
209
|
+
if (node.Selected)
|
|
210
|
+
n++;
|
|
211
|
+
n += this.countSelected(node.Children);
|
|
212
|
+
}
|
|
213
|
+
return n;
|
|
214
|
+
}
|
|
215
|
+
/** Call the GenerateSeedTaxonomy mutation and render the proposal. */
|
|
216
|
+
async Generate() {
|
|
217
|
+
if (this.IsGenerating)
|
|
218
|
+
return;
|
|
219
|
+
if (!this.SourceID) {
|
|
220
|
+
MJNotificationService.Instance.CreateSimpleNotification('Select a source first.', 'warning', 3000);
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
this.IsGenerating = true;
|
|
224
|
+
this.cdr.detectChanges();
|
|
225
|
+
try {
|
|
226
|
+
const client = new GraphQLClassifyClient(this.ProviderToUse);
|
|
227
|
+
const result = await client.GenerateSeedTaxonomy({
|
|
228
|
+
SourceID: this.SourceID,
|
|
229
|
+
SampleSize: this.SampleSize,
|
|
230
|
+
});
|
|
231
|
+
if (!result.Success) {
|
|
232
|
+
MJNotificationService.Instance.CreateSimpleNotification(`Failed to generate taxonomy: ${result.ErrorMessage ?? 'Unknown error'}`, 'error', 5000);
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
this.LastMethod = result.Method ?? null;
|
|
236
|
+
this.LastSampleSize = result.SampleSize;
|
|
237
|
+
this.ProposedNodes = this.toViewModel(result.Nodes, 0);
|
|
238
|
+
this.HasGenerated = true;
|
|
239
|
+
}
|
|
240
|
+
catch (error) {
|
|
241
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
242
|
+
MJNotificationService.Instance.CreateSimpleNotification(`Error: ${msg}`, 'error', 5000);
|
|
243
|
+
}
|
|
244
|
+
finally {
|
|
245
|
+
this.IsGenerating = false;
|
|
246
|
+
this.cdr.detectChanges();
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
toViewModel(nodes, depth) {
|
|
250
|
+
return nodes.map(n => ({
|
|
251
|
+
Key: `n${this.keySeq++}`,
|
|
252
|
+
Name: n.Name ?? '(unnamed)',
|
|
253
|
+
Description: n.Description,
|
|
254
|
+
MemberCount: n.MemberCount,
|
|
255
|
+
Selected: true,
|
|
256
|
+
Renaming: false,
|
|
257
|
+
Depth: depth,
|
|
258
|
+
Children: this.toViewModel(n.Children ?? [], depth + 1),
|
|
259
|
+
}));
|
|
260
|
+
}
|
|
261
|
+
// ── Tree interactions ──
|
|
262
|
+
/** Toggle a node's selection, cascading to descendants. */
|
|
263
|
+
ToggleNode(node) {
|
|
264
|
+
const next = !node.Selected;
|
|
265
|
+
this.setSelectedRecursive(node, next);
|
|
266
|
+
this.cdr.detectChanges();
|
|
267
|
+
}
|
|
268
|
+
setSelectedRecursive(node, value) {
|
|
269
|
+
node.Selected = value;
|
|
270
|
+
for (const child of node.Children)
|
|
271
|
+
this.setSelectedRecursive(child, value);
|
|
272
|
+
}
|
|
273
|
+
StartRename(node) {
|
|
274
|
+
node.Renaming = true;
|
|
275
|
+
this.cdr.detectChanges();
|
|
276
|
+
}
|
|
277
|
+
CommitRename(node, value) {
|
|
278
|
+
const trimmed = value.trim();
|
|
279
|
+
if (trimmed)
|
|
280
|
+
node.Name = trimmed;
|
|
281
|
+
node.Renaming = false;
|
|
282
|
+
this.cdr.detectChanges();
|
|
283
|
+
}
|
|
284
|
+
/** Flatten the visible tree for the template (depth-first), preserving order. */
|
|
285
|
+
get FlatNodes() {
|
|
286
|
+
const out = [];
|
|
287
|
+
const walk = (nodes) => {
|
|
288
|
+
for (const n of nodes) {
|
|
289
|
+
out.push(n);
|
|
290
|
+
walk(n.Children);
|
|
291
|
+
}
|
|
292
|
+
};
|
|
293
|
+
walk(this.ProposedNodes);
|
|
294
|
+
return out;
|
|
295
|
+
}
|
|
296
|
+
// ── Accept → persist as MJ: Tags ──
|
|
297
|
+
/**
|
|
298
|
+
* Persist every selected node as an `MJ: Tags` record. Parent/child links use
|
|
299
|
+
* ParentID; root nodes use the optional ParentTagID input. Walks the tree
|
|
300
|
+
* top-down so a parent's saved ID is available when creating its children.
|
|
301
|
+
*/
|
|
302
|
+
async AcceptSelected() {
|
|
303
|
+
if (this.IsAccepting)
|
|
304
|
+
return;
|
|
305
|
+
if (!this.HasSelection) {
|
|
306
|
+
MJNotificationService.Instance.CreateSimpleNotification('Select at least one tag to accept.', 'warning', 3000);
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
this.IsAccepting = true;
|
|
310
|
+
this.cdr.detectChanges();
|
|
311
|
+
let created = 0;
|
|
312
|
+
try {
|
|
313
|
+
const p = this.ProviderToUse;
|
|
314
|
+
const persistLevel = async (nodes, parentID) => {
|
|
315
|
+
for (const node of nodes) {
|
|
316
|
+
let savedID = parentID;
|
|
317
|
+
if (node.Selected) {
|
|
318
|
+
const tag = await p.GetEntityObject('MJ: Tags', p.CurrentUser);
|
|
319
|
+
tag.NewRecord();
|
|
320
|
+
tag.Name = node.Name;
|
|
321
|
+
tag.DisplayName = node.Name;
|
|
322
|
+
if (node.Description)
|
|
323
|
+
tag.Description = node.Description;
|
|
324
|
+
tag.ParentID = parentID;
|
|
325
|
+
tag.Status = 'Active';
|
|
326
|
+
const ok = await tag.Save();
|
|
327
|
+
if (ok) {
|
|
328
|
+
created++;
|
|
329
|
+
savedID = tag.ID;
|
|
330
|
+
}
|
|
331
|
+
else {
|
|
332
|
+
const detail = tag.LatestResult?.CompleteMessage ?? 'Unknown error';
|
|
333
|
+
MJNotificationService.Instance.CreateSimpleNotification(`Failed to save tag "${node.Name}": ${detail}`, 'error', 5000);
|
|
334
|
+
// Children still attach to the original parent so the tree isn't orphaned.
|
|
335
|
+
savedID = parentID;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
// Recurse: children of an unselected node attach to the nearest selected ancestor.
|
|
339
|
+
await persistLevel(node.Children, savedID);
|
|
340
|
+
}
|
|
341
|
+
};
|
|
342
|
+
await persistLevel(this.ProposedNodes, this.ParentTagID);
|
|
343
|
+
// Refresh the tag cache so other views see the new tags.
|
|
344
|
+
await TagEngineBase.Instance.Config(true, p.CurrentUser, p);
|
|
345
|
+
MJNotificationService.Instance.CreateSimpleNotification(`Created ${created} tag${created === 1 ? '' : 's'}`, 'success', 3000);
|
|
346
|
+
this.Accepted.emit({ Created: created });
|
|
347
|
+
this.ProposedNodes = [];
|
|
348
|
+
this.HasGenerated = false;
|
|
349
|
+
}
|
|
350
|
+
catch (error) {
|
|
351
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
352
|
+
MJNotificationService.Instance.CreateSimpleNotification(`Error: ${msg}`, 'error', 5000);
|
|
353
|
+
}
|
|
354
|
+
finally {
|
|
355
|
+
this.IsAccepting = false;
|
|
356
|
+
this.cdr.detectChanges();
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
static ɵfac = /*@__PURE__*/ (() => { let ɵClassifySeedTaxonomyComponent_BaseFactory; return function ClassifySeedTaxonomyComponent_Factory(__ngFactoryType__) { return (ɵClassifySeedTaxonomyComponent_BaseFactory || (ɵClassifySeedTaxonomyComponent_BaseFactory = i0.ɵɵgetInheritedFactory(ClassifySeedTaxonomyComponent)))(__ngFactoryType__ || ClassifySeedTaxonomyComponent); }; })();
|
|
360
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ClassifySeedTaxonomyComponent, selectors: [["classify-seed-taxonomy"]], inputs: { SourceID: "SourceID", SampleSize: "SampleSize", ParentTagID: "ParentTagID" }, outputs: { Accepted: "Accepted" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 9, vars: 4, consts: [["renameInput", ""], [1, "cls-seed"], [1, "cls-seed-bar"], ["mjButton", "", "variant", "primary", "size", "sm", 3, "click", "disabled"], [1, "cls-seed-meta"], [1, "cls-seed-loading"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "fa-solid", "fa-rotate"], [1, "fa-solid", "fa-wand-magic-sparkles"], ["text", "Sampling content and proposing tags\u2026"], [1, "cls-seed-empty"], [1, "fa-solid", "fa-triangle-exclamation"], [1, "fa-solid", "fa-circle-info"], [1, "cls-seed-tree"], [1, "cls-seed-row", 3, "padding-left"], [1, "cls-seed-actions"], ["mjButton", "", "variant", "secondary", "size", "sm", 3, "click", "disabled"], [1, "cls-seed-row"], ["type", "checkbox", 3, "change", "checked"], ["type", "text", 1, "mj-input", "cls-seed-rename", 3, "value"], ["type", "text", 1, "mj-input", "cls-seed-rename", 3, "blur", "keyup.enter", "value"], ["title", "Click to rename", 1, "cls-seed-name", 3, "click"], [1, "cls-seed-count"], ["aria-label", "Rename", 1, "cls-seed-rename-btn", 3, "click"], [1, "fa-solid", "fa-pen"], [1, "fa-solid", "fa-check"]], template: function ClassifySeedTaxonomyComponent_Template(rf, ctx) { if (rf & 1) {
|
|
361
|
+
i0.ɵɵelementStart(0, "div", 1)(1, "div", 2)(2, "button", 3);
|
|
362
|
+
i0.ɵɵlistener("click", function ClassifySeedTaxonomyComponent_Template_button_click_2_listener() { return ctx.Generate(); });
|
|
363
|
+
i0.ɵɵconditionalCreate(3, ClassifySeedTaxonomyComponent_Conditional_3_Template, 2, 0)(4, ClassifySeedTaxonomyComponent_Conditional_4_Template, 2, 0)(5, ClassifySeedTaxonomyComponent_Conditional_5_Template, 2, 0);
|
|
364
|
+
i0.ɵɵelementEnd();
|
|
365
|
+
i0.ɵɵconditionalCreate(6, ClassifySeedTaxonomyComponent_Conditional_6_Template, 4, 3, "span", 4);
|
|
366
|
+
i0.ɵɵelementEnd();
|
|
367
|
+
i0.ɵɵconditionalCreate(7, ClassifySeedTaxonomyComponent_Conditional_7_Template, 2, 0, "div", 5)(8, ClassifySeedTaxonomyComponent_Conditional_8_Template, 2, 1);
|
|
368
|
+
i0.ɵɵelementEnd();
|
|
369
|
+
} if (rf & 2) {
|
|
370
|
+
i0.ɵɵadvance(2);
|
|
371
|
+
i0.ɵɵproperty("disabled", ctx.IsGenerating || !ctx.SourceID);
|
|
372
|
+
i0.ɵɵadvance();
|
|
373
|
+
i0.ɵɵconditional(ctx.IsGenerating ? 3 : ctx.HasGenerated ? 4 : 5);
|
|
374
|
+
i0.ɵɵadvance(3);
|
|
375
|
+
i0.ɵɵconditional(ctx.HasGenerated ? 6 : -1);
|
|
376
|
+
i0.ɵɵadvance();
|
|
377
|
+
i0.ɵɵconditional(ctx.IsGenerating ? 7 : ctx.HasGenerated ? 8 : -1);
|
|
378
|
+
} }, dependencies: [i1.LoadingComponent, i2.MJButtonDirective], styles: [".cls-seed[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n.cls-seed-bar[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n.cls-seed-meta[_ngcontent-%COMP%] {\n font-size: 0.78rem;\n color: var(--mj-text-muted);\n}\n.cls-seed-loading[_ngcontent-%COMP%] {\n display: flex;\n justify-content: center;\n padding: 24px;\n}\n.cls-seed-empty[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 16px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n color: var(--mj-text-secondary);\n font-size: 0.85rem;\n}\n.cls-seed-empty[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { color: var(--mj-status-info); }\n.cls-seed-tree[_ngcontent-%COMP%] {\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n max-height: 360px;\n overflow-y: auto;\n padding: 6px 0;\n}\n.cls-seed-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding-top: 5px;\n padding-bottom: 5px;\n padding-right: 12px;\n}\n.cls-seed-row[_ngcontent-%COMP%]:hover { background: var(--mj-bg-surface-hover); }\n.cls-seed-name[_ngcontent-%COMP%] {\n flex: 1;\n font-size: 0.85rem;\n color: var(--mj-text-primary);\n cursor: text;\n}\n.cls-seed-rename[_ngcontent-%COMP%] {\n flex: 1;\n font-size: 0.85rem;\n}\n.cls-seed-count[_ngcontent-%COMP%] {\n font-size: 0.72rem;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-sunken);\n border-radius: 999px;\n padding: 1px 8px;\n}\n.cls-seed-rename-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n color: var(--mj-text-muted);\n cursor: pointer;\n padding: 2px 6px;\n font-size: 0.75rem;\n}\n.cls-seed-rename-btn[_ngcontent-%COMP%]:hover { color: var(--mj-brand-primary); }\n.cls-seed-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}"] });
|
|
379
|
+
}
|
|
380
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ClassifySeedTaxonomyComponent, [{
|
|
381
|
+
type: Component,
|
|
382
|
+
args: [{ standalone: false, selector: 'classify-seed-taxonomy', template: "<div class=\"cls-seed\">\n <div class=\"cls-seed-bar\">\n <button mjButton variant=\"primary\" size=\"sm\" (click)=\"Generate()\" [disabled]=\"IsGenerating || !SourceID\">\n @if (IsGenerating) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Generating\u2026\n } @else if (HasGenerated) {\n <i class=\"fa-solid fa-rotate\"></i> Generate again\n } @else {\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i> Generate seed taxonomy\n }\n </button>\n @if (HasGenerated) {\n <span class=\"cls-seed-meta\">\n {{ SelectedCount }} selected\n @if (LastMethod) { \u00B7 {{ LastMethod }} }\n @if (LastSampleSize != null) { \u00B7 sampled {{ LastSampleSize }} }\n </span>\n }\n </div>\n\n @if (IsGenerating) {\n <div class=\"cls-seed-loading\">\n <mj-loading text=\"Sampling content and proposing tags\u2026\"></mj-loading>\n </div>\n } @else if (HasGenerated) {\n @if (FlatNodes.length === 0) {\n @if (LastSampleSize === 0) {\n <div class=\"cls-seed-empty\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n No content sampled \u2014 this source has no ingested content items yet.\n Add content (crawl & vectorize the source) first, then generate a\n taxonomy, or skip this step and define the taxonomy later.\n </div>\n } @else {\n <div class=\"cls-seed-empty\">\n <i class=\"fa-solid fa-circle-info\"></i>\n The model proposed no tags from the sampled content. Try generating again,\n or skip this step and define the taxonomy later.\n </div>\n }\n } @else {\n <div class=\"cls-seed-tree\">\n @for (node of FlatNodes; track node.Key) {\n <div class=\"cls-seed-row\" [style.padding-left.px]=\"12 + node.Depth * 20\">\n <input type=\"checkbox\" [checked]=\"node.Selected\" (change)=\"ToggleNode(node)\">\n @if (node.Renaming) {\n <input #renameInput type=\"text\" class=\"mj-input cls-seed-rename\" [value]=\"node.Name\"\n (blur)=\"CommitRename(node, renameInput.value)\"\n (keyup.enter)=\"CommitRename(node, renameInput.value)\">\n } @else {\n <span class=\"cls-seed-name\" (click)=\"StartRename(node)\" title=\"Click to rename\">{{ node.Name }}</span>\n @if (node.MemberCount != null) {\n <span class=\"cls-seed-count\">{{ node.MemberCount }}</span>\n }\n <button class=\"cls-seed-rename-btn\" (click)=\"StartRename(node)\" aria-label=\"Rename\">\n <i class=\"fa-solid fa-pen\"></i>\n </button>\n }\n </div>\n }\n </div>\n\n <div class=\"cls-seed-actions\">\n <button mjButton variant=\"primary\" size=\"sm\" (click)=\"AcceptSelected()\"\n [disabled]=\"IsAccepting || !HasSelection\">\n @if (IsAccepting) { <i class=\"fa-solid fa-spinner fa-spin\"></i> Saving\u2026 }\n @else { <i class=\"fa-solid fa-check\"></i> Accept selected ({{ SelectedCount }}) }\n </button>\n <button mjButton variant=\"secondary\" size=\"sm\" (click)=\"Generate()\" [disabled]=\"IsGenerating\">\n <i class=\"fa-solid fa-rotate\"></i> Generate again\n </button>\n </div>\n }\n }\n</div>\n", styles: [".cls-seed {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n.cls-seed-bar {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n.cls-seed-meta {\n font-size: 0.78rem;\n color: var(--mj-text-muted);\n}\n.cls-seed-loading {\n display: flex;\n justify-content: center;\n padding: 24px;\n}\n.cls-seed-empty {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 16px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n color: var(--mj-text-secondary);\n font-size: 0.85rem;\n}\n.cls-seed-empty i { color: var(--mj-status-info); }\n.cls-seed-tree {\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n max-height: 360px;\n overflow-y: auto;\n padding: 6px 0;\n}\n.cls-seed-row {\n display: flex;\n align-items: center;\n gap: 8px;\n padding-top: 5px;\n padding-bottom: 5px;\n padding-right: 12px;\n}\n.cls-seed-row:hover { background: var(--mj-bg-surface-hover); }\n.cls-seed-name {\n flex: 1;\n font-size: 0.85rem;\n color: var(--mj-text-primary);\n cursor: text;\n}\n.cls-seed-rename {\n flex: 1;\n font-size: 0.85rem;\n}\n.cls-seed-count {\n font-size: 0.72rem;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-sunken);\n border-radius: 999px;\n padding: 1px 8px;\n}\n.cls-seed-rename-btn {\n background: none;\n border: none;\n color: var(--mj-text-muted);\n cursor: pointer;\n padding: 2px 6px;\n font-size: 0.75rem;\n}\n.cls-seed-rename-btn:hover { color: var(--mj-brand-primary); }\n.cls-seed-actions {\n display: flex;\n gap: 8px;\n}\n"] }]
|
|
383
|
+
}], null, { SourceID: [{
|
|
384
|
+
type: Input
|
|
385
|
+
}], SampleSize: [{
|
|
386
|
+
type: Input
|
|
387
|
+
}], ParentTagID: [{
|
|
388
|
+
type: Input
|
|
389
|
+
}], Accepted: [{
|
|
390
|
+
type: Output
|
|
391
|
+
}] }); })();
|
|
392
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ClassifySeedTaxonomyComponent, { className: "ClassifySeedTaxonomyComponent", filePath: "src/AI/components/autotagging/components/classify-seed-taxonomy.component.ts", lineNumber: 45 }); })();
|
|
393
|
+
//# sourceMappingURL=classify-seed-taxonomy.component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"classify-seed-taxonomy.component.js","sourceRoot":"","sources":["../../../../../src/AI/components/autotagging/components/classify-seed-taxonomy.component.ts","../../../../../src/AI/components/autotagging/components/classify-seed-taxonomy.component.html"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Classify · Seed-taxonomy review.\n *\n * Calls the server-side `GenerateSeedTaxonomy` GraphQL mutation (which samples a\n * source's content and proposes a tag tree), renders the proposal as a checkbox\n * tree with inline rename, and — on Accept — persists the selected nodes as\n * `MJ: Tags` (parent/child wired via ParentID). Used standalone on the Tags /\n * Taxonomy area and embedded inside the setup wizard's Taxonomy step.\n *\n * The mutation is invoked through the first-class transport helper\n * `GraphQLClassifyClient` (constructed from the threaded `ProviderToUse`,\n * narrowed to the concrete `GraphQLDataProvider` it is at runtime), which\n * returns a strongly-typed `SeedTaxonomyResult` — no inline GraphQL or manual\n * JSON parsing in the component.\n */\nimport { Component, ChangeDetectorRef, EventEmitter, Input, Output, inject } from '@angular/core';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { MJNotificationService } from '@memberjunction/ng-notifications';\nimport { MJTagEntity } from '@memberjunction/core-entities';\nimport { TagEngineBase } from '@memberjunction/tag-engine-base';\nimport {\n GraphQLClassifyClient,\n GraphQLDataProvider,\n SeedTaxonomyNode as SeedTaxonomyNodeDTO,\n} from '@memberjunction/graphql-dataprovider';\n\n/** Editable view-model node — adds selection + rename + a stable key for tracking. */\nexport interface SeedTaxonomyNode {\n Key: string;\n Name: string;\n Description?: string;\n MemberCount?: number;\n Selected: boolean;\n Renaming: boolean;\n Depth: number;\n Children: SeedTaxonomyNode[];\n}\n\n@Component({\n standalone: false,\n selector: 'classify-seed-taxonomy',\n templateUrl: './classify-seed-taxonomy.component.html',\n styleUrls: ['./classify-seed-taxonomy.component.css']\n})\nexport class ClassifySeedTaxonomyComponent extends BaseAngularComponent {\n private cdr = inject(ChangeDetectorRef);\n\n /** The content source to sample for the taxonomy proposal. */\n @Input() SourceID: string | null = null;\n /** How many items to sample (passed to the mutation). */\n @Input() SampleSize = 50;\n /** Optional parent tag ID under which accepted root nodes are created. */\n @Input() ParentTagID: string | null = null;\n\n /** Emitted after Accept persists tags, with the count created. */\n @Output() Accepted = new EventEmitter<{ Created: number }>();\n\n public IsGenerating = false;\n public IsAccepting = false;\n public ProposedNodes: SeedTaxonomyNode[] = [];\n public HasGenerated = false;\n public LastMethod: string | null = null;\n public LastSampleSize: number | null = null;\n\n private keySeq = 0;\n\n /** True when at least one node is checked. */\n public get HasSelection(): boolean {\n return this.countSelected(this.ProposedNodes) > 0;\n }\n\n /** Count of currently-selected nodes (template-facing). */\n public get SelectedCount(): number {\n return this.countSelected(this.ProposedNodes);\n }\n\n private countSelected(nodes: SeedTaxonomyNode[]): number {\n let n = 0;\n for (const node of nodes) {\n if (node.Selected) n++;\n n += this.countSelected(node.Children);\n }\n return n;\n }\n\n /** Call the GenerateSeedTaxonomy mutation and render the proposal. */\n public async Generate(): Promise<void> {\n if (this.IsGenerating) return;\n if (!this.SourceID) {\n MJNotificationService.Instance.CreateSimpleNotification('Select a source first.', 'warning', 3000);\n return;\n }\n this.IsGenerating = true;\n this.cdr.detectChanges();\n\n try {\n const client = new GraphQLClassifyClient(this.ProviderToUse as GraphQLDataProvider);\n const result = await client.GenerateSeedTaxonomy({\n SourceID: this.SourceID,\n SampleSize: this.SampleSize,\n });\n\n if (!result.Success) {\n MJNotificationService.Instance.CreateSimpleNotification(\n `Failed to generate taxonomy: ${result.ErrorMessage ?? 'Unknown error'}`, 'error', 5000\n );\n return;\n }\n\n this.LastMethod = result.Method ?? null;\n this.LastSampleSize = result.SampleSize;\n this.ProposedNodes = this.toViewModel(result.Nodes, 0);\n this.HasGenerated = true;\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n MJNotificationService.Instance.CreateSimpleNotification(`Error: ${msg}`, 'error', 5000);\n } finally {\n this.IsGenerating = false;\n this.cdr.detectChanges();\n }\n }\n\n private toViewModel(nodes: SeedTaxonomyNodeDTO[], depth: number): SeedTaxonomyNode[] {\n return nodes.map(n => ({\n Key: `n${this.keySeq++}`,\n Name: n.Name ?? '(unnamed)',\n Description: n.Description,\n MemberCount: n.MemberCount,\n Selected: true,\n Renaming: false,\n Depth: depth,\n Children: this.toViewModel(n.Children ?? [], depth + 1),\n }));\n }\n\n // ── Tree interactions ──\n\n /** Toggle a node's selection, cascading to descendants. */\n public ToggleNode(node: SeedTaxonomyNode): void {\n const next = !node.Selected;\n this.setSelectedRecursive(node, next);\n this.cdr.detectChanges();\n }\n\n private setSelectedRecursive(node: SeedTaxonomyNode, value: boolean): void {\n node.Selected = value;\n for (const child of node.Children) this.setSelectedRecursive(child, value);\n }\n\n public StartRename(node: SeedTaxonomyNode): void {\n node.Renaming = true;\n this.cdr.detectChanges();\n }\n\n public CommitRename(node: SeedTaxonomyNode, value: string): void {\n const trimmed = value.trim();\n if (trimmed) node.Name = trimmed;\n node.Renaming = false;\n this.cdr.detectChanges();\n }\n\n /** Flatten the visible tree for the template (depth-first), preserving order. */\n public get FlatNodes(): SeedTaxonomyNode[] {\n const out: SeedTaxonomyNode[] = [];\n const walk = (nodes: SeedTaxonomyNode[]) => {\n for (const n of nodes) {\n out.push(n);\n walk(n.Children);\n }\n };\n walk(this.ProposedNodes);\n return out;\n }\n\n // ── Accept → persist as MJ: Tags ──\n\n /**\n * Persist every selected node as an `MJ: Tags` record. Parent/child links use\n * ParentID; root nodes use the optional ParentTagID input. Walks the tree\n * top-down so a parent's saved ID is available when creating its children.\n */\n public async AcceptSelected(): Promise<void> {\n if (this.IsAccepting) return;\n if (!this.HasSelection) {\n MJNotificationService.Instance.CreateSimpleNotification('Select at least one tag to accept.', 'warning', 3000);\n return;\n }\n this.IsAccepting = true;\n this.cdr.detectChanges();\n\n let created = 0;\n try {\n const p = this.ProviderToUse;\n const persistLevel = async (nodes: SeedTaxonomyNode[], parentID: string | null): Promise<void> => {\n for (const node of nodes) {\n let savedID: string | null = parentID;\n if (node.Selected) {\n const tag = await p.GetEntityObject<MJTagEntity>('MJ: Tags', p.CurrentUser);\n tag.NewRecord();\n tag.Name = node.Name;\n tag.DisplayName = node.Name;\n if (node.Description) tag.Description = node.Description;\n tag.ParentID = parentID;\n tag.Status = 'Active';\n const ok = await tag.Save();\n if (ok) {\n created++;\n savedID = tag.ID;\n } else {\n const detail = tag.LatestResult?.CompleteMessage ?? 'Unknown error';\n MJNotificationService.Instance.CreateSimpleNotification(\n `Failed to save tag \"${node.Name}\": ${detail}`, 'error', 5000\n );\n // Children still attach to the original parent so the tree isn't orphaned.\n savedID = parentID;\n }\n }\n // Recurse: children of an unselected node attach to the nearest selected ancestor.\n await persistLevel(node.Children, savedID);\n }\n };\n\n await persistLevel(this.ProposedNodes, this.ParentTagID);\n\n // Refresh the tag cache so other views see the new tags.\n await TagEngineBase.Instance.Config(true, p.CurrentUser, p);\n\n MJNotificationService.Instance.CreateSimpleNotification(\n `Created ${created} tag${created === 1 ? '' : 's'}`, 'success', 3000\n );\n this.Accepted.emit({ Created: created });\n this.ProposedNodes = [];\n this.HasGenerated = false;\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n MJNotificationService.Instance.CreateSimpleNotification(`Error: ${msg}`, 'error', 5000);\n } finally {\n this.IsAccepting = false;\n this.cdr.detectChanges();\n }\n }\n}\n","<div class=\"cls-seed\">\n <div class=\"cls-seed-bar\">\n <button mjButton variant=\"primary\" size=\"sm\" (click)=\"Generate()\" [disabled]=\"IsGenerating || !SourceID\">\n @if (IsGenerating) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Generating…\n } @else if (HasGenerated) {\n <i class=\"fa-solid fa-rotate\"></i> Generate again\n } @else {\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i> Generate seed taxonomy\n }\n </button>\n @if (HasGenerated) {\n <span class=\"cls-seed-meta\">\n {{ SelectedCount }} selected\n @if (LastMethod) { · {{ LastMethod }} }\n @if (LastSampleSize != null) { · sampled {{ LastSampleSize }} }\n </span>\n }\n </div>\n\n @if (IsGenerating) {\n <div class=\"cls-seed-loading\">\n <mj-loading text=\"Sampling content and proposing tags…\"></mj-loading>\n </div>\n } @else if (HasGenerated) {\n @if (FlatNodes.length === 0) {\n @if (LastSampleSize === 0) {\n <div class=\"cls-seed-empty\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n No content sampled — this source has no ingested content items yet.\n Add content (crawl & vectorize the source) first, then generate a\n taxonomy, or skip this step and define the taxonomy later.\n </div>\n } @else {\n <div class=\"cls-seed-empty\">\n <i class=\"fa-solid fa-circle-info\"></i>\n The model proposed no tags from the sampled content. Try generating again,\n or skip this step and define the taxonomy later.\n </div>\n }\n } @else {\n <div class=\"cls-seed-tree\">\n @for (node of FlatNodes; track node.Key) {\n <div class=\"cls-seed-row\" [style.padding-left.px]=\"12 + node.Depth * 20\">\n <input type=\"checkbox\" [checked]=\"node.Selected\" (change)=\"ToggleNode(node)\">\n @if (node.Renaming) {\n <input #renameInput type=\"text\" class=\"mj-input cls-seed-rename\" [value]=\"node.Name\"\n (blur)=\"CommitRename(node, renameInput.value)\"\n (keyup.enter)=\"CommitRename(node, renameInput.value)\">\n } @else {\n <span class=\"cls-seed-name\" (click)=\"StartRename(node)\" title=\"Click to rename\">{{ node.Name }}</span>\n @if (node.MemberCount != null) {\n <span class=\"cls-seed-count\">{{ node.MemberCount }}</span>\n }\n <button class=\"cls-seed-rename-btn\" (click)=\"StartRename(node)\" aria-label=\"Rename\">\n <i class=\"fa-solid fa-pen\"></i>\n </button>\n }\n </div>\n }\n </div>\n\n <div class=\"cls-seed-actions\">\n <button mjButton variant=\"primary\" size=\"sm\" (click)=\"AcceptSelected()\"\n [disabled]=\"IsAccepting || !HasSelection\">\n @if (IsAccepting) { <i class=\"fa-solid fa-spinner fa-spin\"></i> Saving… }\n @else { <i class=\"fa-solid fa-check\"></i> Accept selected ({{ SelectedCount }}) }\n </button>\n <button mjButton variant=\"secondary\" size=\"sm\" (click)=\"Generate()\" [disabled]=\"IsGenerating\">\n <i class=\"fa-solid fa-rotate\"></i> Generate again\n </button>\n </div>\n }\n }\n</div>\n"]}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Classify · Guided source setup wizard.
|
|
3
|
+
*
|
|
4
|
+
* A multi-step `mj-dialog` that walks an operator through standing up a new
|
|
5
|
+
* content source: Source Type → Entity → Entity Document → Content Type →
|
|
6
|
+
* Taxonomy Strategy → Domain Context → Review & Create. Steps whose prerequisite
|
|
7
|
+
* already exists (e.g. a content type is already configured, or the chosen
|
|
8
|
+
* entity already has an Entity Document) are auto-skipped.
|
|
9
|
+
*
|
|
10
|
+
* The wizard reuses the inline Entity Document create and the seed-taxonomy
|
|
11
|
+
* review components, and the domain-context fields. It owns no business logic
|
|
12
|
+
* beyond assembling the records — persistence is via the entity API
|
|
13
|
+
* (`GetEntityObject` + `Save()` with result checking) threaded through
|
|
14
|
+
* `ProviderToUse`.
|
|
15
|
+
*/
|
|
16
|
+
import { EventEmitter } from '@angular/core';
|
|
17
|
+
import { BaseAngularComponent } from '@memberjunction/ng-base-types';
|
|
18
|
+
import { DropdownOption } from '../shared/classify.types';
|
|
19
|
+
import { ClassificationContextMode } from './source-type-form.dialog.component';
|
|
20
|
+
import * as i0 from "@angular/core";
|
|
21
|
+
/** The ordered wizard steps. Some are conditionally skipped at run time. */
|
|
22
|
+
type WizardStep = 'source-type' | 'entity' | 'entity-doc' | 'content-type' | 'taxonomy' | 'domain-context' | 'review';
|
|
23
|
+
export declare class ClassifySetupWizardComponent extends BaseAngularComponent {
|
|
24
|
+
private cdr;
|
|
25
|
+
/** Emitted after the wizard creates a source, so the host reloads. */
|
|
26
|
+
Created: EventEmitter<{
|
|
27
|
+
SourceID: string;
|
|
28
|
+
}>;
|
|
29
|
+
/** Emitted when the wizard is dismissed without creating anything. */
|
|
30
|
+
Cancelled: EventEmitter<void>;
|
|
31
|
+
Visible: boolean;
|
|
32
|
+
CurrentStep: WizardStep;
|
|
33
|
+
Saving: boolean;
|
|
34
|
+
SourceName: string;
|
|
35
|
+
SourceTypeID: string;
|
|
36
|
+
EntityID: string;
|
|
37
|
+
EntityDocID: string;
|
|
38
|
+
ContentTypeID: string;
|
|
39
|
+
SourceURL: string;
|
|
40
|
+
ClassificationContext: string;
|
|
41
|
+
ClassificationContextMode: ClassificationContextMode;
|
|
42
|
+
SourceTypeOptions: DropdownOption[];
|
|
43
|
+
ContentTypeOptions: DropdownOption[];
|
|
44
|
+
EntityOptions: {
|
|
45
|
+
ID: string;
|
|
46
|
+
Name: string;
|
|
47
|
+
}[];
|
|
48
|
+
/** A pending source ID is created up-front when we reach the taxonomy step so
|
|
49
|
+
* the embedded seed-taxonomy generator has a real source to sample. */
|
|
50
|
+
PendingSourceID: string | null;
|
|
51
|
+
get IsSubstitutiveMode(): boolean;
|
|
52
|
+
set IsSubstitutiveMode(v: boolean);
|
|
53
|
+
Open(): Promise<void>;
|
|
54
|
+
Close(): void;
|
|
55
|
+
private resetState;
|
|
56
|
+
private loadOptions;
|
|
57
|
+
/** Whether the selected source type is the Entity type (name-based check). */
|
|
58
|
+
get IsEntitySource(): boolean;
|
|
59
|
+
/** EntityInfo for the selected entity, or null. */
|
|
60
|
+
private get selectedEntityInfo();
|
|
61
|
+
get SelectedEntityName(): string;
|
|
62
|
+
/** True when the selected entity has no active Entity Document. */
|
|
63
|
+
get SelectedEntityHasNoDocument(): boolean;
|
|
64
|
+
/** Whether any content type exists (drives the content-type step skip). */
|
|
65
|
+
get HasAnyContentType(): boolean;
|
|
66
|
+
/**
|
|
67
|
+
* The ordered list of steps relevant to the current selections. Steps whose
|
|
68
|
+
* prerequisite already exists are filtered out, so the progress UI + next/back
|
|
69
|
+
* navigation only ever traverse meaningful steps.
|
|
70
|
+
*/
|
|
71
|
+
get ActiveSteps(): WizardStep[];
|
|
72
|
+
get StepIndex(): number;
|
|
73
|
+
get TotalSteps(): number;
|
|
74
|
+
get StepLabel(): string;
|
|
75
|
+
get CanGoNext(): boolean;
|
|
76
|
+
get IsLastStep(): boolean;
|
|
77
|
+
Next(): Promise<void>;
|
|
78
|
+
Back(): void;
|
|
79
|
+
EntityDocSaving: boolean;
|
|
80
|
+
NewEntityDocName: string;
|
|
81
|
+
NewEntityDocSelectedFields: Record<string, boolean>;
|
|
82
|
+
/** Fields of the selected entity, for the field-picker in the inline create. */
|
|
83
|
+
get SelectedEntityFields(): {
|
|
84
|
+
Name: string;
|
|
85
|
+
DisplayName: string;
|
|
86
|
+
}[];
|
|
87
|
+
get SelectedEntityDocFieldCount(): number;
|
|
88
|
+
/** Prime the inline-create defaults when entering the entity-doc step. */
|
|
89
|
+
PrimeEntityDocDefaults(): void;
|
|
90
|
+
/** Create the Entity Document for the selected entity, then refresh + select it. */
|
|
91
|
+
CreateEntityDocument(): Promise<void>;
|
|
92
|
+
/** Called by the embedded seed-taxonomy after it persists tags. */
|
|
93
|
+
OnTaxonomyAccepted(_event: {
|
|
94
|
+
Created: number;
|
|
95
|
+
}): void;
|
|
96
|
+
/**
|
|
97
|
+
* Create (once) the content source record so the taxonomy step can sample it.
|
|
98
|
+
* Subsequent edits (domain context) are applied to this same record on Finish.
|
|
99
|
+
*/
|
|
100
|
+
private ensurePendingSource;
|
|
101
|
+
/**
|
|
102
|
+
* Create or update the content source from the collected selections. Returns
|
|
103
|
+
* the saved ID, or null on failure. Defaults required NOT NULL columns for
|
|
104
|
+
* entity sources the same way the quick-edit form does.
|
|
105
|
+
*/
|
|
106
|
+
private saveSource;
|
|
107
|
+
/** Resolve the entity document ID to store (explicit choice or the entity's only doc). */
|
|
108
|
+
private resolveEntityDocID;
|
|
109
|
+
/** Finish the wizard: persist the (final) source and emit Created. */
|
|
110
|
+
Finish(): Promise<void>;
|
|
111
|
+
get EntityDocOptions(): {
|
|
112
|
+
ID: string;
|
|
113
|
+
Name: string;
|
|
114
|
+
}[];
|
|
115
|
+
get SourceTypeName(): string;
|
|
116
|
+
get ContentTypeName(): string;
|
|
117
|
+
get EntityDocName(): string;
|
|
118
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ClassifySetupWizardComponent, never>;
|
|
119
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<ClassifySetupWizardComponent, "classify-setup-wizard", never, {}, { "Created": "Created"; "Cancelled": "Cancelled"; }, never, never, false, never>;
|
|
120
|
+
}
|
|
121
|
+
export {};
|
|
122
|
+
//# sourceMappingURL=classify-setup-wizard.component.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"classify-setup-wizard.component.d.ts","sourceRoot":"","sources":["../../../../../src/AI/components/autotagging/dialogs/classify-setup-wizard.component.ts"],"names":[],"mappings":"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"}
|