@memberjunction/ng-dashboards 6.2.0-edge.4 → 6.2.0-edge.5
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/vectors/sensitive-fields.d.ts +53 -0
- package/dist/AI/components/vectors/sensitive-fields.d.ts.map +1 -0
- package/dist/AI/components/vectors/sensitive-fields.js +226 -0
- package/dist/AI/components/vectors/sensitive-fields.js.map +1 -0
- package/dist/AI/components/vectors/vector-document-rules.d.ts +126 -0
- package/dist/AI/components/vectors/vector-document-rules.d.ts.map +1 -0
- package/dist/AI/components/vectors/vector-document-rules.js +168 -0
- package/dist/AI/components/vectors/vector-document-rules.js.map +1 -0
- package/dist/AI/components/vectors/vector-management-resource.component.d.ts +49 -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 +428 -230
- package/dist/AI/components/vectors/vector-management-resource.component.js.map +1 -1
- package/dist/Communication/communication-agent-context.d.ts +11 -1
- package/dist/Communication/communication-agent-context.d.ts.map +1 -1
- package/dist/Communication/communication-agent-context.js +15 -0
- package/dist/Communication/communication-agent-context.js.map +1 -1
- package/dist/Communication/communication-dashboard.component.d.ts.map +1 -1
- package/dist/Communication/communication-dashboard.component.js +5 -0
- package/dist/Communication/communication-dashboard.component.js.map +1 -1
- package/dist/Communication/communication-providers-resource.component.d.ts +27 -1
- package/dist/Communication/communication-providers-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-providers-resource.component.js +722 -78
- package/dist/Communication/communication-providers-resource.component.js.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +25 -0
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.js +74 -5
- package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
- package/dist/DevTools/app-state-inspector.component.d.ts.map +1 -1
- package/dist/DevTools/app-state-inspector.component.js +1 -0
- package/dist/DevTools/app-state-inspector.component.js.map +1 -1
- package/dist/DevTools/class-registry.component.d.ts.map +1 -1
- package/dist/DevTools/class-registry.component.js +1 -0
- package/dist/DevTools/class-registry.component.js.map +1 -1
- package/dist/DevTools/event-monitor.component.d.ts.map +1 -1
- package/dist/DevTools/event-monitor.component.js +2 -0
- package/dist/DevTools/event-monitor.component.js.map +1 -1
- package/dist/DevTools/graphql-console.component.d.ts.map +1 -1
- package/dist/DevTools/graphql-console.component.js.map +1 -1
- package/dist/DevTools/grid-width-lab.component.d.ts.map +1 -1
- package/dist/DevTools/grid-width-lab.component.js +1 -0
- package/dist/DevTools/grid-width-lab.component.js.map +1 -1
- package/dist/DevTools/layout-inspector.component.d.ts.map +1 -1
- package/dist/DevTools/layout-inspector.component.js +1 -0
- package/dist/DevTools/layout-inspector.component.js.map +1 -1
- package/dist/DevTools/lazy-module-status.component.d.ts.map +1 -1
- package/dist/DevTools/lazy-module-status.component.js +1 -0
- package/dist/DevTools/lazy-module-status.component.js.map +1 -1
- package/dist/DevTools/settings-explorer.component.d.ts.map +1 -1
- package/dist/DevTools/settings-explorer.component.js +1 -0
- package/dist/DevTools/settings-explorer.component.js.map +1 -1
- package/dist/DevTools/tab-strip-lab.component.d.ts.map +1 -1
- package/dist/DevTools/tab-strip-lab.component.js +1 -0
- package/dist/DevTools/tab-strip-lab.component.js.map +1 -1
- package/dist/EntityAdmin/entity-admin-dashboard.component.d.ts +5 -0
- package/dist/EntityAdmin/entity-admin-dashboard.component.d.ts.map +1 -1
- package/dist/EntityAdmin/entity-admin-dashboard.component.js +8 -5
- package/dist/EntityAdmin/entity-admin-dashboard.component.js.map +1 -1
- package/dist/Integration/components/overview/overview.component.js +2 -2
- package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js +2 -2
- package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js.map +1 -1
- package/dist/KnowledgeHub/components/feature-pipelines/feature-pipeline.engine.d.ts +11 -1
- package/dist/KnowledgeHub/components/feature-pipelines/feature-pipeline.engine.d.ts.map +1 -1
- package/dist/KnowledgeHub/components/feature-pipelines/feature-pipeline.engine.js +24 -2
- package/dist/KnowledgeHub/components/feature-pipelines/feature-pipeline.engine.js.map +1 -1
- package/dist/KnowledgeHub/components/feature-pipelines/feature-pipelines-resource.component.d.ts +16 -2
- package/dist/KnowledgeHub/components/feature-pipelines/feature-pipelines-resource.component.d.ts.map +1 -1
- package/dist/KnowledgeHub/components/feature-pipelines/feature-pipelines-resource.component.js +87 -33
- package/dist/KnowledgeHub/components/feature-pipelines/feature-pipelines-resource.component.js.map +1 -1
- package/dist/LoginStudio/login-studio-inspector.component.d.ts +130 -0
- package/dist/LoginStudio/login-studio-inspector.component.d.ts.map +1 -0
- package/dist/LoginStudio/login-studio-inspector.component.js +781 -0
- package/dist/LoginStudio/login-studio-inspector.component.js.map +1 -0
- package/dist/LoginStudio/login-studio-resource.component.d.ts +153 -0
- package/dist/LoginStudio/login-studio-resource.component.d.ts.map +1 -0
- package/dist/LoginStudio/login-studio-resource.component.js +857 -0
- package/dist/LoginStudio/login-studio-resource.component.js.map +1 -0
- package/dist/Workflows/components/workflow-runs-resource.component.js +4 -4
- package/dist/Workflows/components/workflow-runs-resource.component.js.map +1 -1
- package/dist/core-dashboards.module.d.ts +2 -1
- package/dist/core-dashboards.module.d.ts.map +1 -1
- package/dist/core-dashboards.module.js +11 -3
- package/dist/core-dashboards.module.js.map +1 -1
- package/dist/public-api.d.ts +1 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +1 -0
- package/dist/public-api.js.map +1 -1
- package/package.json +72 -69
|
@@ -17,7 +17,7 @@ import { Subject } from 'rxjs';
|
|
|
17
17
|
import { takeUntil } from 'rxjs/operators';
|
|
18
18
|
import { RunView } from '@memberjunction/core';
|
|
19
19
|
import { KnowledgeHubMetadataEngine } from '@memberjunction/core-entities';
|
|
20
|
-
import { RegisterClass, UUIDsEqual } from '@memberjunction/global';
|
|
20
|
+
import { RegisterClass, UUIDsEqual, EscapeSQLString } from '@memberjunction/global';
|
|
21
21
|
import { BaseResourceComponent, NavigationService, ActivityService } from '@memberjunction/ng-shared';
|
|
22
22
|
import { GraphQLAIClient } from '@memberjunction/graphql-dataprovider';
|
|
23
23
|
import { AIEngineBase } from '@memberjunction/ai-engine-base';
|
|
@@ -27,6 +27,8 @@ import { CronToHumanReadable } from '../autotagging/shared/classify.format';
|
|
|
27
27
|
import { BuildAutoVectorIndexName, FindMatchingVectorIndex } from './vector-index-auto';
|
|
28
28
|
import { BuildVectorAgentContext, ResolveSyncRow, } from './vector-management-agent-context';
|
|
29
29
|
import { ValidateStringParam } from '../../../shared/agent-tool-validation';
|
|
30
|
+
import { WithoutSensitiveFields, SensitiveFieldsInTemplate } from './sensitive-fields';
|
|
31
|
+
import { ENTITY_DOCUMENT_TYPE_BY_USE_CASE, MAX_TEMPLATE_FIELDS, CapSelectedFields, EntityDocumentTypeForUseCase, SuggestionUseCaseForDocumentType, IsVectorizableEntity, TemplateFieldCapRefusal, } from './vector-document-rules';
|
|
30
32
|
import * as i0 from "@angular/core";
|
|
31
33
|
import * as i1 from "@angular/common";
|
|
32
34
|
import * as i2 from "@angular/forms";
|
|
@@ -85,31 +87,31 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_For_3_Tem
|
|
|
85
87
|
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_18_Template(rf, ctx) { if (rf & 1) {
|
|
86
88
|
i0.ɵɵelement(0, "mj-empty-state", 23);
|
|
87
89
|
} }
|
|
88
|
-
function
|
|
90
|
+
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_19_For_20_Conditional_15_Template(rf, ctx) { if (rf & 1) {
|
|
89
91
|
i0.ɵɵtext(0);
|
|
90
92
|
} if (rf & 2) {
|
|
91
93
|
const row_r7 = i0.ɵɵnextContext().$implicit;
|
|
92
94
|
i0.ɵɵtextInterpolate1(" ", row_r7.PercentComplete, "% ");
|
|
93
95
|
} }
|
|
94
|
-
function
|
|
96
|
+
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_19_For_20_Conditional_16_Template(rf, ctx) { if (rf & 1) {
|
|
95
97
|
i0.ɵɵtext(0);
|
|
96
98
|
} if (rf & 2) {
|
|
97
99
|
const row_r7 = i0.ɵɵnextContext().$implicit;
|
|
98
100
|
i0.ɵɵtextInterpolate1(" ", row_r7.Status, " ");
|
|
99
101
|
} }
|
|
100
|
-
function
|
|
101
|
-
i0.ɵɵelement(0, "i",
|
|
102
|
+
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_19_For_20_Conditional_19_Template(rf, ctx) { if (rf & 1) {
|
|
103
|
+
i0.ɵɵelement(0, "i", 61);
|
|
102
104
|
i0.ɵɵtext(1);
|
|
103
105
|
} if (rf & 2) {
|
|
104
106
|
const row_r7 = i0.ɵɵnextContext().$implicit;
|
|
105
107
|
i0.ɵɵadvance();
|
|
106
108
|
i0.ɵɵtextInterpolate1(" ", row_r7.PercentComplete > 0 ? row_r7.PercentComplete + "%" : "Sync", " ");
|
|
107
109
|
} }
|
|
108
|
-
function
|
|
109
|
-
i0.ɵɵelement(0, "i",
|
|
110
|
+
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_19_For_20_Conditional_20_Template(rf, ctx) { if (rf & 1) {
|
|
111
|
+
i0.ɵɵelement(0, "i", 62);
|
|
110
112
|
i0.ɵɵtext(1, " Sync ");
|
|
111
113
|
} }
|
|
112
|
-
function
|
|
114
|
+
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_19_For_20_Template(rf, ctx) { if (rf & 1) {
|
|
113
115
|
const _r6 = i0.ɵɵgetCurrentView();
|
|
114
116
|
i0.ɵɵelementStart(0, "tr")(1, "td", 49);
|
|
115
117
|
i0.ɵɵtext(2);
|
|
@@ -119,26 +121,29 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
119
121
|
i0.ɵɵelementEnd();
|
|
120
122
|
i0.ɵɵelementStart(5, "td", 51);
|
|
121
123
|
i0.ɵɵtext(6);
|
|
122
|
-
i0.ɵɵpipe(7, "number");
|
|
123
124
|
i0.ɵɵelementEnd();
|
|
124
|
-
i0.ɵɵelementStart(
|
|
125
|
-
i0.ɵɵtext(
|
|
125
|
+
i0.ɵɵelementStart(7, "td", 52);
|
|
126
|
+
i0.ɵɵtext(8);
|
|
127
|
+
i0.ɵɵpipe(9, "number");
|
|
128
|
+
i0.ɵɵelementEnd();
|
|
129
|
+
i0.ɵɵelementStart(10, "td", 53);
|
|
130
|
+
i0.ɵɵtext(11);
|
|
126
131
|
i0.ɵɵelementEnd();
|
|
127
|
-
i0.ɵɵelementStart(
|
|
128
|
-
i0.ɵɵelement(
|
|
129
|
-
i0.ɵɵconditionalCreate(
|
|
132
|
+
i0.ɵɵelementStart(12, "td")(13, "span", 54);
|
|
133
|
+
i0.ɵɵelement(14, "i");
|
|
134
|
+
i0.ɵɵconditionalCreate(15, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_19_For_20_Conditional_15_Template, 1, 1)(16, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_19_For_20_Conditional_16_Template, 1, 1);
|
|
130
135
|
i0.ɵɵelementEnd()();
|
|
131
|
-
i0.ɵɵelementStart(
|
|
132
|
-
i0.ɵɵlistener("click", function
|
|
133
|
-
i0.ɵɵconditionalCreate(
|
|
136
|
+
i0.ɵɵelementStart(17, "td", 55)(18, "button", 56);
|
|
137
|
+
i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_19_For_20_Template_button_click_18_listener() { const row_r7 = i0.ɵɵrestoreView(_r6).$implicit; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.SyncEntity(row_r7.EntityDocumentID)); });
|
|
138
|
+
i0.ɵɵconditionalCreate(19, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_19_For_20_Conditional_19_Template, 2, 1)(20, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_19_For_20_Conditional_20_Template, 2, 0);
|
|
134
139
|
i0.ɵɵelementEnd();
|
|
135
|
-
i0.ɵɵelementStart(
|
|
136
|
-
i0.ɵɵlistener("click", function
|
|
137
|
-
i0.ɵɵelement(
|
|
140
|
+
i0.ɵɵelementStart(21, "button", 57);
|
|
141
|
+
i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_19_For_20_Template_button_click_21_listener() { const row_r7 = i0.ɵɵrestoreView(_r6).$implicit; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.OpenScheduleSyncDialog(row_r7.EntityDocumentID)); });
|
|
142
|
+
i0.ɵɵelement(22, "i", 58);
|
|
138
143
|
i0.ɵɵelementEnd();
|
|
139
|
-
i0.ɵɵelementStart(
|
|
140
|
-
i0.ɵɵlistener("click", function
|
|
141
|
-
i0.ɵɵelement(
|
|
144
|
+
i0.ɵɵelementStart(23, "button", 59);
|
|
145
|
+
i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_19_For_20_Template_button_click_23_listener() { const row_r7 = i0.ɵɵrestoreView(_r6).$implicit; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.OpenEditPanel(row_r7.EntityDocumentID)); });
|
|
146
|
+
i0.ɵɵelement(24, "i", 60);
|
|
142
147
|
i0.ɵɵelementEnd()()();
|
|
143
148
|
} if (rf & 2) {
|
|
144
149
|
const row_r7 = ctx.$implicit;
|
|
@@ -148,7 +153,9 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
148
153
|
i0.ɵɵadvance(2);
|
|
149
154
|
i0.ɵɵtextInterpolate(row_r7.DocumentName);
|
|
150
155
|
i0.ɵɵadvance(2);
|
|
151
|
-
i0.ɵɵtextInterpolate(
|
|
156
|
+
i0.ɵɵtextInterpolate(row_r7.DocumentType);
|
|
157
|
+
i0.ɵɵadvance(2);
|
|
158
|
+
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind1(9, 12, row_r7.VectorCount));
|
|
152
159
|
i0.ɵɵadvance(3);
|
|
153
160
|
i0.ɵɵtextInterpolate(ctx_r1.FormatDate(row_r7.LastSynced));
|
|
154
161
|
i0.ɵɵadvance(2);
|
|
@@ -156,11 +163,11 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
156
163
|
i0.ɵɵadvance();
|
|
157
164
|
i0.ɵɵclassMap(ctx_r1.GetStatusIcon(row_r7.Status));
|
|
158
165
|
i0.ɵɵadvance();
|
|
159
|
-
i0.ɵɵconditional(row_r7.Status === "Syncing" && row_r7.PercentComplete > 0 ?
|
|
166
|
+
i0.ɵɵconditional(row_r7.Status === "Syncing" && row_r7.PercentComplete > 0 ? 15 : 16);
|
|
160
167
|
i0.ɵɵadvance(3);
|
|
161
168
|
i0.ɵɵproperty("disabled", ctx_r1.IsSyncing(row_r7.EntityDocumentID));
|
|
162
169
|
i0.ɵɵadvance();
|
|
163
|
-
i0.ɵɵconditional(ctx_r1.IsSyncing(row_r7.EntityDocumentID) ?
|
|
170
|
+
i0.ɵɵconditional(ctx_r1.IsSyncing(row_r7.EntityDocumentID) ? 19 : 20);
|
|
164
171
|
} }
|
|
165
172
|
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_19_Template(rf, ctx) { if (rf & 1) {
|
|
166
173
|
i0.ɵɵelementStart(0, "div", 24)(1, "table", 46)(2, "thead")(3, "tr")(4, "th");
|
|
@@ -169,24 +176,27 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
169
176
|
i0.ɵɵelementStart(6, "th");
|
|
170
177
|
i0.ɵɵtext(7, "Document");
|
|
171
178
|
i0.ɵɵelementEnd();
|
|
172
|
-
i0.ɵɵelementStart(8, "th"
|
|
173
|
-
i0.ɵɵtext(9, "
|
|
179
|
+
i0.ɵɵelementStart(8, "th");
|
|
180
|
+
i0.ɵɵtext(9, "Type");
|
|
174
181
|
i0.ɵɵelementEnd();
|
|
175
|
-
i0.ɵɵelementStart(10, "th");
|
|
176
|
-
i0.ɵɵtext(11, "
|
|
182
|
+
i0.ɵɵelementStart(10, "th", 47);
|
|
183
|
+
i0.ɵɵtext(11, "Vectors");
|
|
177
184
|
i0.ɵɵelementEnd();
|
|
178
185
|
i0.ɵɵelementStart(12, "th");
|
|
179
|
-
i0.ɵɵtext(13, "
|
|
186
|
+
i0.ɵɵtext(13, "Last Synced");
|
|
187
|
+
i0.ɵɵelementEnd();
|
|
188
|
+
i0.ɵɵelementStart(14, "th");
|
|
189
|
+
i0.ɵɵtext(15, "Status");
|
|
180
190
|
i0.ɵɵelementEnd();
|
|
181
|
-
i0.ɵɵelementStart(
|
|
182
|
-
i0.ɵɵtext(
|
|
191
|
+
i0.ɵɵelementStart(16, "th", 48);
|
|
192
|
+
i0.ɵɵtext(17, "Actions");
|
|
183
193
|
i0.ɵɵelementEnd()()();
|
|
184
|
-
i0.ɵɵelementStart(
|
|
185
|
-
i0.ɵɵrepeaterCreate(
|
|
194
|
+
i0.ɵɵelementStart(18, "tbody");
|
|
195
|
+
i0.ɵɵrepeaterCreate(19, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_19_For_20_Template, 25, 14, "tr", null, _forTrack1);
|
|
186
196
|
i0.ɵɵelementEnd()()();
|
|
187
197
|
} if (rf & 2) {
|
|
188
198
|
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
189
|
-
i0.ɵɵadvance(
|
|
199
|
+
i0.ɵɵadvance(19);
|
|
190
200
|
i0.ɵɵrepeater(ctx_r1.SyncRows);
|
|
191
201
|
} }
|
|
192
202
|
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_31_Template(rf, ctx) { if (rf & 1) {
|
|
@@ -202,7 +212,7 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
202
212
|
i0.ɵɵelementStart(0, "div", 36)(1, "span", 37);
|
|
203
213
|
i0.ɵɵtext(2, "Dimensions");
|
|
204
214
|
i0.ɵɵelementEnd();
|
|
205
|
-
i0.ɵɵelementStart(3, "span",
|
|
215
|
+
i0.ɵɵelementStart(3, "span", 63);
|
|
206
216
|
i0.ɵɵtext(4);
|
|
207
217
|
i0.ɵɵpipe(5, "number");
|
|
208
218
|
i0.ɵɵelementEnd()();
|
|
@@ -211,16 +221,16 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
211
221
|
i0.ɵɵadvance(4);
|
|
212
222
|
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind1(5, 1, ctx_r1.EmbeddingModel.Dimensions));
|
|
213
223
|
} }
|
|
214
|
-
function
|
|
215
|
-
i0.ɵɵelement(0, "i",
|
|
224
|
+
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_25_Template(rf, ctx) { if (rf & 1) {
|
|
225
|
+
i0.ɵɵelement(0, "i", 61);
|
|
216
226
|
i0.ɵɵtext(1, " Regenerating... ");
|
|
217
227
|
} }
|
|
218
|
-
function
|
|
228
|
+
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_26_Template(rf, ctx) { if (rf & 1) {
|
|
219
229
|
i0.ɵɵelement(0, "i", 19);
|
|
220
230
|
i0.ɵɵtext(1, " Regenerate with AI ");
|
|
221
231
|
} }
|
|
222
|
-
function
|
|
223
|
-
i0.ɵɵelementStart(0, "span",
|
|
232
|
+
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_29_For_5_Template(rf, ctx) { if (rf & 1) {
|
|
233
|
+
i0.ɵɵelementStart(0, "span", 89);
|
|
224
234
|
i0.ɵɵtext(1);
|
|
225
235
|
i0.ɵɵelementEnd();
|
|
226
236
|
} if (rf & 2) {
|
|
@@ -228,20 +238,20 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
228
238
|
i0.ɵɵadvance();
|
|
229
239
|
i0.ɵɵtextInterpolate(field_r9);
|
|
230
240
|
} }
|
|
231
|
-
function
|
|
232
|
-
i0.ɵɵelementStart(0, "div",
|
|
241
|
+
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_29_Template(rf, ctx) { if (rf & 1) {
|
|
242
|
+
i0.ɵɵelementStart(0, "div", 72)(1, "label", 73);
|
|
233
243
|
i0.ɵɵtext(2, "Selected Fields");
|
|
234
244
|
i0.ɵɵelementEnd();
|
|
235
|
-
i0.ɵɵelementStart(3, "div",
|
|
236
|
-
i0.ɵɵrepeaterCreate(4,
|
|
245
|
+
i0.ɵɵelementStart(3, "div", 88);
|
|
246
|
+
i0.ɵɵrepeaterCreate(4, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_29_For_5_Template, 2, 1, "span", 89, i0.ɵɵrepeaterTrackByIdentity);
|
|
237
247
|
i0.ɵɵelementEnd()();
|
|
238
248
|
} if (rf & 2) {
|
|
239
249
|
const ctx_r1 = i0.ɵɵnextContext(4);
|
|
240
250
|
i0.ɵɵadvance(4);
|
|
241
251
|
i0.ɵɵrepeater(ctx_r1.EditDocSelectedFields);
|
|
242
252
|
} }
|
|
243
|
-
function
|
|
244
|
-
i0.ɵɵelementStart(0, "option",
|
|
253
|
+
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_For_39_Template(rf, ctx) { if (rf & 1) {
|
|
254
|
+
i0.ɵɵelementStart(0, "option", 81);
|
|
245
255
|
i0.ɵɵtext(1);
|
|
246
256
|
i0.ɵɵelementEnd();
|
|
247
257
|
} if (rf & 2) {
|
|
@@ -250,8 +260,8 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
250
260
|
i0.ɵɵadvance();
|
|
251
261
|
i0.ɵɵtextInterpolate(model_r10.Name);
|
|
252
262
|
} }
|
|
253
|
-
function
|
|
254
|
-
i0.ɵɵelementStart(0, "option",
|
|
263
|
+
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_For_45_Template(rf, ctx) { if (rf & 1) {
|
|
264
|
+
i0.ɵɵelementStart(0, "option", 81);
|
|
255
265
|
i0.ɵɵtext(1);
|
|
256
266
|
i0.ɵɵelementEnd();
|
|
257
267
|
} if (rf & 2) {
|
|
@@ -260,8 +270,8 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
260
270
|
i0.ɵɵadvance();
|
|
261
271
|
i0.ɵɵtextInterpolate(db_r11.Name);
|
|
262
272
|
} }
|
|
263
|
-
function
|
|
264
|
-
i0.ɵɵelementStart(0, "option",
|
|
273
|
+
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_49_For_4_Template(rf, ctx) { if (rf & 1) {
|
|
274
|
+
i0.ɵɵelementStart(0, "option", 81);
|
|
265
275
|
i0.ɵɵtext(1);
|
|
266
276
|
i0.ɵɵelementEnd();
|
|
267
277
|
} if (rf & 2) {
|
|
@@ -270,14 +280,14 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
270
280
|
i0.ɵɵadvance();
|
|
271
281
|
i0.ɵɵtextInterpolate(idx_r13.Name);
|
|
272
282
|
} }
|
|
273
|
-
function
|
|
283
|
+
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_49_Template(rf, ctx) { if (rf & 1) {
|
|
274
284
|
const _r12 = i0.ɵɵgetCurrentView();
|
|
275
|
-
i0.ɵɵelementStart(0, "select",
|
|
276
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
277
|
-
i0.ɵɵelementStart(1, "option",
|
|
285
|
+
i0.ɵɵelementStart(0, "select", 80);
|
|
286
|
+
i0.ɵɵtwoWayListener("ngModelChange", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_49_Template_select_ngModelChange_0_listener($event) { i0.ɵɵrestoreView(_r12); const ctx_r1 = i0.ɵɵnextContext(4); i0.ɵɵtwoWayBindingSet(ctx_r1.EditDocVectorIndexID, $event) || (ctx_r1.EditDocVectorIndexID = $event); return i0.ɵɵresetView($event); });
|
|
287
|
+
i0.ɵɵelementStart(1, "option", 90);
|
|
278
288
|
i0.ɵɵtext(2, "Auto (create/find matching index)");
|
|
279
289
|
i0.ɵɵelementEnd();
|
|
280
|
-
i0.ɵɵrepeaterCreate(3,
|
|
290
|
+
i0.ɵɵrepeaterCreate(3, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_49_For_4_Template, 2, 2, "option", 81, _forTrack2);
|
|
281
291
|
i0.ɵɵelementEnd();
|
|
282
292
|
} if (rf & 2) {
|
|
283
293
|
const ctx_r1 = i0.ɵɵnextContext(4);
|
|
@@ -285,113 +295,121 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
285
295
|
i0.ɵɵadvance(3);
|
|
286
296
|
i0.ɵɵrepeater(ctx_r1.EditFilteredIndexes);
|
|
287
297
|
} }
|
|
288
|
-
function
|
|
289
|
-
i0.ɵɵelementStart(0, "span",
|
|
298
|
+
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_50_Template(rf, ctx) { if (rf & 1) {
|
|
299
|
+
i0.ɵɵelementStart(0, "span", 83);
|
|
290
300
|
i0.ɵɵtext(1, " No indexes for this database \u2014 one will be created automatically on sync ");
|
|
291
301
|
i0.ɵɵelementEnd();
|
|
292
302
|
} }
|
|
293
|
-
function
|
|
294
|
-
i0.ɵɵelement(0, "mj-loading",
|
|
303
|
+
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_60_Template(rf, ctx) { if (rf & 1) {
|
|
304
|
+
i0.ɵɵelement(0, "mj-loading", 87);
|
|
295
305
|
} }
|
|
296
|
-
function
|
|
306
|
+
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_61_Template(rf, ctx) { if (rf & 1) {
|
|
297
307
|
const _r14 = i0.ɵɵgetCurrentView();
|
|
298
|
-
i0.ɵɵelementStart(0, "button",
|
|
299
|
-
i0.ɵɵlistener("click", function
|
|
300
|
-
i0.ɵɵelement(1, "i",
|
|
308
|
+
i0.ɵɵelementStart(0, "button", 91);
|
|
309
|
+
i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_61_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.SaveEditedDocument()); });
|
|
310
|
+
i0.ɵɵelement(1, "i", 92);
|
|
301
311
|
i0.ɵɵtext(2, " Save Changes ");
|
|
302
312
|
i0.ɵɵelementEnd();
|
|
303
|
-
i0.ɵɵelementStart(3, "button",
|
|
304
|
-
i0.ɵɵlistener("click", function
|
|
305
|
-
i0.ɵɵelement(4, "i",
|
|
313
|
+
i0.ɵɵelementStart(3, "button", 93);
|
|
314
|
+
i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_61_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.DeleteEntityDocument()); });
|
|
315
|
+
i0.ɵɵelement(4, "i", 94);
|
|
306
316
|
i0.ɵɵtext(5, " Delete ");
|
|
307
317
|
i0.ɵɵelementEnd();
|
|
308
|
-
i0.ɵɵelementStart(6, "button",
|
|
309
|
-
i0.ɵɵlistener("click", function
|
|
318
|
+
i0.ɵɵelementStart(6, "button", 95);
|
|
319
|
+
i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_61_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.CloseEditPanel()); });
|
|
310
320
|
i0.ɵɵtext(7, " Cancel ");
|
|
311
321
|
i0.ɵɵelementEnd();
|
|
312
322
|
} }
|
|
313
323
|
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Template(rf, ctx) { if (rf & 1) {
|
|
314
324
|
const _r8 = i0.ɵɵgetCurrentView();
|
|
315
|
-
i0.ɵɵelementStart(0, "div",
|
|
325
|
+
i0.ɵɵelementStart(0, "div", 64);
|
|
316
326
|
i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.CloseEditPanel()); });
|
|
317
|
-
i0.ɵɵelementStart(1, "div",
|
|
327
|
+
i0.ɵɵelementStart(1, "div", 65);
|
|
318
328
|
i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Template_div_click_1_listener($event) { return $event.stopPropagation(); });
|
|
319
|
-
i0.ɵɵelementStart(2, "div",
|
|
320
|
-
i0.ɵɵelement(4, "i",
|
|
329
|
+
i0.ɵɵelementStart(2, "div", 66)(3, "h3", 67);
|
|
330
|
+
i0.ɵɵelement(4, "i", 60);
|
|
321
331
|
i0.ɵɵtext(5, " Edit Entity Document ");
|
|
322
332
|
i0.ɵɵelementEnd();
|
|
323
|
-
i0.ɵɵelementStart(6, "button",
|
|
333
|
+
i0.ɵɵelementStart(6, "button", 68);
|
|
324
334
|
i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.CloseEditPanel()); });
|
|
325
|
-
i0.ɵɵelement(7, "i",
|
|
335
|
+
i0.ɵɵelement(7, "i", 69);
|
|
326
336
|
i0.ɵɵelementEnd()();
|
|
327
|
-
i0.ɵɵelementStart(8, "div",
|
|
337
|
+
i0.ɵɵelementStart(8, "div", 70)(9, "div", 71)(10, "div", 72)(11, "label", 73);
|
|
328
338
|
i0.ɵɵtext(12, "Entity");
|
|
329
339
|
i0.ɵɵelementEnd();
|
|
330
|
-
i0.ɵɵelementStart(13, "span",
|
|
340
|
+
i0.ɵɵelementStart(13, "span", 74);
|
|
331
341
|
i0.ɵɵtext(14);
|
|
332
342
|
i0.ɵɵelementEnd()();
|
|
333
|
-
i0.ɵɵelementStart(15, "div",
|
|
334
|
-
i0.ɵɵtext(
|
|
343
|
+
i0.ɵɵelementStart(15, "div", 72)(16, "label", 73);
|
|
344
|
+
i0.ɵɵtext(17, "Type");
|
|
345
|
+
i0.ɵɵelementEnd();
|
|
346
|
+
i0.ɵɵelementStart(18, "span", 74);
|
|
347
|
+
i0.ɵɵtext(19);
|
|
348
|
+
i0.ɵɵelementEnd()();
|
|
349
|
+
i0.ɵɵelementStart(20, "div", 72)(21, "div", 75)(22, "label", 73);
|
|
350
|
+
i0.ɵɵtext(23, "Template");
|
|
335
351
|
i0.ɵɵelementEnd();
|
|
336
|
-
i0.ɵɵelementStart(
|
|
337
|
-
i0.ɵɵlistener("click", function
|
|
338
|
-
i0.ɵɵconditionalCreate(
|
|
352
|
+
i0.ɵɵelementStart(24, "button", 76);
|
|
353
|
+
i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Template_button_click_24_listener() { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.RegenerateTemplate()); });
|
|
354
|
+
i0.ɵɵconditionalCreate(25, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_25_Template, 2, 0)(26, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_26_Template, 2, 0);
|
|
339
355
|
i0.ɵɵelementEnd()();
|
|
340
|
-
i0.ɵɵelementStart(
|
|
341
|
-
i0.ɵɵlistener("change", function
|
|
356
|
+
i0.ɵɵelementStart(27, "div", 77)(28, "mj-code-editor", 78);
|
|
357
|
+
i0.ɵɵlistener("change", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Template_mj_code_editor_change_28_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnEditTemplateChange($event)); });
|
|
342
358
|
i0.ɵɵelementEnd()()();
|
|
343
|
-
i0.ɵɵconditionalCreate(
|
|
344
|
-
i0.ɵɵelementStart(
|
|
345
|
-
i0.ɵɵtext(
|
|
359
|
+
i0.ɵɵconditionalCreate(29, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_29_Template, 6, 0, "div", 72);
|
|
360
|
+
i0.ɵɵelementStart(30, "div", 72)(31, "label", 73);
|
|
361
|
+
i0.ɵɵtext(32, "Document Name");
|
|
346
362
|
i0.ɵɵelementEnd();
|
|
347
|
-
i0.ɵɵelementStart(
|
|
348
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
363
|
+
i0.ɵɵelementStart(33, "input", 79);
|
|
364
|
+
i0.ɵɵtwoWayListener("ngModelChange", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Template_input_ngModelChange_33_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(3); i0.ɵɵtwoWayBindingSet(ctx_r1.EditDocName, $event) || (ctx_r1.EditDocName = $event); return i0.ɵɵresetView($event); });
|
|
349
365
|
i0.ɵɵelementEnd()();
|
|
350
|
-
i0.ɵɵelementStart(
|
|
351
|
-
i0.ɵɵtext(
|
|
366
|
+
i0.ɵɵelementStart(34, "div", 72)(35, "label", 73);
|
|
367
|
+
i0.ɵɵtext(36, "Embedding Model");
|
|
352
368
|
i0.ɵɵelementEnd();
|
|
353
|
-
i0.ɵɵelementStart(
|
|
354
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
355
|
-
i0.ɵɵrepeaterCreate(
|
|
369
|
+
i0.ɵɵelementStart(37, "select", 80);
|
|
370
|
+
i0.ɵɵtwoWayListener("ngModelChange", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Template_select_ngModelChange_37_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(3); i0.ɵɵtwoWayBindingSet(ctx_r1.EditDocAIModelID, $event) || (ctx_r1.EditDocAIModelID = $event); return i0.ɵɵresetView($event); });
|
|
371
|
+
i0.ɵɵrepeaterCreate(38, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_For_39_Template, 2, 2, "option", 81, _forTrack2);
|
|
356
372
|
i0.ɵɵelementEnd()();
|
|
357
|
-
i0.ɵɵelementStart(
|
|
358
|
-
i0.ɵɵtext(
|
|
373
|
+
i0.ɵɵelementStart(40, "div", 72)(41, "label", 73);
|
|
374
|
+
i0.ɵɵtext(42, "Vector Database");
|
|
359
375
|
i0.ɵɵelementEnd();
|
|
360
|
-
i0.ɵɵelementStart(
|
|
361
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
362
|
-
i0.ɵɵrepeaterCreate(
|
|
376
|
+
i0.ɵɵelementStart(43, "select", 80);
|
|
377
|
+
i0.ɵɵtwoWayListener("ngModelChange", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Template_select_ngModelChange_43_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(3); i0.ɵɵtwoWayBindingSet(ctx_r1.EditDocVectorDBID, $event) || (ctx_r1.EditDocVectorDBID = $event); return i0.ɵɵresetView($event); });
|
|
378
|
+
i0.ɵɵrepeaterCreate(44, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_For_45_Template, 2, 2, "option", 81, _forTrack2);
|
|
363
379
|
i0.ɵɵelementEnd()();
|
|
364
|
-
i0.ɵɵelementStart(
|
|
365
|
-
i0.ɵɵtext(
|
|
380
|
+
i0.ɵɵelementStart(46, "div", 72)(47, "label", 73);
|
|
381
|
+
i0.ɵɵtext(48, "Vector Index");
|
|
366
382
|
i0.ɵɵelementEnd();
|
|
367
|
-
i0.ɵɵconditionalCreate(
|
|
383
|
+
i0.ɵɵconditionalCreate(49, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_49_Template, 5, 1, "select", 82)(50, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_50_Template, 2, 0, "span", 83);
|
|
368
384
|
i0.ɵɵelementEnd();
|
|
369
|
-
i0.ɵɵelementStart(
|
|
370
|
-
i0.ɵɵtext(
|
|
385
|
+
i0.ɵɵelementStart(51, "div", 72)(52, "label", 73);
|
|
386
|
+
i0.ɵɵtext(53, "Status");
|
|
371
387
|
i0.ɵɵelementEnd();
|
|
372
|
-
i0.ɵɵelementStart(
|
|
373
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
374
|
-
i0.ɵɵelementStart(
|
|
375
|
-
i0.ɵɵtext(
|
|
388
|
+
i0.ɵɵelementStart(54, "select", 80);
|
|
389
|
+
i0.ɵɵtwoWayListener("ngModelChange", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Template_select_ngModelChange_54_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(3); i0.ɵɵtwoWayBindingSet(ctx_r1.EditDocStatus, $event) || (ctx_r1.EditDocStatus = $event); return i0.ɵɵresetView($event); });
|
|
390
|
+
i0.ɵɵelementStart(55, "option", 84);
|
|
391
|
+
i0.ɵɵtext(56, "Active");
|
|
376
392
|
i0.ɵɵelementEnd();
|
|
377
|
-
i0.ɵɵelementStart(
|
|
378
|
-
i0.ɵɵtext(
|
|
393
|
+
i0.ɵɵelementStart(57, "option", 85);
|
|
394
|
+
i0.ɵɵtext(58, "Inactive");
|
|
379
395
|
i0.ɵɵelementEnd()()();
|
|
380
|
-
i0.ɵɵelementStart(
|
|
381
|
-
i0.ɵɵconditionalCreate(
|
|
396
|
+
i0.ɵɵelementStart(59, "div", 86);
|
|
397
|
+
i0.ɵɵconditionalCreate(60, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_60_Template, 1, 0, "mj-loading", 87)(61, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_61_Template, 8, 0);
|
|
382
398
|
i0.ɵɵelementEnd()()()()();
|
|
383
399
|
} if (rf & 2) {
|
|
384
400
|
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
385
401
|
i0.ɵɵadvance(14);
|
|
386
402
|
i0.ɵɵtextInterpolate(ctx_r1.EditDocEntityName);
|
|
387
403
|
i0.ɵɵadvance(5);
|
|
404
|
+
i0.ɵɵtextInterpolate(ctx_r1.EditDocType);
|
|
405
|
+
i0.ɵɵadvance(5);
|
|
388
406
|
i0.ɵɵproperty("disabled", ctx_r1.IsEditRegenerating);
|
|
389
407
|
i0.ɵɵadvance();
|
|
390
|
-
i0.ɵɵconditional(ctx_r1.IsEditRegenerating ?
|
|
408
|
+
i0.ɵɵconditional(ctx_r1.IsEditRegenerating ? 25 : 26);
|
|
391
409
|
i0.ɵɵadvance(3);
|
|
392
410
|
i0.ɵɵproperty("value", ctx_r1.EditDocTemplate)("readonly", false)("lineWrapping", true);
|
|
393
411
|
i0.ɵɵadvance();
|
|
394
|
-
i0.ɵɵconditional(ctx_r1.EditDocSelectedFields.length > 0 ?
|
|
412
|
+
i0.ɵɵconditional(ctx_r1.EditDocSelectedFields.length > 0 ? 29 : -1);
|
|
395
413
|
i0.ɵɵadvance(4);
|
|
396
414
|
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.EditDocName);
|
|
397
415
|
i0.ɵɵadvance(4);
|
|
@@ -403,71 +421,71 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
403
421
|
i0.ɵɵadvance();
|
|
404
422
|
i0.ɵɵrepeater(ctx_r1.vectorDatabases);
|
|
405
423
|
i0.ɵɵadvance(5);
|
|
406
|
-
i0.ɵɵconditional(ctx_r1.EditFilteredIndexes.length > 0 ?
|
|
424
|
+
i0.ɵɵconditional(ctx_r1.EditFilteredIndexes.length > 0 ? 49 : 50);
|
|
407
425
|
i0.ɵɵadvance(5);
|
|
408
426
|
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.EditDocStatus);
|
|
409
427
|
i0.ɵɵadvance(6);
|
|
410
|
-
i0.ɵɵconditional(ctx_r1.IsEditSaving || ctx_r1.IsEditDeleting ?
|
|
428
|
+
i0.ɵɵconditional(ctx_r1.IsEditSaving || ctx_r1.IsEditDeleting ? 60 : 61);
|
|
411
429
|
} }
|
|
412
430
|
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_56_Conditional_32_Template(rf, ctx) { if (rf & 1) {
|
|
413
|
-
i0.ɵɵelement(0, "mj-loading",
|
|
431
|
+
i0.ɵɵelement(0, "mj-loading", 87);
|
|
414
432
|
} }
|
|
415
433
|
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_56_Conditional_33_Template(rf, ctx) { if (rf & 1) {
|
|
416
434
|
const _r16 = i0.ɵɵgetCurrentView();
|
|
417
|
-
i0.ɵɵelementStart(0, "button",
|
|
435
|
+
i0.ɵɵelementStart(0, "button", 91);
|
|
418
436
|
i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_56_Conditional_33_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r16); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.SaveScheduleSync()); });
|
|
419
|
-
i0.ɵɵelement(1, "i",
|
|
437
|
+
i0.ɵɵelement(1, "i", 102);
|
|
420
438
|
i0.ɵɵtext(2, " Create Schedule ");
|
|
421
439
|
i0.ɵɵelementEnd();
|
|
422
|
-
i0.ɵɵelementStart(3, "button",
|
|
440
|
+
i0.ɵɵelementStart(3, "button", 95);
|
|
423
441
|
i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_56_Conditional_33_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r16); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.CloseScheduleSyncDialog()); });
|
|
424
442
|
i0.ɵɵtext(4, " Cancel ");
|
|
425
443
|
i0.ɵɵelementEnd();
|
|
426
444
|
} }
|
|
427
445
|
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_56_Template(rf, ctx) { if (rf & 1) {
|
|
428
446
|
const _r15 = i0.ɵɵgetCurrentView();
|
|
429
|
-
i0.ɵɵelementStart(0, "div",
|
|
447
|
+
i0.ɵɵelementStart(0, "div", 64);
|
|
430
448
|
i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_56_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r15); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.CloseScheduleSyncDialog()); });
|
|
431
|
-
i0.ɵɵelementStart(1, "div",
|
|
449
|
+
i0.ɵɵelementStart(1, "div", 96);
|
|
432
450
|
i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_56_Template_div_click_1_listener($event) { return $event.stopPropagation(); });
|
|
433
|
-
i0.ɵɵelementStart(2, "div",
|
|
434
|
-
i0.ɵɵelement(4, "i",
|
|
451
|
+
i0.ɵɵelementStart(2, "div", 66)(3, "h3", 67);
|
|
452
|
+
i0.ɵɵelement(4, "i", 58);
|
|
435
453
|
i0.ɵɵtext(5, " Schedule Vector Sync ");
|
|
436
454
|
i0.ɵɵelementEnd();
|
|
437
|
-
i0.ɵɵelementStart(6, "button",
|
|
455
|
+
i0.ɵɵelementStart(6, "button", 68);
|
|
438
456
|
i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_56_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r15); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.CloseScheduleSyncDialog()); });
|
|
439
|
-
i0.ɵɵelement(7, "i",
|
|
457
|
+
i0.ɵɵelement(7, "i", 69);
|
|
440
458
|
i0.ɵɵelementEnd()();
|
|
441
|
-
i0.ɵɵelementStart(8, "div",
|
|
459
|
+
i0.ɵɵelementStart(8, "div", 70)(9, "div", 71)(10, "div", 72)(11, "label", 73);
|
|
442
460
|
i0.ɵɵtext(12, "Entity Document");
|
|
443
461
|
i0.ɵɵelementEnd();
|
|
444
|
-
i0.ɵɵelementStart(13, "span",
|
|
462
|
+
i0.ɵɵelementStart(13, "span", 74);
|
|
445
463
|
i0.ɵɵtext(14);
|
|
446
464
|
i0.ɵɵelementEnd()();
|
|
447
|
-
i0.ɵɵelementStart(15, "div",
|
|
465
|
+
i0.ɵɵelementStart(15, "div", 72)(16, "label", 73);
|
|
448
466
|
i0.ɵɵtext(17, "Action");
|
|
449
467
|
i0.ɵɵelementEnd();
|
|
450
|
-
i0.ɵɵelementStart(18, "span",
|
|
468
|
+
i0.ɵɵelementStart(18, "span", 74);
|
|
451
469
|
i0.ɵɵtext(19, "__VectorizeEntity");
|
|
452
470
|
i0.ɵɵelementEnd()();
|
|
453
|
-
i0.ɵɵelementStart(20, "div",
|
|
471
|
+
i0.ɵɵelementStart(20, "div", 72)(21, "label", 73);
|
|
454
472
|
i0.ɵɵtext(22, "Cron Expression");
|
|
455
473
|
i0.ɵɵelementEnd();
|
|
456
|
-
i0.ɵɵelementStart(23, "input",
|
|
474
|
+
i0.ɵɵelementStart(23, "input", 97);
|
|
457
475
|
i0.ɵɵtwoWayListener("ngModelChange", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_56_Template_input_ngModelChange_23_listener($event) { i0.ɵɵrestoreView(_r15); const ctx_r1 = i0.ɵɵnextContext(3); i0.ɵɵtwoWayBindingSet(ctx_r1.ScheduleSyncCron, $event) || (ctx_r1.ScheduleSyncCron = $event); return i0.ɵɵresetView($event); });
|
|
458
476
|
i0.ɵɵelementEnd();
|
|
459
|
-
i0.ɵɵelementStart(24, "div",
|
|
460
|
-
i0.ɵɵelement(25, "i",
|
|
477
|
+
i0.ɵɵelementStart(24, "div", 98);
|
|
478
|
+
i0.ɵɵelement(25, "i", 99);
|
|
461
479
|
i0.ɵɵtext(26);
|
|
462
480
|
i0.ɵɵelementEnd()();
|
|
463
|
-
i0.ɵɵelementStart(27, "div",
|
|
481
|
+
i0.ɵɵelementStart(27, "div", 100)(28, "label", 73);
|
|
464
482
|
i0.ɵɵtext(29, "Enabled");
|
|
465
483
|
i0.ɵɵelementEnd();
|
|
466
|
-
i0.ɵɵelementStart(30, "input",
|
|
484
|
+
i0.ɵɵelementStart(30, "input", 101);
|
|
467
485
|
i0.ɵɵtwoWayListener("ngModelChange", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_56_Template_input_ngModelChange_30_listener($event) { i0.ɵɵrestoreView(_r15); const ctx_r1 = i0.ɵɵnextContext(3); i0.ɵɵtwoWayBindingSet(ctx_r1.ScheduleSyncEnabled, $event) || (ctx_r1.ScheduleSyncEnabled = $event); return i0.ɵɵresetView($event); });
|
|
468
486
|
i0.ɵɵelementEnd()();
|
|
469
|
-
i0.ɵɵelementStart(31, "div",
|
|
470
|
-
i0.ɵɵconditionalCreate(32, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_56_Conditional_32_Template, 1, 0, "mj-loading",
|
|
487
|
+
i0.ɵɵelementStart(31, "div", 86);
|
|
488
|
+
i0.ɵɵconditionalCreate(32, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_56_Conditional_32_Template, 1, 0, "mj-loading", 87)(33, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_56_Conditional_33_Template, 5, 0);
|
|
471
489
|
i0.ɵɵelementEnd()()()()();
|
|
472
490
|
} if (rf & 2) {
|
|
473
491
|
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
@@ -484,25 +502,25 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
484
502
|
} }
|
|
485
503
|
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_57_Template(rf, ctx) { if (rf & 1) {
|
|
486
504
|
const _r17 = i0.ɵɵgetCurrentView();
|
|
487
|
-
i0.ɵɵelementStart(0, "div",
|
|
505
|
+
i0.ɵɵelementStart(0, "div", 64);
|
|
488
506
|
i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_57_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r17); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.CloseNoIndexWarning()); });
|
|
489
|
-
i0.ɵɵelementStart(1, "div",
|
|
507
|
+
i0.ɵɵelementStart(1, "div", 103);
|
|
490
508
|
i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_57_Template_div_click_1_listener($event) { return $event.stopPropagation(); });
|
|
491
|
-
i0.ɵɵelementStart(2, "div",
|
|
492
|
-
i0.ɵɵelement(3, "i",
|
|
509
|
+
i0.ɵɵelementStart(2, "div", 104);
|
|
510
|
+
i0.ɵɵelement(3, "i", 105);
|
|
493
511
|
i0.ɵɵelementEnd();
|
|
494
|
-
i0.ɵɵelementStart(4, "h3",
|
|
512
|
+
i0.ɵɵelementStart(4, "h3", 106);
|
|
495
513
|
i0.ɵɵtext(5, "Vector Index Required");
|
|
496
514
|
i0.ɵɵelementEnd();
|
|
497
|
-
i0.ɵɵelementStart(6, "p",
|
|
515
|
+
i0.ɵɵelementStart(6, "p", 107);
|
|
498
516
|
i0.ɵɵtext(7, " You need to create at least one vector database and index before creating entity documents. Go to the Configuration section to set up a vector database and create an index. ");
|
|
499
517
|
i0.ɵɵelementEnd();
|
|
500
|
-
i0.ɵɵelementStart(8, "div",
|
|
518
|
+
i0.ɵɵelementStart(8, "div", 108)(9, "button", 91);
|
|
501
519
|
i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_57_Template_button_click_9_listener() { i0.ɵɵrestoreView(_r17); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.GoToConfiguration()); });
|
|
502
|
-
i0.ɵɵelement(10, "i",
|
|
520
|
+
i0.ɵɵelement(10, "i", 109);
|
|
503
521
|
i0.ɵɵtext(11, " Go to Configuration ");
|
|
504
522
|
i0.ɵɵelementEnd();
|
|
505
|
-
i0.ɵɵelementStart(12, "button",
|
|
523
|
+
i0.ɵɵelementStart(12, "button", 95);
|
|
506
524
|
i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_57_Template_button_click_12_listener() { i0.ɵɵrestoreView(_r17); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.CloseNoIndexWarning()); });
|
|
507
525
|
i0.ɵɵtext(13, " Close ");
|
|
508
526
|
i0.ɵɵelementEnd()()()();
|
|
@@ -583,15 +601,15 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
583
601
|
i0.ɵɵadvance(2);
|
|
584
602
|
i0.ɵɵconditional(ctx_r1.FilteredEntityGroups.length === 0 ? 8 : -1);
|
|
585
603
|
} }
|
|
586
|
-
function
|
|
587
|
-
i0.ɵɵelement(0, "i",
|
|
604
|
+
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_9_Conditional_21_Template(rf, ctx) { if (rf & 1) {
|
|
605
|
+
i0.ɵɵelement(0, "i", 61);
|
|
588
606
|
i0.ɵɵtext(1, " Generating with AI... ");
|
|
589
607
|
} }
|
|
590
|
-
function
|
|
608
|
+
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_9_Conditional_22_Template(rf, ctx) { if (rf & 1) {
|
|
591
609
|
i0.ɵɵelement(0, "i", 19);
|
|
592
610
|
i0.ɵɵtext(1, " Generate Template ");
|
|
593
611
|
} }
|
|
594
|
-
function
|
|
612
|
+
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_9_Conditional_23_Template(rf, ctx) { if (rf & 1) {
|
|
595
613
|
i0.ɵɵelementStart(0, "mj-alert", 121);
|
|
596
614
|
i0.ɵɵtext(1);
|
|
597
615
|
i0.ɵɵelementEnd();
|
|
@@ -602,39 +620,34 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
602
620
|
} }
|
|
603
621
|
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
604
622
|
const _r19 = i0.ɵɵgetCurrentView();
|
|
605
|
-
i0.ɵɵelementStart(0, "div",
|
|
623
|
+
i0.ɵɵelementStart(0, "div", 71)(1, "div", 72)(2, "label", 73);
|
|
606
624
|
i0.ɵɵtext(3, "Entity");
|
|
607
625
|
i0.ɵɵelementEnd();
|
|
608
|
-
i0.ɵɵelementStart(4, "div",
|
|
626
|
+
i0.ɵɵelementStart(4, "div", 112)(5, "button", 113);
|
|
609
627
|
i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_9_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r19); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.ToggleEntityPicker()); });
|
|
610
628
|
i0.ɵɵconditionalCreate(6, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_9_Conditional_6_Template, 3, 1)(7, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_9_Conditional_7_Template, 3, 0);
|
|
611
|
-
i0.ɵɵelement(8, "i",
|
|
629
|
+
i0.ɵɵelement(8, "i", 114);
|
|
612
630
|
i0.ɵɵelementEnd();
|
|
613
|
-
i0.ɵɵconditionalCreate(9, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_9_Conditional_9_Template, 9, 2, "div",
|
|
631
|
+
i0.ɵɵconditionalCreate(9, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_9_Conditional_9_Template, 9, 2, "div", 115);
|
|
614
632
|
i0.ɵɵelementEnd()();
|
|
615
|
-
i0.ɵɵelementStart(10, "div",
|
|
633
|
+
i0.ɵɵelementStart(10, "div", 72)(11, "label", 73);
|
|
616
634
|
i0.ɵɵtext(12, "Use Case");
|
|
617
635
|
i0.ɵɵelementEnd();
|
|
618
|
-
i0.ɵɵelementStart(13, "div",
|
|
636
|
+
i0.ɵɵelementStart(13, "div", 116)(14, "button", 117);
|
|
619
637
|
i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_9_Template_button_click_14_listener() { i0.ɵɵrestoreView(_r19); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.SuggestUseCase = "duplicate detection"); });
|
|
620
|
-
i0.ɵɵelement(15, "i",
|
|
638
|
+
i0.ɵɵelement(15, "i", 118);
|
|
621
639
|
i0.ɵɵtext(16, " Duplicate Detection ");
|
|
622
640
|
i0.ɵɵelementEnd();
|
|
623
|
-
i0.ɵɵelementStart(17, "button",
|
|
641
|
+
i0.ɵɵelementStart(17, "button", 117);
|
|
624
642
|
i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_9_Template_button_click_17_listener() { i0.ɵɵrestoreView(_r19); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.SuggestUseCase = "search"); });
|
|
625
|
-
i0.ɵɵelement(18, "i",
|
|
643
|
+
i0.ɵɵelement(18, "i", 119);
|
|
626
644
|
i0.ɵɵtext(19, " Search ");
|
|
627
|
-
i0.ɵɵelementEnd();
|
|
628
|
-
i0.ɵɵelementStart(20, "button", 116);
|
|
629
|
-
i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_9_Template_button_click_20_listener() { i0.ɵɵrestoreView(_r19); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.SuggestUseCase = "classification"); });
|
|
630
|
-
i0.ɵɵelement(21, "i", 119);
|
|
631
|
-
i0.ɵɵtext(22, " Classification ");
|
|
632
645
|
i0.ɵɵelementEnd()()();
|
|
633
|
-
i0.ɵɵelementStart(
|
|
634
|
-
i0.ɵɵlistener("click", function
|
|
635
|
-
i0.ɵɵconditionalCreate(
|
|
646
|
+
i0.ɵɵelementStart(20, "button", 120);
|
|
647
|
+
i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_9_Template_button_click_20_listener() { i0.ɵɵrestoreView(_r19); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.RunSuggestion()); });
|
|
648
|
+
i0.ɵɵconditionalCreate(21, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_9_Conditional_21_Template, 2, 0)(22, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_9_Conditional_22_Template, 2, 0);
|
|
636
649
|
i0.ɵɵelementEnd();
|
|
637
|
-
i0.ɵɵconditionalCreate(
|
|
650
|
+
i0.ɵɵconditionalCreate(23, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_9_Conditional_23_Template, 2, 1, "mj-alert", 121);
|
|
638
651
|
i0.ɵɵelementEnd();
|
|
639
652
|
} if (rf & 2) {
|
|
640
653
|
const ctx_r1 = i0.ɵɵnextContext(4);
|
|
@@ -647,16 +660,14 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
647
660
|
i0.ɵɵadvance(3);
|
|
648
661
|
i0.ɵɵclassProp("use-case-btn-active", ctx_r1.SuggestUseCase === "search");
|
|
649
662
|
i0.ɵɵadvance(3);
|
|
650
|
-
i0.ɵɵclassProp("use-case-btn-active", ctx_r1.SuggestUseCase === "classification");
|
|
651
|
-
i0.ɵɵadvance(3);
|
|
652
663
|
i0.ɵɵproperty("disabled", ctx_r1.IsSuggesting || !ctx_r1.SuggestEntityName);
|
|
653
664
|
i0.ɵɵadvance();
|
|
654
|
-
i0.ɵɵconditional(ctx_r1.IsSuggesting ?
|
|
665
|
+
i0.ɵɵconditional(ctx_r1.IsSuggesting ? 21 : 22);
|
|
655
666
|
i0.ɵɵadvance(2);
|
|
656
|
-
i0.ɵɵconditional(ctx_r1.SuggestionError ?
|
|
667
|
+
i0.ɵɵconditional(ctx_r1.SuggestionError ? 23 : -1);
|
|
657
668
|
} }
|
|
658
669
|
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_For_11_Template(rf, ctx) { if (rf & 1) {
|
|
659
|
-
i0.ɵɵelementStart(0, "span",
|
|
670
|
+
i0.ɵɵelementStart(0, "span", 89);
|
|
660
671
|
i0.ɵɵtext(1);
|
|
661
672
|
i0.ɵɵelementEnd();
|
|
662
673
|
} if (rf & 2) {
|
|
@@ -690,7 +701,7 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
690
701
|
i0.ɵɵrepeater(ctx_r1.SuggestionResult.selectedRelationships);
|
|
691
702
|
} }
|
|
692
703
|
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_For_39_Template(rf, ctx) { if (rf & 1) {
|
|
693
|
-
i0.ɵɵelementStart(0, "option",
|
|
704
|
+
i0.ɵɵelementStart(0, "option", 81);
|
|
694
705
|
i0.ɵɵtext(1);
|
|
695
706
|
i0.ɵɵelementEnd();
|
|
696
707
|
} if (rf & 2) {
|
|
@@ -700,7 +711,7 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
700
711
|
i0.ɵɵtextInterpolate(model_r27.Name);
|
|
701
712
|
} }
|
|
702
713
|
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_For_45_Template(rf, ctx) { if (rf & 1) {
|
|
703
|
-
i0.ɵɵelementStart(0, "option",
|
|
714
|
+
i0.ɵɵelementStart(0, "option", 81);
|
|
704
715
|
i0.ɵɵtext(1);
|
|
705
716
|
i0.ɵɵelementEnd();
|
|
706
717
|
} if (rf & 2) {
|
|
@@ -710,7 +721,7 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
710
721
|
i0.ɵɵtextInterpolate(db_r28.Name);
|
|
711
722
|
} }
|
|
712
723
|
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Conditional_49_For_4_Template(rf, ctx) { if (rf & 1) {
|
|
713
|
-
i0.ɵɵelementStart(0, "option",
|
|
724
|
+
i0.ɵɵelementStart(0, "option", 81);
|
|
714
725
|
i0.ɵɵtext(1);
|
|
715
726
|
i0.ɵɵelementEnd();
|
|
716
727
|
} if (rf & 2) {
|
|
@@ -721,12 +732,12 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
721
732
|
} }
|
|
722
733
|
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Conditional_49_Template(rf, ctx) { if (rf & 1) {
|
|
723
734
|
const _r29 = i0.ɵɵgetCurrentView();
|
|
724
|
-
i0.ɵɵelementStart(0, "select",
|
|
735
|
+
i0.ɵɵelementStart(0, "select", 80);
|
|
725
736
|
i0.ɵɵtwoWayListener("ngModelChange", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Conditional_49_Template_select_ngModelChange_0_listener($event) { i0.ɵɵrestoreView(_r29); const ctx_r1 = i0.ɵɵnextContext(5); i0.ɵɵtwoWayBindingSet(ctx_r1.SelectedVectorIndexID, $event) || (ctx_r1.SelectedVectorIndexID = $event); return i0.ɵɵresetView($event); });
|
|
726
|
-
i0.ɵɵelementStart(1, "option",
|
|
737
|
+
i0.ɵɵelementStart(1, "option", 90);
|
|
727
738
|
i0.ɵɵtext(2, "Auto (create/find matching index)");
|
|
728
739
|
i0.ɵɵelementEnd();
|
|
729
|
-
i0.ɵɵrepeaterCreate(3, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Conditional_49_For_4_Template, 2, 2, "option",
|
|
740
|
+
i0.ɵɵrepeaterCreate(3, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Conditional_49_For_4_Template, 2, 2, "option", 81, _forTrack2);
|
|
730
741
|
i0.ɵɵelementEnd();
|
|
731
742
|
} if (rf & 2) {
|
|
732
743
|
const ctx_r1 = i0.ɵɵnextContext(5);
|
|
@@ -735,18 +746,18 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
735
746
|
i0.ɵɵrepeater(ctx_r1.FilteredIndexesForSelectedDB);
|
|
736
747
|
} }
|
|
737
748
|
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Conditional_50_Template(rf, ctx) { if (rf & 1) {
|
|
738
|
-
i0.ɵɵelementStart(0, "span",
|
|
749
|
+
i0.ɵɵelementStart(0, "span", 83);
|
|
739
750
|
i0.ɵɵtext(1, " No indexes yet \u2014 create one in Configuration > Vector Database, or one will be created on sync ");
|
|
740
751
|
i0.ɵɵelementEnd();
|
|
741
752
|
} }
|
|
742
753
|
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Conditional_52_Template(rf, ctx) { if (rf & 1) {
|
|
743
754
|
i0.ɵɵelementStart(0, "div", 145);
|
|
744
|
-
i0.ɵɵelement(1, "mj-loading",
|
|
755
|
+
i0.ɵɵelement(1, "mj-loading", 87);
|
|
745
756
|
i0.ɵɵelementEnd();
|
|
746
757
|
} }
|
|
747
758
|
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Conditional_53_Template(rf, ctx) { if (rf & 1) {
|
|
748
759
|
const _r31 = i0.ɵɵgetCurrentView();
|
|
749
|
-
i0.ɵɵelementStart(0, "button",
|
|
760
|
+
i0.ɵɵelementStart(0, "button", 91);
|
|
750
761
|
i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Conditional_53_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r31); const ctx_r1 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r1.SaveAsEntityDocument()); });
|
|
751
762
|
i0.ɵɵelement(1, "i", 149);
|
|
752
763
|
i0.ɵɵtext(2, " Save as Entity Document ");
|
|
@@ -756,24 +767,24 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
756
767
|
i0.ɵɵelement(4, "i", 151);
|
|
757
768
|
i0.ɵɵtext(5, " Try Again ");
|
|
758
769
|
i0.ɵɵelementEnd();
|
|
759
|
-
i0.ɵɵelementStart(6, "button",
|
|
770
|
+
i0.ɵɵelementStart(6, "button", 95);
|
|
760
771
|
i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Conditional_53_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r31); const ctx_r1 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r1.CloseSuggestDialog()); });
|
|
761
772
|
i0.ɵɵtext(7, " Close ");
|
|
762
773
|
i0.ɵɵelementEnd();
|
|
763
774
|
} }
|
|
764
775
|
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
765
776
|
const _r24 = i0.ɵɵgetCurrentView();
|
|
766
|
-
i0.ɵɵelementStart(0, "div",
|
|
777
|
+
i0.ɵɵelementStart(0, "div", 111)(1, "div", 136)(2, "h4", 137);
|
|
767
778
|
i0.ɵɵtext(3, "Suggested Template");
|
|
768
779
|
i0.ɵɵelementEnd();
|
|
769
|
-
i0.ɵɵelementStart(4, "div",
|
|
780
|
+
i0.ɵɵelementStart(4, "div", 77)(5, "mj-code-editor", 78);
|
|
770
781
|
i0.ɵɵlistener("change", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Template_mj_code_editor_change_5_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.OnTemplateChange($event)); });
|
|
771
782
|
i0.ɵɵelementEnd()()();
|
|
772
783
|
i0.ɵɵelementStart(6, "div", 136)(7, "h4", 137);
|
|
773
784
|
i0.ɵɵtext(8, "Selected Fields");
|
|
774
785
|
i0.ɵɵelementEnd();
|
|
775
|
-
i0.ɵɵelementStart(9, "div",
|
|
776
|
-
i0.ɵɵrepeaterCreate(10, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_For_11_Template, 2, 1, "span",
|
|
786
|
+
i0.ɵɵelementStart(9, "div", 88);
|
|
787
|
+
i0.ɵɵrepeaterCreate(10, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_For_11_Template, 2, 1, "span", 89, i0.ɵɵrepeaterTrackByIdentity);
|
|
777
788
|
i0.ɵɵelementEnd()();
|
|
778
789
|
i0.ɵɵconditionalCreate(12, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Conditional_12_Template, 5, 0, "div", 136);
|
|
779
790
|
i0.ɵɵelementStart(13, "div", 138)(14, "div", 139)(15, "span", 140);
|
|
@@ -794,30 +805,30 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
794
805
|
i0.ɵɵelementStart(27, "p", 142);
|
|
795
806
|
i0.ɵɵtext(28);
|
|
796
807
|
i0.ɵɵelementEnd()();
|
|
797
|
-
i0.ɵɵelementStart(29, "div", 136)(30, "div",
|
|
808
|
+
i0.ɵɵelementStart(29, "div", 136)(30, "div", 72)(31, "label", 73);
|
|
798
809
|
i0.ɵɵtext(32, "Document Name");
|
|
799
810
|
i0.ɵɵelementEnd();
|
|
800
|
-
i0.ɵɵelementStart(33, "input",
|
|
811
|
+
i0.ɵɵelementStart(33, "input", 79);
|
|
801
812
|
i0.ɵɵtwoWayListener("ngModelChange", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Template_input_ngModelChange_33_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r1 = i0.ɵɵnextContext(4); i0.ɵɵtwoWayBindingSet(ctx_r1.SaveDocumentName, $event) || (ctx_r1.SaveDocumentName = $event); return i0.ɵɵresetView($event); });
|
|
802
813
|
i0.ɵɵelementEnd()();
|
|
803
|
-
i0.ɵɵelementStart(34, "div", 143)(35, "label",
|
|
814
|
+
i0.ɵɵelementStart(34, "div", 143)(35, "label", 73);
|
|
804
815
|
i0.ɵɵtext(36, "Embedding Model");
|
|
805
816
|
i0.ɵɵelementEnd();
|
|
806
|
-
i0.ɵɵelementStart(37, "select",
|
|
817
|
+
i0.ɵɵelementStart(37, "select", 80);
|
|
807
818
|
i0.ɵɵtwoWayListener("ngModelChange", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Template_select_ngModelChange_37_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r1 = i0.ɵɵnextContext(4); i0.ɵɵtwoWayBindingSet(ctx_r1.SelectedEmbeddingModelID, $event) || (ctx_r1.SelectedEmbeddingModelID = $event); return i0.ɵɵresetView($event); });
|
|
808
|
-
i0.ɵɵrepeaterCreate(38, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_For_39_Template, 2, 2, "option",
|
|
819
|
+
i0.ɵɵrepeaterCreate(38, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_For_39_Template, 2, 2, "option", 81, _forTrack2);
|
|
809
820
|
i0.ɵɵelementEnd()();
|
|
810
|
-
i0.ɵɵelementStart(40, "div", 143)(41, "label",
|
|
821
|
+
i0.ɵɵelementStart(40, "div", 143)(41, "label", 73);
|
|
811
822
|
i0.ɵɵtext(42, "Vector Database");
|
|
812
823
|
i0.ɵɵelementEnd();
|
|
813
|
-
i0.ɵɵelementStart(43, "select",
|
|
824
|
+
i0.ɵɵelementStart(43, "select", 80);
|
|
814
825
|
i0.ɵɵtwoWayListener("ngModelChange", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Template_select_ngModelChange_43_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r1 = i0.ɵɵnextContext(4); i0.ɵɵtwoWayBindingSet(ctx_r1.SelectedVectorDBID, $event) || (ctx_r1.SelectedVectorDBID = $event); return i0.ɵɵresetView($event); });
|
|
815
|
-
i0.ɵɵrepeaterCreate(44, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_For_45_Template, 2, 2, "option",
|
|
826
|
+
i0.ɵɵrepeaterCreate(44, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_For_45_Template, 2, 2, "option", 81, _forTrack2);
|
|
816
827
|
i0.ɵɵelementEnd()();
|
|
817
|
-
i0.ɵɵelementStart(46, "div", 143)(47, "label",
|
|
828
|
+
i0.ɵɵelementStart(46, "div", 143)(47, "label", 73);
|
|
818
829
|
i0.ɵɵtext(48, "Vector Index");
|
|
819
830
|
i0.ɵɵelementEnd();
|
|
820
|
-
i0.ɵɵconditionalCreate(49, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Conditional_49_Template, 5, 1, "select",
|
|
831
|
+
i0.ɵɵconditionalCreate(49, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Conditional_49_Template, 5, 1, "select", 82)(50, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Conditional_50_Template, 2, 0, "span", 83);
|
|
821
832
|
i0.ɵɵelementEnd()();
|
|
822
833
|
i0.ɵɵelementStart(51, "div", 144);
|
|
823
834
|
i0.ɵɵconditionalCreate(52, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Conditional_52_Template, 2, 0, "div", 145)(53, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Conditional_53_Template, 8, 0);
|
|
@@ -853,20 +864,20 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
853
864
|
} }
|
|
854
865
|
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Template(rf, ctx) { if (rf & 1) {
|
|
855
866
|
const _r18 = i0.ɵɵgetCurrentView();
|
|
856
|
-
i0.ɵɵelementStart(0, "div",
|
|
867
|
+
i0.ɵɵelementStart(0, "div", 64);
|
|
857
868
|
i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r18); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.CloseSuggestDialog()); });
|
|
858
|
-
i0.ɵɵelementStart(1, "div",
|
|
869
|
+
i0.ɵɵelementStart(1, "div", 110);
|
|
859
870
|
i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Template_div_click_1_listener($event) { return $event.stopPropagation(); });
|
|
860
|
-
i0.ɵɵelementStart(2, "div",
|
|
871
|
+
i0.ɵɵelementStart(2, "div", 66)(3, "h3", 67);
|
|
861
872
|
i0.ɵɵelement(4, "i", 19);
|
|
862
873
|
i0.ɵɵtext(5, " AI Document Suggestion ");
|
|
863
874
|
i0.ɵɵelementEnd();
|
|
864
|
-
i0.ɵɵelementStart(6, "button",
|
|
875
|
+
i0.ɵɵelementStart(6, "button", 68);
|
|
865
876
|
i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r18); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.CloseSuggestDialog()); });
|
|
866
|
-
i0.ɵɵelement(7, "i",
|
|
877
|
+
i0.ɵɵelement(7, "i", 69);
|
|
867
878
|
i0.ɵɵelementEnd()();
|
|
868
|
-
i0.ɵɵelementStart(8, "div",
|
|
869
|
-
i0.ɵɵconditionalCreate(9, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_9_Template,
|
|
879
|
+
i0.ɵɵelementStart(8, "div", 70);
|
|
880
|
+
i0.ɵɵconditionalCreate(9, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_9_Template, 24, 9, "div", 71)(10, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Template, 54, 12, "div", 111);
|
|
870
881
|
i0.ɵɵelementEnd()()();
|
|
871
882
|
} if (rf & 2) {
|
|
872
883
|
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
@@ -895,7 +906,7 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Template(
|
|
|
895
906
|
i0.ɵɵelement(16, "i", 22);
|
|
896
907
|
i0.ɵɵtext(17, " Refresh ");
|
|
897
908
|
i0.ɵɵelementEnd()()();
|
|
898
|
-
i0.ɵɵconditionalCreate(18, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_18_Template, 1, 0, "mj-empty-state", 23)(19, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_19_Template,
|
|
909
|
+
i0.ɵɵconditionalCreate(18, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_18_Template, 1, 0, "mj-empty-state", 23)(19, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_19_Template, 21, 0, "div", 24);
|
|
899
910
|
i0.ɵɵelementEnd();
|
|
900
911
|
i0.ɵɵelementStart(20, "div", 25)(21, "div", 26)(22, "h4", 27);
|
|
901
912
|
i0.ɵɵelement(23, "i", 28);
|
|
@@ -937,7 +948,7 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Template(
|
|
|
937
948
|
i0.ɵɵtext(53);
|
|
938
949
|
i0.ɵɵpipe(54, "number");
|
|
939
950
|
i0.ɵɵelementEnd()()()()();
|
|
940
|
-
i0.ɵɵconditionalCreate(55, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Template,
|
|
951
|
+
i0.ɵɵconditionalCreate(55, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Template, 62, 14, "div", 45);
|
|
941
952
|
i0.ɵɵconditionalCreate(56, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_56_Template, 34, 5, "div", 45);
|
|
942
953
|
i0.ɵɵconditionalCreate(57, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_57_Template, 14, 0, "div", 45);
|
|
943
954
|
i0.ɵɵconditionalCreate(58, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Template, 11, 3, "div", 45);
|
|
@@ -1033,6 +1044,8 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
|
|
|
1033
1044
|
EditDocVectorIndexID = '';
|
|
1034
1045
|
EditDocStatus = '';
|
|
1035
1046
|
EditDocTemplate = '';
|
|
1047
|
+
/** Entity Document Type of the document being edited. Fixed at creation, shown read-only. */
|
|
1048
|
+
EditDocType = '';
|
|
1036
1049
|
IsEditRegenerating = false;
|
|
1037
1050
|
/** Parse {{ FieldName }} patterns from the edit panel's template */
|
|
1038
1051
|
get EditDocSelectedFields() {
|
|
@@ -1057,6 +1070,7 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
|
|
|
1057
1070
|
this.EditDocAIModelID = doc.AIModelID ?? '';
|
|
1058
1071
|
this.EditDocVectorIndexID = doc.VectorIndexID || '';
|
|
1059
1072
|
this.EditDocStatus = doc.Status;
|
|
1073
|
+
this.EditDocType = doc.Type || '';
|
|
1060
1074
|
this.EditDocTemplate = '';
|
|
1061
1075
|
this.IsEditRegenerating = false;
|
|
1062
1076
|
this.ShowEditPanel = true;
|
|
@@ -1162,10 +1176,17 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
|
|
|
1162
1176
|
async RegenerateTemplate() {
|
|
1163
1177
|
if (!this.EditDocEntityName || this.IsEditRegenerating)
|
|
1164
1178
|
return;
|
|
1179
|
+
// Ask for the use case this document's type stands for, so the regenerated template
|
|
1180
|
+
// still matches the type. Refuse rather than fall back to another use case.
|
|
1181
|
+
const useCase = SuggestionUseCaseForDocumentType(this.EditDocType);
|
|
1182
|
+
if (!useCase) {
|
|
1183
|
+
MJNotificationService.Instance.CreateSimpleNotification(`Can't regenerate: documents of type "${this.EditDocType || 'unknown'}" have no AI template use case.`, 'error', 5000);
|
|
1184
|
+
return;
|
|
1185
|
+
}
|
|
1165
1186
|
this.IsEditRegenerating = true;
|
|
1166
1187
|
this.cdr.detectChanges();
|
|
1167
1188
|
try {
|
|
1168
|
-
const result = await this.callSuggestionPrompt(this.EditDocEntityName,
|
|
1189
|
+
const result = await this.callSuggestionPrompt(this.EditDocEntityName, useCase);
|
|
1169
1190
|
if (result) {
|
|
1170
1191
|
this.EditDocTemplate = result.template;
|
|
1171
1192
|
MJNotificationService.Instance.CreateSimpleNotification('Template regenerated with AI. Review and save to apply.', 'info', 3000);
|
|
@@ -1896,6 +1917,15 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
|
|
|
1896
1917
|
try {
|
|
1897
1918
|
const result = await this.callSuggestionPrompt(this.SuggestEntityName, this.SuggestUseCase);
|
|
1898
1919
|
if (result) {
|
|
1920
|
+
// The field list is whatever the model returned — no cap, no filter. Bound it
|
|
1921
|
+
// here so an over-wide suggestion is visible immediately rather than at save.
|
|
1922
|
+
const capped = CapSelectedFields(result.selectedFields);
|
|
1923
|
+
if (capped.dropped > 0) {
|
|
1924
|
+
MJNotificationService.Instance.CreateSimpleNotification(`The suggestion selected ${capped.fields.length + capped.dropped} fields. ` +
|
|
1925
|
+
`Keeping the first ${MAX_TEMPLATE_FIELDS} and dropping ${capped.dropped} — a list ` +
|
|
1926
|
+
`this long usually means the whole table was pulled in. Check the template.`, 'warning', 6000);
|
|
1927
|
+
}
|
|
1928
|
+
result.selectedFields = capped.fields;
|
|
1899
1929
|
this.SuggestionResult = result;
|
|
1900
1930
|
this.EditableTemplate = result.template;
|
|
1901
1931
|
this.SaveDocumentName = `${this.SuggestEntityName} - ${this.SuggestUseCase}`;
|
|
@@ -1920,8 +1950,7 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
|
|
|
1920
1950
|
this.cdr.detectChanges();
|
|
1921
1951
|
try {
|
|
1922
1952
|
const md = this.ProviderToUse;
|
|
1923
|
-
const entityDoc = await
|
|
1924
|
-
entityDoc.NewRecord();
|
|
1953
|
+
const entityDoc = await this.findOrCreateEntityDocument();
|
|
1925
1954
|
entityDoc.Name = this.SaveDocumentName;
|
|
1926
1955
|
const matchingEntity = md.Entities.find(e => e.Name === this.SuggestEntityName);
|
|
1927
1956
|
if (matchingEntity) {
|
|
@@ -2069,6 +2098,7 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
|
|
|
2069
2098
|
EntityDocumentID: doc.ID,
|
|
2070
2099
|
EntityName: doc.Entity || '',
|
|
2071
2100
|
DocumentName: doc.Name,
|
|
2101
|
+
DocumentType: doc.Type || '',
|
|
2072
2102
|
VectorCount: vectorCount,
|
|
2073
2103
|
LastSynced: lastSynced,
|
|
2074
2104
|
Status: status,
|
|
@@ -2221,19 +2251,39 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
|
|
|
2221
2251
|
missing.push('Embedding Model');
|
|
2222
2252
|
throw new Error(`Prerequisites not configured: ${missing.join(', ')}. Go to the Configuration tab to set these up.`);
|
|
2223
2253
|
}
|
|
2224
|
-
// TypeID —
|
|
2254
|
+
// TypeID — from the use case the user actually chose. This used to be hardcoded to
|
|
2255
|
+
// 'Record Duplicate', so picking "search" in the dialog silently produced a
|
|
2256
|
+
// duplicate-detection document: the selection was discarded and the document was the
|
|
2257
|
+
// wrong type. A vector pool is typed — Provider.SearchEntity and the Search Entity
|
|
2258
|
+
// action read Search-typed documents — so the mislabelled document is also invisible
|
|
2259
|
+
// to the feature that asked for it.
|
|
2260
|
+
const wantedTypeName = EntityDocumentTypeForUseCase(this.SuggestUseCase);
|
|
2261
|
+
if (!wantedTypeName) {
|
|
2262
|
+
throw new Error(`No Entity Document Type is defined for the "${this.SuggestUseCase}" use case. ` +
|
|
2263
|
+
`Known use cases: ${Object.keys(ENTITY_DOCUMENT_TYPE_BY_USE_CASE).join(', ')}.`);
|
|
2264
|
+
}
|
|
2225
2265
|
const rv = RunView.FromMetadataProvider(this.ProviderToUse);
|
|
2226
2266
|
const typeResult = await rv.RunView({
|
|
2227
2267
|
EntityName: 'MJ: Entity Document Types',
|
|
2228
|
-
ExtraFilter: "Name = 'Record Duplicate'",
|
|
2229
2268
|
ResultType: 'simple',
|
|
2230
|
-
Fields: ['ID']
|
|
2269
|
+
Fields: ['ID', 'Name']
|
|
2231
2270
|
});
|
|
2232
|
-
|
|
2233
|
-
|
|
2271
|
+
const availableTypes = typeResult.Success ? typeResult.Results : [];
|
|
2272
|
+
// Trimmed, case-insensitive comparison — the same match EntityDocumentCache
|
|
2273
|
+
// .GetDocumentTypeByName makes server-side, so the dialog and the syncer agree.
|
|
2274
|
+
const wanted = wantedTypeName.trim().toLowerCase();
|
|
2275
|
+
const matchedType = availableTypes.find(t => t.Name?.trim().toLowerCase() === wanted);
|
|
2276
|
+
if (matchedType) {
|
|
2277
|
+
entityDoc.TypeID = matchedType.ID;
|
|
2234
2278
|
}
|
|
2235
2279
|
else {
|
|
2236
|
-
|
|
2280
|
+
// Never substitute a type that happens to exist: that is the defect above.
|
|
2281
|
+
const names = availableTypes.map(t => t.Name).sort();
|
|
2282
|
+
throw new Error(`Entity Document Type "${wantedTypeName}" not found in database. It is the type the ` +
|
|
2283
|
+
`"${this.SuggestUseCase}" use case needs, and no other type will be used in its place. ` +
|
|
2284
|
+
(names.length > 0
|
|
2285
|
+
? `Types that do exist: ${names.join(', ')}. Add "${wantedTypeName}" to MJ: Entity Document Types.`
|
|
2286
|
+
: 'No Entity Document Types exist at all.'));
|
|
2237
2287
|
}
|
|
2238
2288
|
// An explicitly chosen index fixes the DB + model. "Auto (create/find matching index)" resolves
|
|
2239
2289
|
// (or creates) the index for the chosen DB + model, so the syncer always has a VectorIndexID:
|
|
@@ -2297,12 +2347,33 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
|
|
|
2297
2347
|
if (!templateText) {
|
|
2298
2348
|
throw new Error('No template content to save');
|
|
2299
2349
|
}
|
|
2300
|
-
//
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2350
|
+
// LAYER 2: the template is hand-editable after the model returns, so a user can type
|
|
2351
|
+
// a field the picker never offered. Refuse before anything is written — once values
|
|
2352
|
+
// reach the vector index they are retrievable by similarity search, outside the
|
|
2353
|
+
// entity permissions that guard the source column, and not fully reversible.
|
|
2354
|
+
const sensitive = SensitiveFieldsInTemplate(templateText);
|
|
2355
|
+
if (sensitive.length > 0) {
|
|
2356
|
+
throw new Error(`This template references ${sensitive.length === 1 ? 'a field' : 'fields'} that must not be ` +
|
|
2357
|
+
`vectorized: ${sensitive.join(', ')}. Embedding copies the values into the vector index, ` +
|
|
2358
|
+
`where they are retrievable by similarity search rather than by an authorized query. ` +
|
|
2359
|
+
`Remove ${sensitive.length === 1 ? 'it' : 'them'} from the template and save again.`);
|
|
2360
|
+
}
|
|
2361
|
+
// The field list is unbounded and comes straight from a prompt, and the template stays
|
|
2362
|
+
// hand-editable after the model returns — so the authoritative bound is here, on what
|
|
2363
|
+
// actually gets embedded, not on the model's own description of what it picked.
|
|
2364
|
+
const capRefusal = TemplateFieldCapRefusal(templateText);
|
|
2365
|
+
if (capRefusal) {
|
|
2366
|
+
throw new Error(capRefusal);
|
|
2367
|
+
}
|
|
2368
|
+
// Find-or-create, so a retry after a mid-flow failure converges on one set of rows.
|
|
2369
|
+
const templateName = this.templateNameForDocument();
|
|
2370
|
+
const template = await this.findOrCreateTemplate(templateName, entityDoc.TemplateID);
|
|
2371
|
+
template.Name = templateName;
|
|
2304
2372
|
template.Description = `Auto-generated template for entity document: ${this.SaveDocumentName}`;
|
|
2305
|
-
template
|
|
2373
|
+
// An adopted template keeps its owner; only a new one is the current user's.
|
|
2374
|
+
if (!template.UserID) {
|
|
2375
|
+
template.UserID = md.CurrentUser.ID;
|
|
2376
|
+
}
|
|
2306
2377
|
template.IsActive = true;
|
|
2307
2378
|
const templateSaved = await template.Save();
|
|
2308
2379
|
if (!templateSaved) {
|
|
@@ -2322,8 +2393,7 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
|
|
|
2322
2393
|
// Create TemplateContent record with the template text
|
|
2323
2394
|
// Server-side MJTemplateContentEntityServer hook auto-creates Scalar params
|
|
2324
2395
|
// for each {{FieldName}} — GetTemplateData() handles them via the flat convention.
|
|
2325
|
-
const content = await
|
|
2326
|
-
content.NewRecord();
|
|
2396
|
+
const content = await this.findOrCreateTemplateContent(template.ID);
|
|
2327
2397
|
content.TemplateID = template.ID;
|
|
2328
2398
|
content.TypeID = contentTypeResult.Results[0].ID;
|
|
2329
2399
|
content.TemplateText = templateText;
|
|
@@ -2334,11 +2404,136 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
|
|
|
2334
2404
|
throw new Error(`Failed to create template content: ${content.LatestResult?.CompleteMessage || 'unknown error'}`);
|
|
2335
2405
|
}
|
|
2336
2406
|
}
|
|
2407
|
+
/** The Template name this dialog deterministically gives the current document. */
|
|
2408
|
+
templateNameForDocument() {
|
|
2409
|
+
return `Template for ${this.SaveDocumentName}`;
|
|
2410
|
+
}
|
|
2411
|
+
/**
|
|
2412
|
+
* The Entity Document for the current dialog, reusing the row an earlier attempt created
|
|
2413
|
+
* rather than adding a second one.
|
|
2414
|
+
*
|
|
2415
|
+
* This flow writes three rows — Template, Template Content, Entity Document — in that
|
|
2416
|
+
* order, and only the last is protected by a unique index (`UQ_EntityDocument_Name` on
|
|
2417
|
+
* `EntityDocument.Name`). So a duplicate was not a rare partial-failure case: that index
|
|
2418
|
+
* guarantees a second attempt with the same name fails at the final step, *after* the
|
|
2419
|
+
* Template and Template Content rows have been written again. Orphans accumulated one
|
|
2420
|
+
* pair per retry.
|
|
2421
|
+
*
|
|
2422
|
+
* Matched on Name, because that is the identity the database itself enforces.
|
|
2423
|
+
*
|
|
2424
|
+
* An existing document is adopted only when this dialog created it — its TemplateID points
|
|
2425
|
+
* at the template named `Template for <document name>` — and only for the same entity, so a
|
|
2426
|
+
* retry never moves another entity's document. A collision with a document
|
|
2427
|
+
* authored anywhere else is refused, because silently overwriting somebody's configured
|
|
2428
|
+
* document is worse than asking for a different name.
|
|
2429
|
+
*/
|
|
2430
|
+
async findOrCreateEntityDocument() {
|
|
2431
|
+
const md = this.ProviderToUse;
|
|
2432
|
+
const rv = RunView.FromMetadataProvider(md);
|
|
2433
|
+
const existing = await rv.RunView({
|
|
2434
|
+
EntityName: 'MJ: Entity Documents',
|
|
2435
|
+
ExtraFilter: `Name='${EscapeSQLString(this.SaveDocumentName)}'`,
|
|
2436
|
+
ResultType: 'entity_object',
|
|
2437
|
+
MaxRows: 1,
|
|
2438
|
+
});
|
|
2439
|
+
if (existing.Success && existing.Results.length > 0) {
|
|
2440
|
+
const priorDoc = existing.Results[0];
|
|
2441
|
+
const ownTemplate = priorDoc.TemplateID
|
|
2442
|
+
? await this.templateHasName(priorDoc.TemplateID, this.templateNameForDocument())
|
|
2443
|
+
: false;
|
|
2444
|
+
if (!ownTemplate) {
|
|
2445
|
+
throw new Error(`An Entity Document named "${this.SaveDocumentName}" already exists and was not ` +
|
|
2446
|
+
`created here, so it will not be overwritten. Choose a different name.`);
|
|
2447
|
+
}
|
|
2448
|
+
// Adopting a document for another entity would move it to this one.
|
|
2449
|
+
const entity = md.Entities.find(e => e.Name === this.SuggestEntityName);
|
|
2450
|
+
if (entity && priorDoc.EntityID && !UUIDsEqual(priorDoc.EntityID, entity.ID)) {
|
|
2451
|
+
throw new Error(`An Entity Document named "${this.SaveDocumentName}" already exists for ` +
|
|
2452
|
+
`${priorDoc.Entity || 'another entity'}, so it will not be reused. Choose a different name.`);
|
|
2453
|
+
}
|
|
2454
|
+
return priorDoc;
|
|
2455
|
+
}
|
|
2456
|
+
const entityDoc = await md.GetEntityObject('MJ: Entity Documents');
|
|
2457
|
+
entityDoc.NewRecord();
|
|
2458
|
+
return entityDoc;
|
|
2459
|
+
}
|
|
2460
|
+
/**
|
|
2461
|
+
* The Template for the current document, reusing an earlier attempt's row.
|
|
2462
|
+
*
|
|
2463
|
+
* An adopted Entity Document already points at its template (findOrCreateEntityDocument
|
|
2464
|
+
* checked its name), so that row is reused by ID. Matching it on Name + UserID instead
|
|
2465
|
+
* misses it when another user created it, writes a second template, re-points the document
|
|
2466
|
+
* and orphans the first Template and Template Content.
|
|
2467
|
+
*
|
|
2468
|
+
* For a new document, matched on Name + UserID: `Template` carries no unique index, and that
|
|
2469
|
+
* pair is exactly what this flow writes, so it identifies our own prior row without claiming
|
|
2470
|
+
* anyone else's.
|
|
2471
|
+
*/
|
|
2472
|
+
async findOrCreateTemplate(templateName, adoptedTemplateId) {
|
|
2473
|
+
const md = this.ProviderToUse;
|
|
2474
|
+
const rv = RunView.FromMetadataProvider(md);
|
|
2475
|
+
const existing = await rv.RunView({
|
|
2476
|
+
EntityName: 'MJ: Templates',
|
|
2477
|
+
ExtraFilter: adoptedTemplateId
|
|
2478
|
+
? `ID='${EscapeSQLString(adoptedTemplateId)}'`
|
|
2479
|
+
: `Name='${EscapeSQLString(templateName)}' AND UserID='${md.CurrentUser.ID}'`,
|
|
2480
|
+
ResultType: 'entity_object',
|
|
2481
|
+
MaxRows: 1,
|
|
2482
|
+
});
|
|
2483
|
+
if (existing.Success && existing.Results.length > 0) {
|
|
2484
|
+
return existing.Results[0];
|
|
2485
|
+
}
|
|
2486
|
+
const template = await md.GetEntityObject('MJ: Templates');
|
|
2487
|
+
template.NewRecord();
|
|
2488
|
+
return template;
|
|
2489
|
+
}
|
|
2490
|
+
/**
|
|
2491
|
+
* The Template Content row for a template, reusing the one it already has.
|
|
2492
|
+
*
|
|
2493
|
+
* `Priority ASC`, first row, is how loadEditDocTemplate and saveEditDocTemplate already
|
|
2494
|
+
* identify "the" content of a template — this follows that convention rather than adding
|
|
2495
|
+
* a second one.
|
|
2496
|
+
*/
|
|
2497
|
+
async findOrCreateTemplateContent(templateId) {
|
|
2498
|
+
const md = this.ProviderToUse;
|
|
2499
|
+
const rv = RunView.FromMetadataProvider(md);
|
|
2500
|
+
const existing = await rv.RunView({
|
|
2501
|
+
EntityName: 'MJ: Template Contents',
|
|
2502
|
+
ExtraFilter: `TemplateID='${templateId}'`,
|
|
2503
|
+
ResultType: 'entity_object',
|
|
2504
|
+
OrderBy: 'Priority ASC',
|
|
2505
|
+
MaxRows: 1,
|
|
2506
|
+
});
|
|
2507
|
+
if (existing.Success && existing.Results.length > 0) {
|
|
2508
|
+
return existing.Results[0];
|
|
2509
|
+
}
|
|
2510
|
+
const content = await md.GetEntityObject('MJ: Template Contents');
|
|
2511
|
+
content.NewRecord();
|
|
2512
|
+
return content;
|
|
2513
|
+
}
|
|
2514
|
+
/** True when the template with this ID carries the given name. */
|
|
2515
|
+
async templateHasName(templateId, name) {
|
|
2516
|
+
const rv = RunView.FromMetadataProvider(this.ProviderToUse);
|
|
2517
|
+
const result = await rv.RunView({
|
|
2518
|
+
EntityName: 'MJ: Templates',
|
|
2519
|
+
ExtraFilter: `ID='${templateId}'`,
|
|
2520
|
+
Fields: ['Name'],
|
|
2521
|
+
ResultType: 'simple',
|
|
2522
|
+
MaxRows: 1,
|
|
2523
|
+
});
|
|
2524
|
+
return result.Success && result.Results.length > 0 && result.Results[0].Name === name;
|
|
2525
|
+
}
|
|
2337
2526
|
/** Build grouped entity list from metadata, grouped by SchemaName */
|
|
2338
2527
|
loadEntityGroups() {
|
|
2339
2528
|
const md = this.ProviderToUse;
|
|
2340
2529
|
const groupMap = new Map();
|
|
2341
2530
|
for (const entity of md.Entities) {
|
|
2531
|
+
// The picker used to list every entity in metadata, so MJ's own internal entities
|
|
2532
|
+
// were offered as vectorization targets. See vector-document-rules.ts for the rule
|
|
2533
|
+
// and the precedent it follows.
|
|
2534
|
+
if (!IsVectorizableEntity(entity)) {
|
|
2535
|
+
continue;
|
|
2536
|
+
}
|
|
2342
2537
|
const schema = entity.SchemaName || '__default';
|
|
2343
2538
|
const existing = groupMap.get(schema);
|
|
2344
2539
|
if (existing) {
|
|
@@ -2453,7 +2648,9 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
|
|
|
2453
2648
|
}
|
|
2454
2649
|
/** Build the data payload for the suggestion prompt */
|
|
2455
2650
|
buildPromptData(entity, useCase) {
|
|
2456
|
-
|
|
2651
|
+
// LAYER 1 of the sensitive-field refusal: the model never sees these columns, so it
|
|
2652
|
+
// cannot suggest them. See sensitive-fields.ts for why this cannot live in the prompt.
|
|
2653
|
+
const fields = WithoutSensitiveFields(entity.Fields).map(f => ({
|
|
2457
2654
|
Name: f.Name,
|
|
2458
2655
|
Type: f.Type,
|
|
2459
2656
|
IsPrimaryKey: f.IsPrimaryKey,
|
|
@@ -2468,8 +2665,9 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
|
|
|
2468
2665
|
.slice(0, 20)
|
|
2469
2666
|
.map(r => {
|
|
2470
2667
|
const relatedEntity = md.Entities.find(e => e.Name === r.RelatedEntity);
|
|
2668
|
+
// Layer 1 covers related entities too: their fields reach the model here.
|
|
2471
2669
|
const relFields = relatedEntity
|
|
2472
|
-
? relatedEntity.Fields
|
|
2670
|
+
? WithoutSensitiveFields(relatedEntity.Fields)
|
|
2473
2671
|
.filter(f => !f.IsPrimaryKey && f.Type !== 'datetimeoffset')
|
|
2474
2672
|
.map(f => f.Name)
|
|
2475
2673
|
: [];
|
|
@@ -2493,7 +2691,7 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
|
|
|
2493
2691
|
} if (rf & 2) {
|
|
2494
2692
|
let _t;
|
|
2495
2693
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.EntitySearchInput = _t.first);
|
|
2496
|
-
} }, inputs: { HideToolbar: "HideToolbar" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 4, vars: 2, consts: [["vectorBody", ""], ["entitySearchInput", ""], ["Title", "Vector Management", "Icon", "fa-solid fa-cubes", "Subtitle", "Vector index health, embeddings, and entity sync status"], ["actions", ""], [3, "KeyChange", "Options", "ActiveKey"], [3, "Flex"], [4, "ngTemplateOutlet"], [1, "vector-loading"], ["text", "Loading vector management data..."], [1, "vector-dashboard"], [1, "kpi-row"], [3, "data"], [1, "content-area"], [1, "sync-table-panel"], [1, "panel-header"], [1, "panel-title"], [1, "fa-solid", "fa-table-list"], [1, "panel-actions"], ["title", "Use AI to suggest an Entity Document template", 1, "suggest-btn", 3, "click"], [1, "fa-solid", "fa-wand-magic-sparkles"], [1, "suggest-btn-text"], ["title", "Refresh data", 1, "refresh-btn", 3, "click"], [1, "fa-solid", "fa-arrows-rotate"], ["Icon", "fa-solid fa-folder-open", "Title", "No entity documents configured for vectorization."], [1, "table-wrapper"], [1, "sidebar"], [1, "sidebar-card"], [1, "sidebar-title"], [1, "fa-solid", "fa-heart-pulse"], [1, "health-row"], [1, "health-dot"], [1, "health-label"], [1, "health-status", 3, "title"], [1, "health-reason"], [1, "fa-solid", "fa-microchip"], [1, "model-info"], [1, "info-row"], [1, "info-label"], [1, "info-value", 3, "title"], [1, "fa-solid", "fa-hard-drive"], [1, "gauge-container"], [1, "gauge-bar"], [1, "gauge-fill"], [1, "gauge-label"], [1, "storage-detail"], [1, "slide-panel-overlay"], [1, "sync-table"], [1, "text-right"], [1, "text-center"], [1, "entity-name"], [1, "document-name"], [1, "text-right", "vector-count"], [1, "last-synced"], [1, "status-badge"], [1, "text-center", "actions-cell"], ["title", "Sync now", 1, "sync-btn", 3, "click", "disabled"], ["title", "Schedule recurring sync", 1, "schedule-btn", 3, "click"], [1, "fa-regular", "fa-clock"], ["title", "Edit entity document", 1, "edit-btn", 3, "click"], [1, "fa-solid", "fa-pen"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "fa-solid", "fa-play"], [1, "info-value"], [1, "slide-panel-overlay", 3, "click"], [1, "slide-panel", "open", 3, "click"], [1, "suggest-dialog-header"], [1, "suggest-dialog-title"], [1, "suggest-close-btn", 3, "click"], [1, "fa-solid", "fa-times"], [1, "suggest-dialog-body"], [1, "suggest-form"], [1, "suggest-field"], [1, "suggest-label"], [1, "edit-readonly-value"], [1, "edit-template-header"], ["title", "Regenerate template using AI", 1, "edit-regenerate-btn", 3, "click", "disabled"], [1, "template-editor-wrapper"], ["language", "markdown", 3, "change", "value", "readonly", "lineWrapping"], ["type", "text", 1, "suggest-input", 3, "ngModelChange", "ngModel"], [1, "suggest-select", 3, "ngModelChange", "ngModel"], [3, "value"], [1, "suggest-select", 3, "ngModel"], [1, "edit-readonly-value", 2, "font-size", "13px", "color", "var(--mj-text-muted)"], ["value", "Active"], ["value", "Inactive"], [1, "result-actions", 2, "margin-top", "1rem"], ["text", "Saving...", "size", "small"], [1, "result-tags"], [1, "result-tag"], ["value", ""], [1, "suggest-submit-btn", 3, "click"], [1, "fa-solid", "fa-save"], [1, "edit-delete-btn", 3, "click"], [1, "fa-solid", "fa-trash-can"], [1, "suggest-close-action", 3, "click"], [1, "schedule-dialog", 3, "click"], ["type", "text", "placeholder", "0 2 * * *", 1, "suggest-input", 3, "ngModelChange", "ngModel"], [1, "schedule-cron-preview"], [1, "fa-solid", "fa-info-circle"], [1, "suggest-field", "schedule-toggle-row"], ["type", "checkbox", 1, "mj-checkbox", 3, "ngModelChange", "ngModel"], [1, "fa-solid", "fa-check"], [1, "no-index-warning-dialog", 3, "click"], [1, "no-index-warning-icon"], [1, "fa-solid", "fa-triangle-exclamation"], [1, "no-index-warning-title"], [1, "no-index-warning-message"], [1, "no-index-warning-actions"], [1, "fa-solid", "fa-gear"], [1, "slide-panel", 3, "click"], [1, "suggest-result"], [1, "entity-picker"], [1, "entity-picker-trigger", 3, "click"], [1, "fa-solid", "fa-chevron-down", "entity-picker-arrow"], [1, "entity-picker-dropdown"], [1, "use-case-options"], [1, "use-case-btn", 3, "click"], [1, "fa-solid", "fa-clone"], [1, "fa-solid", "fa-magnifying-glass"], [1, "
|
|
2694
|
+
} }, inputs: { HideToolbar: "HideToolbar" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 4, vars: 2, consts: [["vectorBody", ""], ["entitySearchInput", ""], ["Title", "Vector Management", "Icon", "fa-solid fa-cubes", "Subtitle", "Vector index health, embeddings, and entity sync status"], ["actions", ""], [3, "KeyChange", "Options", "ActiveKey"], [3, "Flex"], [4, "ngTemplateOutlet"], [1, "vector-loading"], ["text", "Loading vector management data..."], [1, "vector-dashboard"], [1, "kpi-row"], [3, "data"], [1, "content-area"], [1, "sync-table-panel"], [1, "panel-header"], [1, "panel-title"], [1, "fa-solid", "fa-table-list"], [1, "panel-actions"], ["title", "Use AI to suggest an Entity Document template", 1, "suggest-btn", 3, "click"], [1, "fa-solid", "fa-wand-magic-sparkles"], [1, "suggest-btn-text"], ["title", "Refresh data", 1, "refresh-btn", 3, "click"], [1, "fa-solid", "fa-arrows-rotate"], ["Icon", "fa-solid fa-folder-open", "Title", "No entity documents configured for vectorization."], [1, "table-wrapper"], [1, "sidebar"], [1, "sidebar-card"], [1, "sidebar-title"], [1, "fa-solid", "fa-heart-pulse"], [1, "health-row"], [1, "health-dot"], [1, "health-label"], [1, "health-status", 3, "title"], [1, "health-reason"], [1, "fa-solid", "fa-microchip"], [1, "model-info"], [1, "info-row"], [1, "info-label"], [1, "info-value", 3, "title"], [1, "fa-solid", "fa-hard-drive"], [1, "gauge-container"], [1, "gauge-bar"], [1, "gauge-fill"], [1, "gauge-label"], [1, "storage-detail"], [1, "slide-panel-overlay"], [1, "sync-table"], [1, "text-right"], [1, "text-center"], [1, "entity-name"], [1, "document-name"], [1, "document-type"], [1, "text-right", "vector-count"], [1, "last-synced"], [1, "status-badge"], [1, "text-center", "actions-cell"], ["title", "Sync now", 1, "sync-btn", 3, "click", "disabled"], ["title", "Schedule recurring sync", 1, "schedule-btn", 3, "click"], [1, "fa-regular", "fa-clock"], ["title", "Edit entity document", 1, "edit-btn", 3, "click"], [1, "fa-solid", "fa-pen"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "fa-solid", "fa-play"], [1, "info-value"], [1, "slide-panel-overlay", 3, "click"], [1, "slide-panel", "open", 3, "click"], [1, "suggest-dialog-header"], [1, "suggest-dialog-title"], [1, "suggest-close-btn", 3, "click"], [1, "fa-solid", "fa-times"], [1, "suggest-dialog-body"], [1, "suggest-form"], [1, "suggest-field"], [1, "suggest-label"], [1, "edit-readonly-value"], [1, "edit-template-header"], ["title", "Regenerate template using AI", 1, "edit-regenerate-btn", 3, "click", "disabled"], [1, "template-editor-wrapper"], ["language", "markdown", 3, "change", "value", "readonly", "lineWrapping"], ["type", "text", 1, "suggest-input", 3, "ngModelChange", "ngModel"], [1, "suggest-select", 3, "ngModelChange", "ngModel"], [3, "value"], [1, "suggest-select", 3, "ngModel"], [1, "edit-readonly-value", 2, "font-size", "13px", "color", "var(--mj-text-muted)"], ["value", "Active"], ["value", "Inactive"], [1, "result-actions", 2, "margin-top", "1rem"], ["text", "Saving...", "size", "small"], [1, "result-tags"], [1, "result-tag"], ["value", ""], [1, "suggest-submit-btn", 3, "click"], [1, "fa-solid", "fa-save"], [1, "edit-delete-btn", 3, "click"], [1, "fa-solid", "fa-trash-can"], [1, "suggest-close-action", 3, "click"], [1, "schedule-dialog", 3, "click"], ["type", "text", "placeholder", "0 2 * * *", 1, "suggest-input", 3, "ngModelChange", "ngModel"], [1, "schedule-cron-preview"], [1, "fa-solid", "fa-info-circle"], [1, "suggest-field", "schedule-toggle-row"], ["type", "checkbox", 1, "mj-checkbox", 3, "ngModelChange", "ngModel"], [1, "fa-solid", "fa-check"], [1, "no-index-warning-dialog", 3, "click"], [1, "no-index-warning-icon"], [1, "fa-solid", "fa-triangle-exclamation"], [1, "no-index-warning-title"], [1, "no-index-warning-message"], [1, "no-index-warning-actions"], [1, "fa-solid", "fa-gear"], [1, "slide-panel", 3, "click"], [1, "suggest-result"], [1, "entity-picker"], [1, "entity-picker-trigger", 3, "click"], [1, "fa-solid", "fa-chevron-down", "entity-picker-arrow"], [1, "entity-picker-dropdown"], [1, "use-case-options"], [1, "use-case-btn", 3, "click"], [1, "fa-solid", "fa-clone"], [1, "fa-solid", "fa-magnifying-glass"], [1, "suggest-submit-btn", 3, "click", "disabled"], ["Variant", "error", "Size", "sm"], [1, "fa-solid", "fa-table"], [1, "entity-picker-value"], [1, "fa-solid", "fa-search"], [1, "entity-picker-placeholder"], [1, "entity-picker-dropdown", 3, "mousedown"], [1, "entity-picker-search"], ["type", "text", "placeholder", "Filter entities...", 1, "entity-picker-search-input", 3, "ngModelChange", "input", "keydown", "ngModel"], [1, "entity-picker-list"], [1, "entity-picker-group"], [1, "entity-picker-empty"], [1, "entity-picker-group-header"], [1, "fa-solid", "fa-database"], [1, "entity-picker-item", 3, "entity-picker-item-selected", "entity-picker-item-focused"], [1, "entity-picker-item", 3, "click"], [1, "result-section"], [1, "result-heading"], [1, "result-section", "result-thresholds"], [1, "threshold-item"], [1, "threshold-label"], [1, "threshold-value"], [1, "result-reasoning"], [1, "suggest-field", 2, "margin-top", "0.75rem"], [1, "result-actions"], [1, "save-spinner"], [1, "result-relationship"], [1, "rel-name"], [1, "rel-fields"], [1, "fa-solid", "fa-floppy-disk"], [1, "suggest-submit-btn", "suggest-try-again-btn", 3, "click"], [1, "fa-solid", "fa-rotate"]], template: function VectorManagementResourceComponent_Template(rf, ctx) { if (rf & 1) {
|
|
2497
2695
|
i0.ɵɵconditionalCreate(0, VectorManagementResourceComponent_Conditional_0_Template, 6, 4, "mj-page-layout");
|
|
2498
2696
|
i0.ɵɵconditionalCreate(1, VectorManagementResourceComponent_Conditional_1_Template, 1, 1, "ng-container");
|
|
2499
2697
|
i0.ɵɵtemplate(2, VectorManagementResourceComponent_ng_template_2_Template, 2, 1, "ng-template", null, 0, i0.ɵɵtemplateRefExtractor);
|
|
@@ -2501,7 +2699,7 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
|
|
|
2501
2699
|
i0.ɵɵconditional(!ctx.HideToolbar ? 0 : -1);
|
|
2502
2700
|
i0.ɵɵadvance();
|
|
2503
2701
|
i0.ɵɵconditional(ctx.HideToolbar ? 1 : -1);
|
|
2504
|
-
} }, dependencies: [i1.NgTemplateOutlet, i2.NgSelectOption, i2.ɵNgSelectMultipleOption, i2.DefaultValueAccessor, i2.CheckboxControlValueAccessor, i2.SelectControlValueAccessor, i2.NgControlStatus, i2.NgModel, i3.CodeEditorComponent, i4.LoadingComponent, i5.KPICardComponent, i6.MJPageHeaderComponent, i6.MJPageLayoutComponent, i6.MJPageBodyComponent, i6.MJViewToggleComponent, i6.MJEmptyStateComponent, i6.MJAlertComponent, i1.DecimalPipe], styles: ["\n\n\n\n\n\n\n.vector-loading[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 400px;\n}\n\n\n.view-mode-toggle[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.25rem;\n padding: 0 24px 0;\n margin-bottom: -12px;\n}\n\n.view-mode-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n padding: 0.4rem 0.85rem;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 0.82rem;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.view-mode-btn[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n}\n\n.view-mode-btn-active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n\n.vector-dashboard[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 24px;\n padding: 24px;\n background: var(--mj-bg-page);\n min-height: 100%;\n}\n\n\n.kpi-row[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 16px;\n}\n\n@media (max-width: 1200px) {\n .kpi-row[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n}\n\n@media (max-width: 600px) {\n .kpi-row[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n}\n\n\n.content-area[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 1fr 300px;\n gap: 24px;\n align-items: start;\n}\n\n@media (max-width: 1024px) {\n .content-area[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n}\n\n\n.sync-table-panel[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n overflow: hidden;\n}\n\n.panel-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.panel-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 15px;\n font-weight: 600;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.panel-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 14px;\n}\n\n.refresh-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.refresh-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n border-color: var(--mj-border-strong);\n}\n\n\n.table-wrapper[_ngcontent-%COMP%] {\n overflow-x: auto;\n}\n\n.sync-table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n}\n\n.sync-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n padding: 10px 16px;\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n text-align: left;\n white-space: nowrap;\n}\n\n.sync-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 12px 16px;\n font-size: 13px;\n color: var(--mj-text-primary);\n border-bottom: 1px solid var(--mj-border-subtle);\n vertical-align: middle;\n}\n\n.sync-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.sync-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:last-child td[_ngcontent-%COMP%] {\n border-bottom: none;\n}\n\n.text-right[_ngcontent-%COMP%] {\n text-align: right;\n}\n\n.text-center[_ngcontent-%COMP%] {\n text-align: center;\n}\n\n.entity-name[_ngcontent-%COMP%] {\n font-weight: 600;\n}\n\n.document-name[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n}\n\n.vector-count[_ngcontent-%COMP%] {\n font-variant-numeric: tabular-nums;\n font-weight: 600;\n}\n\n.last-synced[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n font-size: 12px;\n white-space: nowrap;\n}\n\n\n\n.actions-cell[_ngcontent-%COMP%] {\n display: flex;\n gap: 6px;\n align-items: center;\n justify-content: center;\n}\n\n.schedule-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 30px;\n height: 30px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: transparent;\n color: var(--mj-text-muted);\n font-size: 12px;\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.schedule-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n}\n\n.edit-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 30px;\n height: 30px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: transparent;\n color: var(--mj-text-muted);\n font-size: 12px;\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.edit-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n border-color: var(--mj-border-strong);\n}\n\n\n.schedule-dialog[_ngcontent-%COMP%] {\n width: 440px;\n max-width: 90vw;\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.2);\n overflow: hidden;\n}\n\n.schedule-cron-preview[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 0 0;\n font-size: 0.82rem;\n color: var(--mj-text-muted);\n}\n\n.schedule-toggle-row[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: 12px;\n}\n\n.edit-delete-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n border: 1px solid var(--mj-status-error-border);\n border-radius: 6px;\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n color: var(--mj-status-error-text);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.edit-delete-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-status-error) 20%, var(--mj-bg-surface));\n}\n\n.edit-readonly-value[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n padding: 8px 0;\n}\n\n\n.status-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 10px;\n border-radius: 999px;\n font-size: 11px;\n font-weight: 600;\n white-space: nowrap;\n}\n\n.status-synced[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 12%, var(--mj-bg-surface));\n color: var(--mj-status-success-text, var(--mj-status-success));\n}\n\n.status-syncing[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.status-error[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 12%, var(--mj-bg-surface));\n color: var(--mj-status-error-text, var(--mj-status-error));\n}\n\n.status-pending[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 12%, var(--mj-bg-surface));\n color: var(--mj-status-warning-text, var(--mj-status-warning));\n}\n\n\n.sync-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 5px 12px;\n border: 1px solid var(--mj-brand-primary);\n border-radius: 6px;\n background: transparent;\n color: var(--mj-brand-primary);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.sync-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.sync-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n\n\n\n.sidebar[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.sidebar-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n padding: 16px 20px;\n}\n\n.sidebar-title[_ngcontent-%COMP%] {\n margin: 0 0 14px 0;\n font-size: 13px;\n font-weight: 700;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.sidebar-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 13px;\n}\n\n\n.health-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 6px;\n}\n\n.health-dot[_ngcontent-%COMP%] {\n width: 10px;\n height: 10px;\n border-radius: 50%;\n flex-shrink: 0;\n}\n\n.health-healthy[_ngcontent-%COMP%] {\n background: var(--mj-status-success);\n box-shadow: 0 0 6px color-mix(in srgb, var(--mj-status-success) 50%, transparent);\n}\n\n.health-degraded[_ngcontent-%COMP%] {\n background: var(--mj-status-warning);\n box-shadow: 0 0 6px color-mix(in srgb, var(--mj-status-warning) 50%, transparent);\n}\n\n.health-offline[_ngcontent-%COMP%] {\n background: var(--mj-status-error);\n box-shadow: 0 0 6px color-mix(in srgb, var(--mj-status-error) 50%, transparent);\n}\n\n.health-label[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.health-status[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n padding-left: 18px;\n}\n\n.health-reason[_ngcontent-%COMP%] {\n font-size: 11px;\n line-height: 1.4;\n color: var(--mj-text-muted);\n padding-left: 18px;\n margin-top: 4px;\n}\n\n\n.model-info[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.info-row[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.info-label[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.info-value[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n\n.gauge-container[_ngcontent-%COMP%] {\n margin-bottom: 8px;\n}\n\n.gauge-bar[_ngcontent-%COMP%] {\n height: 8px;\n border-radius: 4px;\n background: var(--mj-bg-surface-sunken);\n overflow: hidden;\n margin-bottom: 6px;\n}\n\n.gauge-fill[_ngcontent-%COMP%] {\n height: 100%;\n border-radius: 4px;\n background: var(--mj-brand-primary);\n transition: width 0.6s cubic-bezier(0.4, 0, 0.2, 1);\n min-width: 2px;\n}\n\n.gauge-label[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n.storage-detail[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n\n.panel-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n\n.suggest-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border: 1px solid var(--mj-brand-primary);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.suggest-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary-hover);\n}\n\n\n.slide-panel-overlay[_ngcontent-%COMP%] {\n position: fixed;\n inset: 0;\n background: var(--mj-bg-overlay);\n z-index: 100000;\n}\n\n.slide-panel[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n right: 0;\n height: 100vh;\n width: 480px;\n max-width: 90vw;\n background: var(--mj-bg-surface);\n box-shadow: -4px 0 24px color-mix(in srgb, var(--mj-text-primary) 12%, transparent);\n transform: translateX(100%);\n transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n overflow-y: auto;\n}\n\n.slide-panel.open[_ngcontent-%COMP%] {\n transform: translateX(0);\n}\n\n.suggest-dialog-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px 24px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.suggest-dialog-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.suggest-dialog-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.suggest-close-btn[_ngcontent-%COMP%] {\n border: none;\n background: none;\n color: var(--mj-text-muted);\n font-size: 16px;\n cursor: pointer;\n padding: 4px;\n}\n\n.suggest-close-btn[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n}\n\n.suggest-dialog-body[_ngcontent-%COMP%] {\n padding: 24px;\n}\n\n\n.suggest-form[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.suggest-field[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.suggest-label[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n.suggest-select[_ngcontent-%COMP%] {\n padding: 8px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n}\n\n.suggest-select[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n\n\n.use-case-options[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n flex-wrap: wrap;\n}\n\n.use-case-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.use-case-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-border-strong);\n color: var(--mj-text-primary);\n}\n\n.use-case-btn-active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n.use-case-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n\n\n.entity-picker[_ngcontent-%COMP%] {\n position: relative;\n}\n\n.entity-picker-trigger[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n padding: 9px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n cursor: pointer;\n text-align: left;\n transition: border-color 0.15s;\n}\n\n.entity-picker-trigger[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-border-strong);\n}\n\n.entity-picker-placeholder[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n flex: 1;\n}\n\n.entity-picker-value[_ngcontent-%COMP%] {\n flex: 1;\n font-weight: 500;\n}\n\n.entity-picker-arrow[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--mj-text-muted);\n transition: transform 0.2s;\n}\n\n.entity-picker-dropdown[_ngcontent-%COMP%] {\n position: absolute;\n top: calc(100% + 4px);\n left: 0;\n right: 0;\n background: var(--mj-bg-surface-elevated, var(--mj-bg-surface));\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n box-shadow: 0 8px 32px color-mix(in srgb, var(--mj-text-primary) 15%, transparent);\n z-index: 100;\n max-height: 350px;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n.entity-picker-search[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 14px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.entity-picker-search[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 13px;\n}\n\n.entity-picker-search-input[_ngcontent-%COMP%] {\n flex: 1;\n border: none;\n background: transparent;\n color: var(--mj-text-primary);\n font-size: 13px;\n outline: none;\n}\n\n.entity-picker-search-input[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-disabled);\n}\n\n.entity-picker-list[_ngcontent-%COMP%] {\n overflow-y: auto;\n max-height: 300px;\n padding: 4px 0;\n}\n\n.entity-picker-group-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 14px 4px;\n font-size: 11px;\n font-weight: 700;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n position: sticky;\n top: 0;\n background: var(--mj-bg-surface-elevated, var(--mj-bg-surface));\n}\n\n.entity-picker-group-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n.entity-picker-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n padding: 7px 14px 7px 28px;\n border: none;\n background: transparent;\n color: var(--mj-text-primary);\n font-size: 13px;\n cursor: pointer;\n text-align: left;\n transition: background 0.1s;\n}\n\n.entity-picker-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.entity-picker-item-selected[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n.entity-picker-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.entity-picker-item-selected[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.entity-picker-item-focused[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-hover);\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: -2px;\n}\n\n.entity-picker-empty[_ngcontent-%COMP%] {\n padding: 20px 14px;\n text-align: center;\n color: var(--mj-text-disabled);\n font-size: 13px;\n}\n\n\n\n.template-editor-wrapper[_ngcontent-%COMP%] {\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n min-height: 120px;\n max-height: 300px;\n}\n\n.template-editor-wrapper[_ngcontent-%COMP%] .cm-editor {\n min-height: 120px;\n max-height: 300px;\n font-size: 13px;\n}\n\n.suggest-submit-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n padding: 10px 20px;\n border: none;\n border-radius: 6px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.2s ease;\n}\n\n.suggest-submit-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n\n.suggest-submit-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n\n.suggest-result[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.result-section[_ngcontent-%COMP%] {\n border-bottom: 1px solid var(--mj-border-subtle);\n padding-bottom: 12px;\n}\n\n.result-section[_ngcontent-%COMP%]:last-child {\n border-bottom: none;\n}\n\n.result-heading[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.result-template[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 6px;\n padding: 12px;\n font-size: 12px;\n color: var(--mj-text-primary);\n white-space: pre-wrap;\n word-break: break-all;\n margin: 0;\n}\n\n.result-tags[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n}\n\n.result-tag[_ngcontent-%COMP%] {\n padding: 3px 10px;\n border-radius: 12px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 12px;\n font-weight: 500;\n}\n\n.result-relationship[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 4px 0;\n}\n\n.rel-name[_ngcontent-%COMP%] {\n font-weight: 600;\n font-size: 13px;\n color: var(--mj-text-primary);\n}\n\n.rel-fields[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.result-thresholds[_ngcontent-%COMP%] {\n display: flex;\n gap: 24px;\n}\n\n.threshold-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.threshold-label[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.threshold-value[_ngcontent-%COMP%] {\n font-size: 18px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.result-reasoning[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 13px;\n color: var(--mj-text-secondary);\n line-height: 1.5;\n}\n\n.result-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n padding-top: 8px;\n}\n\n.suggest-close-action[_ngcontent-%COMP%] {\n padding: 10px 20px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n}\n\n.suggest-close-action[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n\n.suggest-input[_ngcontent-%COMP%] {\n padding: 8px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n width: 100%;\n box-sizing: border-box;\n}\n\n.suggest-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n\n.suggest-try-again-btn[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n border: 1px solid var(--mj-brand-primary);\n}\n\n.suggest-try-again-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n\n.save-spinner[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 8px 0;\n}\n\n\n.edit-template-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n}\n\n.edit-regenerate-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 10px;\n border: 1px solid var(--mj-brand-primary);\n border-radius: 6px;\n background: transparent;\n color: var(--mj-brand-primary);\n font-size: 11px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n white-space: nowrap;\n}\n\n.edit-regenerate-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.edit-regenerate-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n\n.no-index-warning-dialog[_ngcontent-%COMP%] {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 440px;\n max-width: 90vw;\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: 0 20px 60px color-mix(in srgb, var(--mj-text-primary) 20%, transparent);\n padding: 32px;\n text-align: center;\n}\n\n.no-index-warning-icon[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 56px;\n height: 56px;\n margin: 0 auto 16px;\n border-radius: 50%;\n background: color-mix(in srgb, var(--mj-status-warning) 12%, var(--mj-bg-surface));\n}\n\n.no-index-warning-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 24px;\n color: var(--mj-status-warning);\n}\n\n.no-index-warning-title[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: 18px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.no-index-warning-message[_ngcontent-%COMP%] {\n margin: 0 0 24px 0;\n font-size: 14px;\n line-height: 1.5;\n color: var(--mj-text-secondary);\n}\n\n.no-index-warning-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n justify-content: center;\n}\n\n\n\n\n\n@media (max-width: 768px) {\n .panel-header[_ngcontent-%COMP%] {\n flex-direction: column;\n align-items: flex-start;\n gap: 12px;\n }\n\n .panel-actions[_ngcontent-%COMP%] {\n flex-wrap: wrap;\n }\n}\n\n@media (max-width: 600px) {\n .slide-panel[_ngcontent-%COMP%] {\n width: 100vw;\n max-width: 100vw;\n }\n}\n\n@media (max-width: 480px) {\n .vector-dashboard[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .suggest-btn[_ngcontent-%COMP%] .suggest-btn-text[_ngcontent-%COMP%] {\n display: none;\n }\n}"] });
|
|
2702
|
+
} }, dependencies: [i1.NgTemplateOutlet, i2.NgSelectOption, i2.ɵNgSelectMultipleOption, i2.DefaultValueAccessor, i2.CheckboxControlValueAccessor, i2.SelectControlValueAccessor, i2.NgControlStatus, i2.NgModel, i3.CodeEditorComponent, i4.LoadingComponent, i5.KPICardComponent, i6.MJPageHeaderComponent, i6.MJPageLayoutComponent, i6.MJPageBodyComponent, i6.MJViewToggleComponent, i6.MJEmptyStateComponent, i6.MJAlertComponent, i1.DecimalPipe], styles: ["\n\n\n\n\n\n\n.vector-loading[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 400px;\n}\n\n\n.view-mode-toggle[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.25rem;\n padding: 0 24px 0;\n margin-bottom: -12px;\n}\n\n.view-mode-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n padding: 0.4rem 0.85rem;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 0.82rem;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.view-mode-btn[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n}\n\n.view-mode-btn-active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n\n.vector-dashboard[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 24px;\n padding: 24px;\n background: var(--mj-bg-page);\n min-height: 100%;\n}\n\n\n.kpi-row[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 16px;\n}\n\n@media (max-width: 1200px) {\n .kpi-row[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n}\n\n@media (max-width: 600px) {\n .kpi-row[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n}\n\n\n.content-area[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 1fr 300px;\n gap: 24px;\n align-items: start;\n}\n\n@media (max-width: 1024px) {\n .content-area[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n}\n\n\n.sync-table-panel[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n overflow: hidden;\n}\n\n.panel-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.panel-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 15px;\n font-weight: 600;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.panel-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 14px;\n}\n\n.refresh-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.refresh-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n border-color: var(--mj-border-strong);\n}\n\n\n.table-wrapper[_ngcontent-%COMP%] {\n overflow-x: auto;\n}\n\n.sync-table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n}\n\n.sync-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n padding: 10px 16px;\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n text-align: left;\n white-space: nowrap;\n}\n\n.sync-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 12px 16px;\n font-size: 13px;\n color: var(--mj-text-primary);\n border-bottom: 1px solid var(--mj-border-subtle);\n vertical-align: middle;\n}\n\n.sync-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.sync-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:last-child td[_ngcontent-%COMP%] {\n border-bottom: none;\n}\n\n.text-right[_ngcontent-%COMP%] {\n text-align: right;\n}\n\n.text-center[_ngcontent-%COMP%] {\n text-align: center;\n}\n\n.entity-name[_ngcontent-%COMP%] {\n font-weight: 600;\n}\n\n.document-name[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n}\n\n.document-type[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n white-space: nowrap;\n}\n\n.vector-count[_ngcontent-%COMP%] {\n font-variant-numeric: tabular-nums;\n font-weight: 600;\n}\n\n.last-synced[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n font-size: 12px;\n white-space: nowrap;\n}\n\n\n\n.actions-cell[_ngcontent-%COMP%] {\n display: flex;\n gap: 6px;\n align-items: center;\n justify-content: center;\n}\n\n.schedule-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 30px;\n height: 30px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: transparent;\n color: var(--mj-text-muted);\n font-size: 12px;\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.schedule-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n}\n\n.edit-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 30px;\n height: 30px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: transparent;\n color: var(--mj-text-muted);\n font-size: 12px;\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.edit-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n border-color: var(--mj-border-strong);\n}\n\n\n.schedule-dialog[_ngcontent-%COMP%] {\n width: 440px;\n max-width: 90vw;\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.2);\n overflow: hidden;\n}\n\n.schedule-cron-preview[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 0 0;\n font-size: 0.82rem;\n color: var(--mj-text-muted);\n}\n\n.schedule-toggle-row[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: 12px;\n}\n\n.edit-delete-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n border: 1px solid var(--mj-status-error-border);\n border-radius: 6px;\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n color: var(--mj-status-error-text);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.edit-delete-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-status-error) 20%, var(--mj-bg-surface));\n}\n\n.edit-readonly-value[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n padding: 8px 0;\n}\n\n\n.status-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 10px;\n border-radius: 999px;\n font-size: 11px;\n font-weight: 600;\n white-space: nowrap;\n}\n\n.status-synced[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 12%, var(--mj-bg-surface));\n color: var(--mj-status-success-text, var(--mj-status-success));\n}\n\n.status-syncing[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.status-error[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 12%, var(--mj-bg-surface));\n color: var(--mj-status-error-text, var(--mj-status-error));\n}\n\n.status-pending[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 12%, var(--mj-bg-surface));\n color: var(--mj-status-warning-text, var(--mj-status-warning));\n}\n\n\n.sync-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 5px 12px;\n border: 1px solid var(--mj-brand-primary);\n border-radius: 6px;\n background: transparent;\n color: var(--mj-brand-primary);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.sync-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.sync-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n\n\n\n.sidebar[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.sidebar-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n padding: 16px 20px;\n}\n\n.sidebar-title[_ngcontent-%COMP%] {\n margin: 0 0 14px 0;\n font-size: 13px;\n font-weight: 700;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.sidebar-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 13px;\n}\n\n\n.health-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 6px;\n}\n\n.health-dot[_ngcontent-%COMP%] {\n width: 10px;\n height: 10px;\n border-radius: 50%;\n flex-shrink: 0;\n}\n\n.health-healthy[_ngcontent-%COMP%] {\n background: var(--mj-status-success);\n box-shadow: 0 0 6px color-mix(in srgb, var(--mj-status-success) 50%, transparent);\n}\n\n.health-degraded[_ngcontent-%COMP%] {\n background: var(--mj-status-warning);\n box-shadow: 0 0 6px color-mix(in srgb, var(--mj-status-warning) 50%, transparent);\n}\n\n.health-offline[_ngcontent-%COMP%] {\n background: var(--mj-status-error);\n box-shadow: 0 0 6px color-mix(in srgb, var(--mj-status-error) 50%, transparent);\n}\n\n.health-label[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.health-status[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n padding-left: 18px;\n}\n\n.health-reason[_ngcontent-%COMP%] {\n font-size: 11px;\n line-height: 1.4;\n color: var(--mj-text-muted);\n padding-left: 18px;\n margin-top: 4px;\n}\n\n\n.model-info[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.info-row[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.info-label[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.info-value[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n\n.gauge-container[_ngcontent-%COMP%] {\n margin-bottom: 8px;\n}\n\n.gauge-bar[_ngcontent-%COMP%] {\n height: 8px;\n border-radius: 4px;\n background: var(--mj-bg-surface-sunken);\n overflow: hidden;\n margin-bottom: 6px;\n}\n\n.gauge-fill[_ngcontent-%COMP%] {\n height: 100%;\n border-radius: 4px;\n background: var(--mj-brand-primary);\n transition: width 0.6s cubic-bezier(0.4, 0, 0.2, 1);\n min-width: 2px;\n}\n\n.gauge-label[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n.storage-detail[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n\n.panel-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n\n.suggest-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border: 1px solid var(--mj-brand-primary);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.suggest-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary-hover);\n}\n\n\n.slide-panel-overlay[_ngcontent-%COMP%] {\n position: fixed;\n inset: 0;\n background: var(--mj-bg-overlay);\n z-index: 100000;\n}\n\n.slide-panel[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n right: 0;\n height: 100vh;\n width: 480px;\n max-width: 90vw;\n background: var(--mj-bg-surface);\n box-shadow: -4px 0 24px color-mix(in srgb, var(--mj-text-primary) 12%, transparent);\n transform: translateX(100%);\n transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n overflow-y: auto;\n}\n\n.slide-panel.open[_ngcontent-%COMP%] {\n transform: translateX(0);\n}\n\n.suggest-dialog-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px 24px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.suggest-dialog-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.suggest-dialog-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.suggest-close-btn[_ngcontent-%COMP%] {\n border: none;\n background: none;\n color: var(--mj-text-muted);\n font-size: 16px;\n cursor: pointer;\n padding: 4px;\n}\n\n.suggest-close-btn[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n}\n\n.suggest-dialog-body[_ngcontent-%COMP%] {\n padding: 24px;\n}\n\n\n.suggest-form[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.suggest-field[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.suggest-label[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n.suggest-select[_ngcontent-%COMP%] {\n padding: 8px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n}\n\n.suggest-select[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n\n\n.use-case-options[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n flex-wrap: wrap;\n}\n\n.use-case-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.use-case-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-border-strong);\n color: var(--mj-text-primary);\n}\n\n.use-case-btn-active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n.use-case-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n\n\n.entity-picker[_ngcontent-%COMP%] {\n position: relative;\n}\n\n.entity-picker-trigger[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n padding: 9px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n cursor: pointer;\n text-align: left;\n transition: border-color 0.15s;\n}\n\n.entity-picker-trigger[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-border-strong);\n}\n\n.entity-picker-placeholder[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n flex: 1;\n}\n\n.entity-picker-value[_ngcontent-%COMP%] {\n flex: 1;\n font-weight: 500;\n}\n\n.entity-picker-arrow[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--mj-text-muted);\n transition: transform 0.2s;\n}\n\n.entity-picker-dropdown[_ngcontent-%COMP%] {\n position: absolute;\n top: calc(100% + 4px);\n left: 0;\n right: 0;\n background: var(--mj-bg-surface-elevated, var(--mj-bg-surface));\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n box-shadow: 0 8px 32px color-mix(in srgb, var(--mj-text-primary) 15%, transparent);\n z-index: 100;\n max-height: 350px;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n.entity-picker-search[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 14px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.entity-picker-search[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 13px;\n}\n\n.entity-picker-search-input[_ngcontent-%COMP%] {\n flex: 1;\n border: none;\n background: transparent;\n color: var(--mj-text-primary);\n font-size: 13px;\n outline: none;\n}\n\n.entity-picker-search-input[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-disabled);\n}\n\n.entity-picker-list[_ngcontent-%COMP%] {\n overflow-y: auto;\n max-height: 300px;\n padding: 4px 0;\n}\n\n.entity-picker-group-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 14px 4px;\n font-size: 11px;\n font-weight: 700;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n position: sticky;\n top: 0;\n background: var(--mj-bg-surface-elevated, var(--mj-bg-surface));\n}\n\n.entity-picker-group-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n.entity-picker-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n padding: 7px 14px 7px 28px;\n border: none;\n background: transparent;\n color: var(--mj-text-primary);\n font-size: 13px;\n cursor: pointer;\n text-align: left;\n transition: background 0.1s;\n}\n\n.entity-picker-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.entity-picker-item-selected[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n.entity-picker-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.entity-picker-item-selected[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.entity-picker-item-focused[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-hover);\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: -2px;\n}\n\n.entity-picker-empty[_ngcontent-%COMP%] {\n padding: 20px 14px;\n text-align: center;\n color: var(--mj-text-disabled);\n font-size: 13px;\n}\n\n\n\n.template-editor-wrapper[_ngcontent-%COMP%] {\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n min-height: 120px;\n max-height: 300px;\n}\n\n.template-editor-wrapper[_ngcontent-%COMP%] .cm-editor {\n min-height: 120px;\n max-height: 300px;\n font-size: 13px;\n}\n\n.suggest-submit-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n padding: 10px 20px;\n border: none;\n border-radius: 6px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.2s ease;\n}\n\n.suggest-submit-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n\n.suggest-submit-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n\n.suggest-result[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.result-section[_ngcontent-%COMP%] {\n border-bottom: 1px solid var(--mj-border-subtle);\n padding-bottom: 12px;\n}\n\n.result-section[_ngcontent-%COMP%]:last-child {\n border-bottom: none;\n}\n\n.result-heading[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.result-template[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 6px;\n padding: 12px;\n font-size: 12px;\n color: var(--mj-text-primary);\n white-space: pre-wrap;\n word-break: break-all;\n margin: 0;\n}\n\n.result-tags[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n}\n\n.result-tag[_ngcontent-%COMP%] {\n padding: 3px 10px;\n border-radius: 12px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 12px;\n font-weight: 500;\n}\n\n.result-relationship[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 4px 0;\n}\n\n.rel-name[_ngcontent-%COMP%] {\n font-weight: 600;\n font-size: 13px;\n color: var(--mj-text-primary);\n}\n\n.rel-fields[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.result-thresholds[_ngcontent-%COMP%] {\n display: flex;\n gap: 24px;\n}\n\n.threshold-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.threshold-label[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.threshold-value[_ngcontent-%COMP%] {\n font-size: 18px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.result-reasoning[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 13px;\n color: var(--mj-text-secondary);\n line-height: 1.5;\n}\n\n.result-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n padding-top: 8px;\n}\n\n.suggest-close-action[_ngcontent-%COMP%] {\n padding: 10px 20px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n}\n\n.suggest-close-action[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n\n.suggest-input[_ngcontent-%COMP%] {\n padding: 8px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n width: 100%;\n box-sizing: border-box;\n}\n\n.suggest-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n\n.suggest-try-again-btn[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n border: 1px solid var(--mj-brand-primary);\n}\n\n.suggest-try-again-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n\n.save-spinner[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 8px 0;\n}\n\n\n.edit-template-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n}\n\n.edit-regenerate-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 10px;\n border: 1px solid var(--mj-brand-primary);\n border-radius: 6px;\n background: transparent;\n color: var(--mj-brand-primary);\n font-size: 11px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n white-space: nowrap;\n}\n\n.edit-regenerate-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.edit-regenerate-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n\n.no-index-warning-dialog[_ngcontent-%COMP%] {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 440px;\n max-width: 90vw;\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: 0 20px 60px color-mix(in srgb, var(--mj-text-primary) 20%, transparent);\n padding: 32px;\n text-align: center;\n}\n\n.no-index-warning-icon[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 56px;\n height: 56px;\n margin: 0 auto 16px;\n border-radius: 50%;\n background: color-mix(in srgb, var(--mj-status-warning) 12%, var(--mj-bg-surface));\n}\n\n.no-index-warning-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 24px;\n color: var(--mj-status-warning);\n}\n\n.no-index-warning-title[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: 18px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.no-index-warning-message[_ngcontent-%COMP%] {\n margin: 0 0 24px 0;\n font-size: 14px;\n line-height: 1.5;\n color: var(--mj-text-secondary);\n}\n\n.no-index-warning-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n justify-content: center;\n}\n\n\n\n\n\n@media (max-width: 768px) {\n .panel-header[_ngcontent-%COMP%] {\n flex-direction: column;\n align-items: flex-start;\n gap: 12px;\n }\n\n .panel-actions[_ngcontent-%COMP%] {\n flex-wrap: wrap;\n }\n}\n\n@media (max-width: 600px) {\n .slide-panel[_ngcontent-%COMP%] {\n width: 100vw;\n max-width: 100vw;\n }\n}\n\n@media (max-width: 480px) {\n .vector-dashboard[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .suggest-btn[_ngcontent-%COMP%] .suggest-btn-text[_ngcontent-%COMP%] {\n display: none;\n }\n}"] });
|
|
2505
2703
|
};
|
|
2506
2704
|
VectorManagementResourceComponent = __decorate([
|
|
2507
2705
|
RegisterClass(BaseResourceComponent, 'VectorManagementResource')
|
|
@@ -2509,14 +2707,14 @@ VectorManagementResourceComponent = __decorate([
|
|
|
2509
2707
|
export { VectorManagementResourceComponent };
|
|
2510
2708
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(VectorManagementResourceComponent, [{
|
|
2511
2709
|
type: Component,
|
|
2512
|
-
args: [{ standalone: false, selector: 'app-vector-management-resource', template: "@if (!HideToolbar) {\n <mj-page-layout>\n <mj-page-header\n Title=\"Vector Management\"\n Icon=\"fa-solid fa-cubes\"\n Subtitle=\"Vector index health, embeddings, and entity sync status\">\n <div actions>\n <mj-view-toggle\n [Options]=\"VectorViewOptions\"\n [ActiveKey]=\"ViewMode\"\n (KeyChange)=\"ViewMode = $any($event)\">\n </mj-view-toggle>\n </div>\n </mj-page-header>\n <mj-page-body [Flex]=\"true\">\n <ng-container *ngTemplateOutlet=\"vectorBody\"></ng-container>\n </mj-page-body>\n </mj-page-layout>\n}\n@if (HideToolbar) {\n <ng-container *ngTemplateOutlet=\"vectorBody\"></ng-container>\n}\n\n<ng-template #vectorBody>\n@if (IsLoading) {\n <div class=\"vector-loading\">\n <mj-loading text=\"Loading vector management data...\"></mj-loading>\n </div>\n} @else {\n <div class=\"vector-dashboard\">\n\n <!-- KPI Cards Row -->\n <div class=\"kpi-row\">\n @for (card of KPICards; track card.title) {\n <app-kpi-card [data]=\"card\"></app-kpi-card>\n }\n </div>\n\n <!-- Main Content Area: Table + Sidebar -->\n <div class=\"content-area\">\n <!-- Entity Sync Table -->\n <div class=\"sync-table-panel\">\n <div class=\"panel-header\">\n <h3 class=\"panel-title\">\n <i class=\"fa-solid fa-table-list\"></i>\n Entity Sync Status\n </h3>\n <div class=\"panel-actions\">\n <button class=\"suggest-btn\" (click)=\"OpenSuggestDialog()\" title=\"Use AI to suggest an Entity Document template\">\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i>\n <span class=\"suggest-btn-text\">Suggest Document</span>\n </button>\n <button class=\"refresh-btn\" (click)=\"LoadData(true)\" title=\"Refresh data\">\n <i class=\"fa-solid fa-arrows-rotate\"></i>\n Refresh\n </button>\n </div>\n </div>\n\n @if (SyncRows.length === 0) {\n <mj-empty-state Icon=\"fa-solid fa-folder-open\"\n Title=\"No entity documents configured for vectorization.\" />\n } @else {\n <div class=\"table-wrapper\">\n <table class=\"sync-table\">\n <thead>\n <tr>\n <th>Entity</th>\n <th>Document</th>\n <th class=\"text-right\">Vectors</th>\n <th>Last Synced</th>\n <th>Status</th>\n <th class=\"text-center\">Actions</th>\n </tr>\n </thead>\n <tbody>\n @for (row of SyncRows; track row.EntityDocumentID) {\n <tr>\n <td class=\"entity-name\">{{ row.EntityName }}</td>\n <td class=\"document-name\">{{ row.DocumentName }}</td>\n <td class=\"text-right vector-count\">{{ row.VectorCount | number }}</td>\n <td class=\"last-synced\">{{ FormatDate(row.LastSynced) }}</td>\n <td>\n <span class=\"status-badge\" [class]=\"GetStatusClass(row.Status)\">\n <i [class]=\"GetStatusIcon(row.Status)\"></i>\n @if (row.Status === 'Syncing' && row.PercentComplete > 0) {\n {{ row.PercentComplete }}%\n } @else {\n {{ row.Status }}\n }\n </span>\n </td>\n <td class=\"text-center actions-cell\">\n <button\n class=\"sync-btn\"\n [disabled]=\"IsSyncing(row.EntityDocumentID)\"\n (click)=\"SyncEntity(row.EntityDocumentID)\"\n title=\"Sync now\">\n @if (IsSyncing(row.EntityDocumentID)) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n {{ row.PercentComplete > 0 ? row.PercentComplete + '%' : 'Sync' }}\n } @else {\n <i class=\"fa-solid fa-play\"></i>\n Sync\n }\n </button>\n <button\n class=\"schedule-btn\"\n (click)=\"OpenScheduleSyncDialog(row.EntityDocumentID)\"\n title=\"Schedule recurring sync\">\n <i class=\"fa-regular fa-clock\"></i>\n </button>\n <button\n class=\"edit-btn\"\n (click)=\"OpenEditPanel(row.EntityDocumentID)\"\n title=\"Edit entity document\">\n <i class=\"fa-solid fa-pen\"></i>\n </button>\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n </div>\n\n <!-- Sidebar Panels -->\n <div class=\"sidebar\">\n <!-- Vector DB Health -->\n <div class=\"sidebar-card\">\n <h4 class=\"sidebar-title\">\n <i class=\"fa-solid fa-heart-pulse\"></i>\n Vector DB Health\n </h4>\n <div class=\"health-row\">\n <span class=\"health-dot\" [class]=\"DBHealthClass\"></span>\n <span class=\"health-label\">{{ VectorDBName }}</span>\n </div>\n <div class=\"health-status\" [title]=\"VectorDBStatusReason\">{{ VectorDBStatus }}</div>\n @if (VectorDBStatusReason) {\n <div class=\"health-reason\">{{ VectorDBStatusReason }}</div>\n }\n </div>\n\n <!-- Embedding Model Info -->\n <div class=\"sidebar-card\">\n <h4 class=\"sidebar-title\">\n <i class=\"fa-solid fa-microchip\"></i>\n Embedding Model\n </h4>\n <div class=\"model-info\">\n <div class=\"info-row\">\n <span class=\"info-label\">Model</span>\n <span class=\"info-value\" [title]=\"'Embeddings are generated by this model; the index above stores the resulting vectors.'\">{{ EmbeddingModel.Name }}</span>\n </div>\n @if (EmbeddingModel.Dimensions != null) {\n <div class=\"info-row\">\n <span class=\"info-label\">Dimensions</span>\n <span class=\"info-value\">{{ EmbeddingModel.Dimensions | number }}</span>\n </div>\n }\n </div>\n </div>\n\n <!-- Storage Usage -->\n <div class=\"sidebar-card\">\n <h4 class=\"sidebar-title\">\n <i class=\"fa-solid fa-hard-drive\"></i>\n Vectorization Coverage\n </h4>\n <div class=\"gauge-container\">\n <div class=\"gauge-bar\">\n <div class=\"gauge-fill\" [style.width.%]=\"StorageUsagePercent\"></div>\n </div>\n <div class=\"gauge-label\">{{ StorageLabel }} of records vectorized</div>\n </div>\n <div class=\"storage-detail\">\n {{ TotalVectors | number }} vectors stored\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Edit Entity Document Slide-in Panel -->\n @if (ShowEditPanel) {\n <div class=\"slide-panel-overlay\" (click)=\"CloseEditPanel()\">\n <div class=\"slide-panel open\" (click)=\"$event.stopPropagation()\">\n <div class=\"suggest-dialog-header\">\n <h3 class=\"suggest-dialog-title\">\n <i class=\"fa-solid fa-pen\"></i>\n Edit Entity Document\n </h3>\n <button class=\"suggest-close-btn\" (click)=\"CloseEditPanel()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n <div class=\"suggest-dialog-body\">\n <div class=\"suggest-form\">\n <div class=\"suggest-field\">\n <label class=\"suggest-label\">Entity</label>\n <span class=\"edit-readonly-value\">{{ EditDocEntityName }}</span>\n </div>\n\n <!-- Template Section -->\n <div class=\"suggest-field\">\n <div class=\"edit-template-header\">\n <label class=\"suggest-label\">Template</label>\n <button class=\"edit-regenerate-btn\"\n [disabled]=\"IsEditRegenerating\"\n (click)=\"RegenerateTemplate()\"\n title=\"Regenerate template using AI\">\n @if (IsEditRegenerating) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Regenerating...\n } @else {\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i> Regenerate with AI\n }\n </button>\n </div>\n <div class=\"template-editor-wrapper\">\n <mj-code-editor\n [value]=\"EditDocTemplate\"\n language=\"markdown\"\n [readonly]=\"false\"\n [lineWrapping]=\"true\"\n (change)=\"OnEditTemplateChange($event)\">\n </mj-code-editor>\n </div>\n </div>\n\n <!-- Selected Fields (parsed from template) -->\n @if (EditDocSelectedFields.length > 0) {\n <div class=\"suggest-field\">\n <label class=\"suggest-label\">Selected Fields</label>\n <div class=\"result-tags\">\n @for (field of EditDocSelectedFields; track field) {\n <span class=\"result-tag\">{{ field }}</span>\n }\n </div>\n </div>\n }\n\n <div class=\"suggest-field\">\n <label class=\"suggest-label\">Document Name</label>\n <input class=\"suggest-input\" type=\"text\" [(ngModel)]=\"EditDocName\" />\n </div>\n <div class=\"suggest-field\">\n <label class=\"suggest-label\">Embedding Model</label>\n <select class=\"suggest-select\" [(ngModel)]=\"EditDocAIModelID\">\n @for (model of AvailableEmbeddingModels; track model.ID) {\n <option [value]=\"model.ID\">{{ model.Name }}</option>\n }\n </select>\n </div>\n <div class=\"suggest-field\">\n <label class=\"suggest-label\">Vector Database</label>\n <select class=\"suggest-select\" [(ngModel)]=\"EditDocVectorDBID\">\n @for (db of vectorDatabases; track db.ID) {\n <option [value]=\"db.ID\">{{ db.Name }}</option>\n }\n </select>\n </div>\n <div class=\"suggest-field\">\n <label class=\"suggest-label\">Vector Index</label>\n @if (EditFilteredIndexes.length > 0) {\n <select class=\"suggest-select\" [(ngModel)]=\"EditDocVectorIndexID\">\n <option value=\"\">Auto (create/find matching index)</option>\n @for (idx of EditFilteredIndexes; track idx.ID) {\n <option [value]=\"idx.ID\">{{ idx.Name }}</option>\n }\n </select>\n } @else {\n <span class=\"edit-readonly-value\" style=\"font-size: 13px; color: var(--mj-text-muted);\">\n No indexes for this database \u2014 one will be created automatically on sync\n </span>\n }\n </div>\n <div class=\"suggest-field\">\n <label class=\"suggest-label\">Status</label>\n <select class=\"suggest-select\" [(ngModel)]=\"EditDocStatus\">\n <option value=\"Active\">Active</option>\n <option value=\"Inactive\">Inactive</option>\n </select>\n </div>\n <div class=\"result-actions\" style=\"margin-top: 1rem\">\n @if (IsEditSaving || IsEditDeleting) {\n <mj-loading text=\"Saving...\" size=\"small\"></mj-loading>\n } @else {\n <button class=\"suggest-submit-btn\" (click)=\"SaveEditedDocument()\">\n <i class=\"fa-solid fa-save\"></i> Save Changes\n </button>\n <button class=\"edit-delete-btn\" (click)=\"DeleteEntityDocument()\">\n <i class=\"fa-solid fa-trash-can\"></i> Delete\n </button>\n <button class=\"suggest-close-action\" (click)=\"CloseEditPanel()\">\n Cancel\n </button>\n }\n </div>\n </div>\n </div>\n </div>\n </div>\n }\n\n <!-- Schedule Sync Dialog -->\n @if (ShowScheduleSyncDialog) {\n <div class=\"slide-panel-overlay\" (click)=\"CloseScheduleSyncDialog()\">\n <div class=\"schedule-dialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"suggest-dialog-header\">\n <h3 class=\"suggest-dialog-title\">\n <i class=\"fa-regular fa-clock\"></i>\n Schedule Vector Sync\n </h3>\n <button class=\"suggest-close-btn\" (click)=\"CloseScheduleSyncDialog()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n <div class=\"suggest-dialog-body\">\n <div class=\"suggest-form\">\n <div class=\"suggest-field\">\n <label class=\"suggest-label\">Entity Document</label>\n <span class=\"edit-readonly-value\">{{ ScheduleSyncDocName }}</span>\n </div>\n <div class=\"suggest-field\">\n <label class=\"suggest-label\">Action</label>\n <span class=\"edit-readonly-value\">__VectorizeEntity</span>\n </div>\n <div class=\"suggest-field\">\n <label class=\"suggest-label\">Cron Expression</label>\n <input class=\"suggest-input\" type=\"text\" [(ngModel)]=\"ScheduleSyncCron\" placeholder=\"0 2 * * *\" />\n <div class=\"schedule-cron-preview\">\n <i class=\"fa-solid fa-info-circle\"></i>\n {{ GetScheduleCronPreview(ScheduleSyncCron) }}\n </div>\n </div>\n <div class=\"suggest-field schedule-toggle-row\">\n <label class=\"suggest-label\">Enabled</label>\n <input type=\"checkbox\" class=\"mj-checkbox\" [(ngModel)]=\"ScheduleSyncEnabled\" />\n </div>\n <div class=\"result-actions\" style=\"margin-top: 1rem\">\n @if (ScheduleSyncSaving) {\n <mj-loading text=\"Saving...\" size=\"small\"></mj-loading>\n } @else {\n <button class=\"suggest-submit-btn\" (click)=\"SaveScheduleSync()\">\n <i class=\"fa-solid fa-check\"></i> Create Schedule\n </button>\n <button class=\"suggest-close-action\" (click)=\"CloseScheduleSyncDialog()\">\n Cancel\n </button>\n }\n </div>\n </div>\n </div>\n </div>\n </div>\n }\n\n <!-- No Vector Index Warning Dialog -->\n @if (ShowNoIndexWarning) {\n <div class=\"slide-panel-overlay\" (click)=\"CloseNoIndexWarning()\">\n <div class=\"no-index-warning-dialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"no-index-warning-icon\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n </div>\n <h3 class=\"no-index-warning-title\">Vector Index Required</h3>\n <p class=\"no-index-warning-message\">\n You need to create at least one vector database and index before creating entity documents.\n Go to the Configuration section to set up a vector database and create an index.\n </p>\n <div class=\"no-index-warning-actions\">\n <button class=\"suggest-submit-btn\" (click)=\"GoToConfiguration()\">\n <i class=\"fa-solid fa-gear\"></i> Go to Configuration\n </button>\n <button class=\"suggest-close-action\" (click)=\"CloseNoIndexWarning()\">\n Close\n </button>\n </div>\n </div>\n </div>\n }\n\n <!-- Suggest Document Slide-in Panel -->\n @if (ShowSuggestDialog) {\n <div class=\"slide-panel-overlay\" (click)=\"CloseSuggestDialog()\">\n <div class=\"slide-panel\" [class.open]=\"ShowSuggestDialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"suggest-dialog-header\">\n <h3 class=\"suggest-dialog-title\">\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i>\n AI Document Suggestion\n </h3>\n <button class=\"suggest-close-btn\" (click)=\"CloseSuggestDialog()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n <div class=\"suggest-dialog-body\">\n @if (!SuggestionResult) {\n <div class=\"suggest-form\">\n <div class=\"suggest-field\">\n <label class=\"suggest-label\">Entity</label>\n <div class=\"entity-picker\">\n <button class=\"entity-picker-trigger\" (click)=\"ToggleEntityPicker()\">\n @if (SuggestEntityName) {\n <i class=\"fa-solid fa-table\"></i>\n <span class=\"entity-picker-value\">{{ SuggestEntityName }}</span>\n } @else {\n <i class=\"fa-solid fa-search\"></i>\n <span class=\"entity-picker-placeholder\">Search and select an entity...</span>\n }\n <i class=\"fa-solid fa-chevron-down entity-picker-arrow\"></i>\n </button>\n @if (ShowEntityPicker) {\n <div class=\"entity-picker-dropdown\" (mousedown)=\"$event.stopPropagation()\">\n <div class=\"entity-picker-search\">\n <i class=\"fa-solid fa-search\"></i>\n <input #entitySearchInput\n type=\"text\"\n class=\"entity-picker-search-input\"\n placeholder=\"Filter entities...\"\n [(ngModel)]=\"EntitySearchText\"\n (input)=\"FilterEntities()\"\n (keydown)=\"OnEntityPickerKeyDown($event)\" />\n </div>\n <div class=\"entity-picker-list\">\n @for (group of FilteredEntityGroups; track group.SchemaName) {\n <div class=\"entity-picker-group\">\n <div class=\"entity-picker-group-header\">\n <i class=\"fa-solid fa-database\"></i>\n {{ group.SchemaName }}\n </div>\n @for (entity of group.Entities; track entity.ID) {\n <button class=\"entity-picker-item\"\n [class.entity-picker-item-selected]=\"entity.Name === SuggestEntityName\"\n [class.entity-picker-item-focused]=\"FlatFilteredEntities[SelectedEntityIndex]?.ID === entity.ID\"\n (click)=\"SelectEntity(entity.Name)\">\n <i class=\"fa-solid fa-table\"></i>\n {{ entity.Name }}\n </button>\n }\n </div>\n }\n @if (FilteredEntityGroups.length === 0) {\n <div class=\"entity-picker-empty\">\n No entities matching \"{{ EntitySearchText }}\"\n </div>\n }\n </div>\n </div>\n }\n </div>\n </div>\n <div class=\"suggest-field\">\n <label class=\"suggest-label\">Use Case</label>\n <div class=\"use-case-options\">\n <button class=\"use-case-btn\"\n [class.use-case-btn-active]=\"SuggestUseCase === 'duplicate detection'\"\n (click)=\"SuggestUseCase = 'duplicate detection'\">\n <i class=\"fa-solid fa-clone\"></i>\n Duplicate Detection\n </button>\n <button class=\"use-case-btn\"\n [class.use-case-btn-active]=\"SuggestUseCase === 'search'\"\n (click)=\"SuggestUseCase = 'search'\">\n <i class=\"fa-solid fa-magnifying-glass\"></i>\n Search\n </button>\n <button class=\"use-case-btn\"\n [class.use-case-btn-active]=\"SuggestUseCase === 'classification'\"\n (click)=\"SuggestUseCase = 'classification'\">\n <i class=\"fa-solid fa-tags\"></i>\n Classification\n </button>\n </div>\n </div>\n <button class=\"suggest-submit-btn\"\n [disabled]=\"IsSuggesting || !SuggestEntityName\"\n (click)=\"RunSuggestion()\">\n @if (IsSuggesting) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Generating with AI...\n } @else {\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i> Generate Template\n }\n </button>\n @if (SuggestionError) {\n <mj-alert Variant=\"error\" Size=\"sm\">{{ SuggestionError }}</mj-alert>\n }\n </div>\n } @else {\n <div class=\"suggest-result\">\n <div class=\"result-section\">\n <h4 class=\"result-heading\">Suggested Template</h4>\n <div class=\"template-editor-wrapper\">\n <mj-code-editor\n [value]=\"EditableTemplate\"\n language=\"markdown\"\n [readonly]=\"false\"\n [lineWrapping]=\"true\"\n (change)=\"OnTemplateChange($event)\">\n </mj-code-editor>\n </div>\n </div>\n <div class=\"result-section\">\n <h4 class=\"result-heading\">Selected Fields</h4>\n <div class=\"result-tags\">\n @for (field of SuggestionResult.selectedFields; track field) {\n <span class=\"result-tag\">{{ field }}</span>\n }\n </div>\n </div>\n @if ((SuggestionResult.selectedRelationships?.length ?? 0) > 0) {\n <div class=\"result-section\">\n <h4 class=\"result-heading\">Related Entities</h4>\n @for (rel of SuggestionResult.selectedRelationships; track rel.name) {\n <div class=\"result-relationship\">\n <span class=\"rel-name\">{{ rel.name }}</span>\n <span class=\"rel-fields\">{{ rel.fields.join(', ') }}</span>\n </div>\n }\n </div>\n }\n <div class=\"result-section result-thresholds\">\n <div class=\"threshold-item\">\n <span class=\"threshold-label\">Potential Match</span>\n <span class=\"threshold-value\">{{ (SuggestionResult.potentialMatchThreshold * 100).toFixed(0) }}%</span>\n </div>\n <div class=\"threshold-item\">\n <span class=\"threshold-label\">Absolute Match</span>\n <span class=\"threshold-value\">{{ (SuggestionResult.absoluteMatchThreshold * 100).toFixed(0) }}%</span>\n </div>\n </div>\n <div class=\"result-section\">\n <h4 class=\"result-heading\">Reasoning</h4>\n <p class=\"result-reasoning\">{{ SuggestionResult.reasoning }}</p>\n </div>\n <div class=\"result-section\">\n <div class=\"suggest-field\">\n <label class=\"suggest-label\">Document Name</label>\n <input class=\"suggest-input\" type=\"text\" [(ngModel)]=\"SaveDocumentName\" />\n </div>\n <div class=\"suggest-field\" style=\"margin-top: 0.75rem\">\n <label class=\"suggest-label\">Embedding Model</label>\n <select class=\"suggest-select\" [(ngModel)]=\"SelectedEmbeddingModelID\">\n @for (model of AvailableEmbeddingModels; track model.ID) {\n <option [value]=\"model.ID\">{{ model.Name }}</option>\n }\n </select>\n </div>\n <div class=\"suggest-field\" style=\"margin-top: 0.75rem\">\n <label class=\"suggest-label\">Vector Database</label>\n <select class=\"suggest-select\" [(ngModel)]=\"SelectedVectorDBID\">\n @for (db of vectorDatabases; track db.ID) {\n <option [value]=\"db.ID\">{{ db.Name }}</option>\n }\n </select>\n </div>\n <div class=\"suggest-field\" style=\"margin-top: 0.75rem\">\n <label class=\"suggest-label\">Vector Index</label>\n @if (FilteredIndexesForSelectedDB.length > 0) {\n <select class=\"suggest-select\" [(ngModel)]=\"SelectedVectorIndexID\">\n <option value=\"\">Auto (create/find matching index)</option>\n @for (idx of FilteredIndexesForSelectedDB; track idx.ID) {\n <option [value]=\"idx.ID\">{{ idx.Name }}</option>\n }\n </select>\n } @else {\n <span class=\"edit-readonly-value\" style=\"font-size: 13px; color: var(--mj-text-muted);\">\n No indexes yet \u2014 create one in Configuration > Vector Database, or one will be created on sync\n </span>\n }\n </div>\n </div>\n <div class=\"result-actions\">\n @if (IsSavingDocument) {\n <div class=\"save-spinner\">\n <mj-loading text=\"Saving...\" size=\"small\"></mj-loading>\n </div>\n } @else {\n <button class=\"suggest-submit-btn\" (click)=\"SaveAsEntityDocument()\">\n <i class=\"fa-solid fa-floppy-disk\"></i> Save as Entity Document\n </button>\n <button class=\"suggest-submit-btn suggest-try-again-btn\" (click)=\"ClearSuggestion()\">\n <i class=\"fa-solid fa-rotate\"></i> Try Again\n </button>\n <button class=\"suggest-close-action\" (click)=\"CloseSuggestDialog()\">\n Close\n </button>\n }\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n }\n}\n</ng-template>\n", styles: ["/* ================================================================\n Vector Management Dashboard\n All colors use MJ design tokens from _tokens.scss\n ================================================================ */\n\n\n/* --- Loading state --- */\n.vector-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 400px;\n}\n\n/* --- View Mode Toggle --- */\n.view-mode-toggle {\n display: flex;\n gap: 0.25rem;\n padding: 0 24px 0;\n margin-bottom: -12px;\n}\n\n.view-mode-btn {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n padding: 0.4rem 0.85rem;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 0.82rem;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.view-mode-btn:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n}\n\n.view-mode-btn-active {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n/* --- Dashboard container --- */\n.vector-dashboard {\n display: flex;\n flex-direction: column;\n gap: 24px;\n padding: 24px;\n background: var(--mj-bg-page);\n min-height: 100%;\n}\n\n/* --- KPI cards row --- */\n.kpi-row {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 16px;\n}\n\n@media (max-width: 1200px) {\n .kpi-row {\n grid-template-columns: repeat(2, 1fr);\n }\n}\n\n@media (max-width: 600px) {\n .kpi-row {\n grid-template-columns: 1fr;\n }\n}\n\n/* --- Main content: table + sidebar --- */\n.content-area {\n display: grid;\n grid-template-columns: 1fr 300px;\n gap: 24px;\n align-items: start;\n}\n\n@media (max-width: 1024px) {\n .content-area {\n grid-template-columns: 1fr;\n }\n}\n\n/* --- Sync table panel --- */\n.sync-table-panel {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n overflow: hidden;\n}\n\n.panel-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.panel-title {\n margin: 0;\n font-size: 15px;\n font-weight: 600;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.panel-title i {\n color: var(--mj-brand-primary);\n font-size: 14px;\n}\n\n.refresh-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.refresh-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n border-color: var(--mj-border-strong);\n}\n\n/* --- Table --- */\n.table-wrapper {\n overflow-x: auto;\n}\n\n.sync-table {\n width: 100%;\n border-collapse: collapse;\n}\n\n.sync-table th {\n padding: 10px 16px;\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n text-align: left;\n white-space: nowrap;\n}\n\n.sync-table td {\n padding: 12px 16px;\n font-size: 13px;\n color: var(--mj-text-primary);\n border-bottom: 1px solid var(--mj-border-subtle);\n vertical-align: middle;\n}\n\n.sync-table tbody tr:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.sync-table tbody tr:last-child td {\n border-bottom: none;\n}\n\n.text-right {\n text-align: right;\n}\n\n.text-center {\n text-align: center;\n}\n\n.entity-name {\n font-weight: 600;\n}\n\n.document-name {\n color: var(--mj-text-secondary);\n}\n\n.vector-count {\n font-variant-numeric: tabular-nums;\n font-weight: 600;\n}\n\n.last-synced {\n color: var(--mj-text-secondary);\n font-size: 12px;\n white-space: nowrap;\n}\n\n/* --- Action buttons in table --- */\n\n.actions-cell {\n display: flex;\n gap: 6px;\n align-items: center;\n justify-content: center;\n}\n\n.schedule-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 30px;\n height: 30px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: transparent;\n color: var(--mj-text-muted);\n font-size: 12px;\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.schedule-btn:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n}\n\n.edit-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 30px;\n height: 30px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: transparent;\n color: var(--mj-text-muted);\n font-size: 12px;\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.edit-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n border-color: var(--mj-border-strong);\n}\n\n/* --- Schedule Dialog --- */\n.schedule-dialog {\n width: 440px;\n max-width: 90vw;\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.2);\n overflow: hidden;\n}\n\n.schedule-cron-preview {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 0 0;\n font-size: 0.82rem;\n color: var(--mj-text-muted);\n}\n\n.schedule-toggle-row {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: 12px;\n}\n\n.edit-delete-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n border: 1px solid var(--mj-status-error-border);\n border-radius: 6px;\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n color: var(--mj-status-error-text);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.edit-delete-btn:hover {\n background: color-mix(in srgb, var(--mj-status-error) 20%, var(--mj-bg-surface));\n}\n\n.edit-readonly-value {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n padding: 8px 0;\n}\n\n/* --- Status badges --- */\n.status-badge {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 10px;\n border-radius: 999px;\n font-size: 11px;\n font-weight: 600;\n white-space: nowrap;\n}\n\n.status-synced {\n background: color-mix(in srgb, var(--mj-status-success) 12%, var(--mj-bg-surface));\n color: var(--mj-status-success-text, var(--mj-status-success));\n}\n\n.status-syncing {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.status-error {\n background: color-mix(in srgb, var(--mj-status-error) 12%, var(--mj-bg-surface));\n color: var(--mj-status-error-text, var(--mj-status-error));\n}\n\n.status-pending {\n background: color-mix(in srgb, var(--mj-status-warning) 12%, var(--mj-bg-surface));\n color: var(--mj-status-warning-text, var(--mj-status-warning));\n}\n\n/* --- Sync button --- */\n.sync-btn {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 5px 12px;\n border: 1px solid var(--mj-brand-primary);\n border-radius: 6px;\n background: transparent;\n color: var(--mj-brand-primary);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.sync-btn:hover:not(:disabled) {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.sync-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n/* ================================================================\n Sidebar\n ================================================================ */\n.sidebar {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.sidebar-card {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n padding: 16px 20px;\n}\n\n.sidebar-title {\n margin: 0 0 14px 0;\n font-size: 13px;\n font-weight: 700;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.sidebar-title i {\n color: var(--mj-brand-primary);\n font-size: 13px;\n}\n\n/* --- Vector DB Health --- */\n.health-row {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 6px;\n}\n\n.health-dot {\n width: 10px;\n height: 10px;\n border-radius: 50%;\n flex-shrink: 0;\n}\n\n.health-healthy {\n background: var(--mj-status-success);\n box-shadow: 0 0 6px color-mix(in srgb, var(--mj-status-success) 50%, transparent);\n}\n\n.health-degraded {\n background: var(--mj-status-warning);\n box-shadow: 0 0 6px color-mix(in srgb, var(--mj-status-warning) 50%, transparent);\n}\n\n.health-offline {\n background: var(--mj-status-error);\n box-shadow: 0 0 6px color-mix(in srgb, var(--mj-status-error) 50%, transparent);\n}\n\n.health-label {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.health-status {\n font-size: 12px;\n color: var(--mj-text-muted);\n padding-left: 18px;\n}\n\n.health-reason {\n font-size: 11px;\n line-height: 1.4;\n color: var(--mj-text-muted);\n padding-left: 18px;\n margin-top: 4px;\n}\n\n/* --- Model Info --- */\n.model-info {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.info-row {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.info-label {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.info-value {\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n/* --- Storage / Coverage Gauge --- */\n.gauge-container {\n margin-bottom: 8px;\n}\n\n.gauge-bar {\n height: 8px;\n border-radius: 4px;\n background: var(--mj-bg-surface-sunken);\n overflow: hidden;\n margin-bottom: 6px;\n}\n\n.gauge-fill {\n height: 100%;\n border-radius: 4px;\n background: var(--mj-brand-primary);\n transition: width 0.6s cubic-bezier(0.4, 0, 0.2, 1);\n min-width: 2px;\n}\n\n.gauge-label {\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n.storage-detail {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n/* --- Panel actions row --- */\n.panel-actions {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n/* --- Suggest Document Button --- */\n.suggest-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border: 1px solid var(--mj-brand-primary);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.suggest-btn:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary-hover);\n}\n\n/* --- Slide-in Panel Overlay --- */\n.slide-panel-overlay {\n position: fixed;\n inset: 0;\n background: var(--mj-bg-overlay);\n z-index: 100000;\n}\n\n.slide-panel {\n position: fixed;\n top: 0;\n right: 0;\n height: 100vh;\n width: 480px;\n max-width: 90vw;\n background: var(--mj-bg-surface);\n box-shadow: -4px 0 24px color-mix(in srgb, var(--mj-text-primary) 12%, transparent);\n transform: translateX(100%);\n transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n overflow-y: auto;\n}\n\n.slide-panel.open {\n transform: translateX(0);\n}\n\n.suggest-dialog-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px 24px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.suggest-dialog-title {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.suggest-dialog-title i {\n color: var(--mj-brand-primary);\n}\n\n.suggest-close-btn {\n border: none;\n background: none;\n color: var(--mj-text-muted);\n font-size: 16px;\n cursor: pointer;\n padding: 4px;\n}\n\n.suggest-close-btn:hover {\n color: var(--mj-text-primary);\n}\n\n.suggest-dialog-body {\n padding: 24px;\n}\n\n/* --- Suggest Form --- */\n.suggest-form {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.suggest-field {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.suggest-label {\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n.suggest-select {\n padding: 8px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n}\n\n.suggest-select:focus {\n outline: none;\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n/* ---- Use Case Button Group ---- */\n\n.use-case-options {\n display: flex;\n gap: 8px;\n flex-wrap: wrap;\n}\n\n.use-case-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.use-case-btn:hover {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-border-strong);\n color: var(--mj-text-primary);\n}\n\n.use-case-btn-active {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n.use-case-btn i {\n font-size: 12px;\n}\n\n/* ---- Entity Picker (grouped by schema) ---- */\n\n.entity-picker {\n position: relative;\n}\n\n.entity-picker-trigger {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n padding: 9px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n cursor: pointer;\n text-align: left;\n transition: border-color 0.15s;\n}\n\n.entity-picker-trigger:hover {\n border-color: var(--mj-border-strong);\n}\n\n.entity-picker-placeholder {\n color: var(--mj-text-muted);\n flex: 1;\n}\n\n.entity-picker-value {\n flex: 1;\n font-weight: 500;\n}\n\n.entity-picker-arrow {\n font-size: 10px;\n color: var(--mj-text-muted);\n transition: transform 0.2s;\n}\n\n.entity-picker-dropdown {\n position: absolute;\n top: calc(100% + 4px);\n left: 0;\n right: 0;\n background: var(--mj-bg-surface-elevated, var(--mj-bg-surface));\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n box-shadow: 0 8px 32px color-mix(in srgb, var(--mj-text-primary) 15%, transparent);\n z-index: 100;\n max-height: 350px;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n.entity-picker-search {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 14px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.entity-picker-search i {\n color: var(--mj-text-muted);\n font-size: 13px;\n}\n\n.entity-picker-search-input {\n flex: 1;\n border: none;\n background: transparent;\n color: var(--mj-text-primary);\n font-size: 13px;\n outline: none;\n}\n\n.entity-picker-search-input::placeholder {\n color: var(--mj-text-disabled);\n}\n\n.entity-picker-list {\n overflow-y: auto;\n max-height: 300px;\n padding: 4px 0;\n}\n\n.entity-picker-group-header {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 14px 4px;\n font-size: 11px;\n font-weight: 700;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n position: sticky;\n top: 0;\n background: var(--mj-bg-surface-elevated, var(--mj-bg-surface));\n}\n\n.entity-picker-group-header i {\n font-size: 10px;\n}\n\n.entity-picker-item {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n padding: 7px 14px 7px 28px;\n border: none;\n background: transparent;\n color: var(--mj-text-primary);\n font-size: 13px;\n cursor: pointer;\n text-align: left;\n transition: background 0.1s;\n}\n\n.entity-picker-item:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.entity-picker-item-selected {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n.entity-picker-item i {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.entity-picker-item-selected i {\n color: var(--mj-brand-primary);\n}\n\n.entity-picker-item-focused {\n background: var(--mj-bg-surface-hover);\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: -2px;\n}\n\n.entity-picker-empty {\n padding: 20px 14px;\n text-align: center;\n color: var(--mj-text-disabled);\n font-size: 13px;\n}\n\n/* ---- Template Editor ---- */\n\n.template-editor-wrapper {\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n min-height: 120px;\n max-height: 300px;\n}\n\n.template-editor-wrapper ::ng-deep .cm-editor {\n min-height: 120px;\n max-height: 300px;\n font-size: 13px;\n}\n\n.suggest-submit-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n padding: 10px 20px;\n border: none;\n border-radius: 6px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.2s ease;\n}\n\n.suggest-submit-btn:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n\n.suggest-submit-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n/* --- Suggestion Result --- */\n.suggest-result {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.result-section {\n border-bottom: 1px solid var(--mj-border-subtle);\n padding-bottom: 12px;\n}\n\n.result-section:last-child {\n border-bottom: none;\n}\n\n.result-heading {\n margin: 0 0 8px 0;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.result-template {\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 6px;\n padding: 12px;\n font-size: 12px;\n color: var(--mj-text-primary);\n white-space: pre-wrap;\n word-break: break-all;\n margin: 0;\n}\n\n.result-tags {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n}\n\n.result-tag {\n padding: 3px 10px;\n border-radius: 12px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 12px;\n font-weight: 500;\n}\n\n.result-relationship {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 4px 0;\n}\n\n.rel-name {\n font-weight: 600;\n font-size: 13px;\n color: var(--mj-text-primary);\n}\n\n.rel-fields {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.result-thresholds {\n display: flex;\n gap: 24px;\n}\n\n.threshold-item {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.threshold-label {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.threshold-value {\n font-size: 18px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.result-reasoning {\n margin: 0;\n font-size: 13px;\n color: var(--mj-text-secondary);\n line-height: 1.5;\n}\n\n.result-actions {\n display: flex;\n gap: 8px;\n padding-top: 8px;\n}\n\n.suggest-close-action {\n padding: 10px 20px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n}\n\n.suggest-close-action:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n/* --- Suggest Input --- */\n.suggest-input {\n padding: 8px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n width: 100%;\n box-sizing: border-box;\n}\n\n.suggest-input:focus {\n outline: none;\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n/* --- Try Again Button (secondary style) --- */\n.suggest-try-again-btn {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n border: 1px solid var(--mj-brand-primary);\n}\n\n.suggest-try-again-btn:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n/* --- Save Spinner --- */\n.save-spinner {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 8px 0;\n}\n\n/* --- Edit Panel Template Header --- */\n.edit-template-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n}\n\n.edit-regenerate-btn {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 10px;\n border: 1px solid var(--mj-brand-primary);\n border-radius: 6px;\n background: transparent;\n color: var(--mj-brand-primary);\n font-size: 11px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n white-space: nowrap;\n}\n\n.edit-regenerate-btn:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.edit-regenerate-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n/* --- No Vector Index Warning Dialog --- */\n.no-index-warning-dialog {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 440px;\n max-width: 90vw;\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: 0 20px 60px color-mix(in srgb, var(--mj-text-primary) 20%, transparent);\n padding: 32px;\n text-align: center;\n}\n\n.no-index-warning-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 56px;\n height: 56px;\n margin: 0 auto 16px;\n border-radius: 50%;\n background: color-mix(in srgb, var(--mj-status-warning) 12%, var(--mj-bg-surface));\n}\n\n.no-index-warning-icon i {\n font-size: 24px;\n color: var(--mj-status-warning);\n}\n\n.no-index-warning-title {\n margin: 0 0 8px 0;\n font-size: 18px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.no-index-warning-message {\n margin: 0 0 24px 0;\n font-size: 14px;\n line-height: 1.5;\n color: var(--mj-text-secondary);\n}\n\n.no-index-warning-actions {\n display: flex;\n gap: 8px;\n justify-content: center;\n}\n\n/* ================================================================\n Responsive \u2014 Vector Management\n ================================================================ */\n\n@media (max-width: 768px) {\n .panel-header {\n flex-direction: column;\n align-items: flex-start;\n gap: 12px;\n }\n\n .panel-actions {\n flex-wrap: wrap;\n }\n}\n\n@media (max-width: 600px) {\n .slide-panel {\n width: 100vw;\n max-width: 100vw;\n }\n}\n\n@media (max-width: 480px) {\n .vector-dashboard {\n padding: 12px;\n }\n\n .suggest-btn .suggest-btn-text {\n display: none;\n }\n}\n"] }]
|
|
2710
|
+
args: [{ standalone: false, selector: 'app-vector-management-resource', template: "@if (!HideToolbar) {\n <mj-page-layout>\n <mj-page-header\n Title=\"Vector Management\"\n Icon=\"fa-solid fa-cubes\"\n Subtitle=\"Vector index health, embeddings, and entity sync status\">\n <div actions>\n <mj-view-toggle\n [Options]=\"VectorViewOptions\"\n [ActiveKey]=\"ViewMode\"\n (KeyChange)=\"ViewMode = $any($event)\">\n </mj-view-toggle>\n </div>\n </mj-page-header>\n <mj-page-body [Flex]=\"true\">\n <ng-container *ngTemplateOutlet=\"vectorBody\"></ng-container>\n </mj-page-body>\n </mj-page-layout>\n}\n@if (HideToolbar) {\n <ng-container *ngTemplateOutlet=\"vectorBody\"></ng-container>\n}\n\n<ng-template #vectorBody>\n@if (IsLoading) {\n <div class=\"vector-loading\">\n <mj-loading text=\"Loading vector management data...\"></mj-loading>\n </div>\n} @else {\n <div class=\"vector-dashboard\">\n\n <!-- KPI Cards Row -->\n <div class=\"kpi-row\">\n @for (card of KPICards; track card.title) {\n <app-kpi-card [data]=\"card\"></app-kpi-card>\n }\n </div>\n\n <!-- Main Content Area: Table + Sidebar -->\n <div class=\"content-area\">\n <!-- Entity Sync Table -->\n <div class=\"sync-table-panel\">\n <div class=\"panel-header\">\n <h3 class=\"panel-title\">\n <i class=\"fa-solid fa-table-list\"></i>\n Entity Sync Status\n </h3>\n <div class=\"panel-actions\">\n <button class=\"suggest-btn\" (click)=\"OpenSuggestDialog()\" title=\"Use AI to suggest an Entity Document template\">\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i>\n <span class=\"suggest-btn-text\">Suggest Document</span>\n </button>\n <button class=\"refresh-btn\" (click)=\"LoadData(true)\" title=\"Refresh data\">\n <i class=\"fa-solid fa-arrows-rotate\"></i>\n Refresh\n </button>\n </div>\n </div>\n\n @if (SyncRows.length === 0) {\n <mj-empty-state Icon=\"fa-solid fa-folder-open\"\n Title=\"No entity documents configured for vectorization.\" />\n } @else {\n <div class=\"table-wrapper\">\n <table class=\"sync-table\">\n <thead>\n <tr>\n <th>Entity</th>\n <th>Document</th>\n <th>Type</th>\n <th class=\"text-right\">Vectors</th>\n <th>Last Synced</th>\n <th>Status</th>\n <th class=\"text-center\">Actions</th>\n </tr>\n </thead>\n <tbody>\n @for (row of SyncRows; track row.EntityDocumentID) {\n <tr>\n <td class=\"entity-name\">{{ row.EntityName }}</td>\n <td class=\"document-name\">{{ row.DocumentName }}</td>\n <td class=\"document-type\">{{ row.DocumentType }}</td>\n <td class=\"text-right vector-count\">{{ row.VectorCount | number }}</td>\n <td class=\"last-synced\">{{ FormatDate(row.LastSynced) }}</td>\n <td>\n <span class=\"status-badge\" [class]=\"GetStatusClass(row.Status)\">\n <i [class]=\"GetStatusIcon(row.Status)\"></i>\n @if (row.Status === 'Syncing' && row.PercentComplete > 0) {\n {{ row.PercentComplete }}%\n } @else {\n {{ row.Status }}\n }\n </span>\n </td>\n <td class=\"text-center actions-cell\">\n <button\n class=\"sync-btn\"\n [disabled]=\"IsSyncing(row.EntityDocumentID)\"\n (click)=\"SyncEntity(row.EntityDocumentID)\"\n title=\"Sync now\">\n @if (IsSyncing(row.EntityDocumentID)) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n {{ row.PercentComplete > 0 ? row.PercentComplete + '%' : 'Sync' }}\n } @else {\n <i class=\"fa-solid fa-play\"></i>\n Sync\n }\n </button>\n <button\n class=\"schedule-btn\"\n (click)=\"OpenScheduleSyncDialog(row.EntityDocumentID)\"\n title=\"Schedule recurring sync\">\n <i class=\"fa-regular fa-clock\"></i>\n </button>\n <button\n class=\"edit-btn\"\n (click)=\"OpenEditPanel(row.EntityDocumentID)\"\n title=\"Edit entity document\">\n <i class=\"fa-solid fa-pen\"></i>\n </button>\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n </div>\n\n <!-- Sidebar Panels -->\n <div class=\"sidebar\">\n <!-- Vector DB Health -->\n <div class=\"sidebar-card\">\n <h4 class=\"sidebar-title\">\n <i class=\"fa-solid fa-heart-pulse\"></i>\n Vector DB Health\n </h4>\n <div class=\"health-row\">\n <span class=\"health-dot\" [class]=\"DBHealthClass\"></span>\n <span class=\"health-label\">{{ VectorDBName }}</span>\n </div>\n <div class=\"health-status\" [title]=\"VectorDBStatusReason\">{{ VectorDBStatus }}</div>\n @if (VectorDBStatusReason) {\n <div class=\"health-reason\">{{ VectorDBStatusReason }}</div>\n }\n </div>\n\n <!-- Embedding Model Info -->\n <div class=\"sidebar-card\">\n <h4 class=\"sidebar-title\">\n <i class=\"fa-solid fa-microchip\"></i>\n Embedding Model\n </h4>\n <div class=\"model-info\">\n <div class=\"info-row\">\n <span class=\"info-label\">Model</span>\n <span class=\"info-value\" [title]=\"'Embeddings are generated by this model; the index above stores the resulting vectors.'\">{{ EmbeddingModel.Name }}</span>\n </div>\n @if (EmbeddingModel.Dimensions != null) {\n <div class=\"info-row\">\n <span class=\"info-label\">Dimensions</span>\n <span class=\"info-value\">{{ EmbeddingModel.Dimensions | number }}</span>\n </div>\n }\n </div>\n </div>\n\n <!-- Storage Usage -->\n <div class=\"sidebar-card\">\n <h4 class=\"sidebar-title\">\n <i class=\"fa-solid fa-hard-drive\"></i>\n Vectorization Coverage\n </h4>\n <div class=\"gauge-container\">\n <div class=\"gauge-bar\">\n <div class=\"gauge-fill\" [style.width.%]=\"StorageUsagePercent\"></div>\n </div>\n <div class=\"gauge-label\">{{ StorageLabel }} of records vectorized</div>\n </div>\n <div class=\"storage-detail\">\n {{ TotalVectors | number }} vectors stored\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Edit Entity Document Slide-in Panel -->\n @if (ShowEditPanel) {\n <div class=\"slide-panel-overlay\" (click)=\"CloseEditPanel()\">\n <div class=\"slide-panel open\" (click)=\"$event.stopPropagation()\">\n <div class=\"suggest-dialog-header\">\n <h3 class=\"suggest-dialog-title\">\n <i class=\"fa-solid fa-pen\"></i>\n Edit Entity Document\n </h3>\n <button class=\"suggest-close-btn\" (click)=\"CloseEditPanel()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n <div class=\"suggest-dialog-body\">\n <div class=\"suggest-form\">\n <div class=\"suggest-field\">\n <label class=\"suggest-label\">Entity</label>\n <span class=\"edit-readonly-value\">{{ EditDocEntityName }}</span>\n </div>\n <div class=\"suggest-field\">\n <label class=\"suggest-label\">Type</label>\n <span class=\"edit-readonly-value\">{{ EditDocType }}</span>\n </div>\n\n <!-- Template Section -->\n <div class=\"suggest-field\">\n <div class=\"edit-template-header\">\n <label class=\"suggest-label\">Template</label>\n <button class=\"edit-regenerate-btn\"\n [disabled]=\"IsEditRegenerating\"\n (click)=\"RegenerateTemplate()\"\n title=\"Regenerate template using AI\">\n @if (IsEditRegenerating) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Regenerating...\n } @else {\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i> Regenerate with AI\n }\n </button>\n </div>\n <div class=\"template-editor-wrapper\">\n <mj-code-editor\n [value]=\"EditDocTemplate\"\n language=\"markdown\"\n [readonly]=\"false\"\n [lineWrapping]=\"true\"\n (change)=\"OnEditTemplateChange($event)\">\n </mj-code-editor>\n </div>\n </div>\n\n <!-- Selected Fields (parsed from template) -->\n @if (EditDocSelectedFields.length > 0) {\n <div class=\"suggest-field\">\n <label class=\"suggest-label\">Selected Fields</label>\n <div class=\"result-tags\">\n @for (field of EditDocSelectedFields; track field) {\n <span class=\"result-tag\">{{ field }}</span>\n }\n </div>\n </div>\n }\n\n <div class=\"suggest-field\">\n <label class=\"suggest-label\">Document Name</label>\n <input class=\"suggest-input\" type=\"text\" [(ngModel)]=\"EditDocName\" />\n </div>\n <div class=\"suggest-field\">\n <label class=\"suggest-label\">Embedding Model</label>\n <select class=\"suggest-select\" [(ngModel)]=\"EditDocAIModelID\">\n @for (model of AvailableEmbeddingModels; track model.ID) {\n <option [value]=\"model.ID\">{{ model.Name }}</option>\n }\n </select>\n </div>\n <div class=\"suggest-field\">\n <label class=\"suggest-label\">Vector Database</label>\n <select class=\"suggest-select\" [(ngModel)]=\"EditDocVectorDBID\">\n @for (db of vectorDatabases; track db.ID) {\n <option [value]=\"db.ID\">{{ db.Name }}</option>\n }\n </select>\n </div>\n <div class=\"suggest-field\">\n <label class=\"suggest-label\">Vector Index</label>\n @if (EditFilteredIndexes.length > 0) {\n <select class=\"suggest-select\" [(ngModel)]=\"EditDocVectorIndexID\">\n <option value=\"\">Auto (create/find matching index)</option>\n @for (idx of EditFilteredIndexes; track idx.ID) {\n <option [value]=\"idx.ID\">{{ idx.Name }}</option>\n }\n </select>\n } @else {\n <span class=\"edit-readonly-value\" style=\"font-size: 13px; color: var(--mj-text-muted);\">\n No indexes for this database \u2014 one will be created automatically on sync\n </span>\n }\n </div>\n <div class=\"suggest-field\">\n <label class=\"suggest-label\">Status</label>\n <select class=\"suggest-select\" [(ngModel)]=\"EditDocStatus\">\n <option value=\"Active\">Active</option>\n <option value=\"Inactive\">Inactive</option>\n </select>\n </div>\n <div class=\"result-actions\" style=\"margin-top: 1rem\">\n @if (IsEditSaving || IsEditDeleting) {\n <mj-loading text=\"Saving...\" size=\"small\"></mj-loading>\n } @else {\n <button class=\"suggest-submit-btn\" (click)=\"SaveEditedDocument()\">\n <i class=\"fa-solid fa-save\"></i> Save Changes\n </button>\n <button class=\"edit-delete-btn\" (click)=\"DeleteEntityDocument()\">\n <i class=\"fa-solid fa-trash-can\"></i> Delete\n </button>\n <button class=\"suggest-close-action\" (click)=\"CloseEditPanel()\">\n Cancel\n </button>\n }\n </div>\n </div>\n </div>\n </div>\n </div>\n }\n\n <!-- Schedule Sync Dialog -->\n @if (ShowScheduleSyncDialog) {\n <div class=\"slide-panel-overlay\" (click)=\"CloseScheduleSyncDialog()\">\n <div class=\"schedule-dialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"suggest-dialog-header\">\n <h3 class=\"suggest-dialog-title\">\n <i class=\"fa-regular fa-clock\"></i>\n Schedule Vector Sync\n </h3>\n <button class=\"suggest-close-btn\" (click)=\"CloseScheduleSyncDialog()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n <div class=\"suggest-dialog-body\">\n <div class=\"suggest-form\">\n <div class=\"suggest-field\">\n <label class=\"suggest-label\">Entity Document</label>\n <span class=\"edit-readonly-value\">{{ ScheduleSyncDocName }}</span>\n </div>\n <div class=\"suggest-field\">\n <label class=\"suggest-label\">Action</label>\n <span class=\"edit-readonly-value\">__VectorizeEntity</span>\n </div>\n <div class=\"suggest-field\">\n <label class=\"suggest-label\">Cron Expression</label>\n <input class=\"suggest-input\" type=\"text\" [(ngModel)]=\"ScheduleSyncCron\" placeholder=\"0 2 * * *\" />\n <div class=\"schedule-cron-preview\">\n <i class=\"fa-solid fa-info-circle\"></i>\n {{ GetScheduleCronPreview(ScheduleSyncCron) }}\n </div>\n </div>\n <div class=\"suggest-field schedule-toggle-row\">\n <label class=\"suggest-label\">Enabled</label>\n <input type=\"checkbox\" class=\"mj-checkbox\" [(ngModel)]=\"ScheduleSyncEnabled\" />\n </div>\n <div class=\"result-actions\" style=\"margin-top: 1rem\">\n @if (ScheduleSyncSaving) {\n <mj-loading text=\"Saving...\" size=\"small\"></mj-loading>\n } @else {\n <button class=\"suggest-submit-btn\" (click)=\"SaveScheduleSync()\">\n <i class=\"fa-solid fa-check\"></i> Create Schedule\n </button>\n <button class=\"suggest-close-action\" (click)=\"CloseScheduleSyncDialog()\">\n Cancel\n </button>\n }\n </div>\n </div>\n </div>\n </div>\n </div>\n }\n\n <!-- No Vector Index Warning Dialog -->\n @if (ShowNoIndexWarning) {\n <div class=\"slide-panel-overlay\" (click)=\"CloseNoIndexWarning()\">\n <div class=\"no-index-warning-dialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"no-index-warning-icon\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n </div>\n <h3 class=\"no-index-warning-title\">Vector Index Required</h3>\n <p class=\"no-index-warning-message\">\n You need to create at least one vector database and index before creating entity documents.\n Go to the Configuration section to set up a vector database and create an index.\n </p>\n <div class=\"no-index-warning-actions\">\n <button class=\"suggest-submit-btn\" (click)=\"GoToConfiguration()\">\n <i class=\"fa-solid fa-gear\"></i> Go to Configuration\n </button>\n <button class=\"suggest-close-action\" (click)=\"CloseNoIndexWarning()\">\n Close\n </button>\n </div>\n </div>\n </div>\n }\n\n <!-- Suggest Document Slide-in Panel -->\n @if (ShowSuggestDialog) {\n <div class=\"slide-panel-overlay\" (click)=\"CloseSuggestDialog()\">\n <div class=\"slide-panel\" [class.open]=\"ShowSuggestDialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"suggest-dialog-header\">\n <h3 class=\"suggest-dialog-title\">\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i>\n AI Document Suggestion\n </h3>\n <button class=\"suggest-close-btn\" (click)=\"CloseSuggestDialog()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n <div class=\"suggest-dialog-body\">\n @if (!SuggestionResult) {\n <div class=\"suggest-form\">\n <div class=\"suggest-field\">\n <label class=\"suggest-label\">Entity</label>\n <div class=\"entity-picker\">\n <button class=\"entity-picker-trigger\" (click)=\"ToggleEntityPicker()\">\n @if (SuggestEntityName) {\n <i class=\"fa-solid fa-table\"></i>\n <span class=\"entity-picker-value\">{{ SuggestEntityName }}</span>\n } @else {\n <i class=\"fa-solid fa-search\"></i>\n <span class=\"entity-picker-placeholder\">Search and select an entity...</span>\n }\n <i class=\"fa-solid fa-chevron-down entity-picker-arrow\"></i>\n </button>\n @if (ShowEntityPicker) {\n <div class=\"entity-picker-dropdown\" (mousedown)=\"$event.stopPropagation()\">\n <div class=\"entity-picker-search\">\n <i class=\"fa-solid fa-search\"></i>\n <input #entitySearchInput\n type=\"text\"\n class=\"entity-picker-search-input\"\n placeholder=\"Filter entities...\"\n [(ngModel)]=\"EntitySearchText\"\n (input)=\"FilterEntities()\"\n (keydown)=\"OnEntityPickerKeyDown($event)\" />\n </div>\n <div class=\"entity-picker-list\">\n @for (group of FilteredEntityGroups; track group.SchemaName) {\n <div class=\"entity-picker-group\">\n <div class=\"entity-picker-group-header\">\n <i class=\"fa-solid fa-database\"></i>\n {{ group.SchemaName }}\n </div>\n @for (entity of group.Entities; track entity.ID) {\n <button class=\"entity-picker-item\"\n [class.entity-picker-item-selected]=\"entity.Name === SuggestEntityName\"\n [class.entity-picker-item-focused]=\"FlatFilteredEntities[SelectedEntityIndex]?.ID === entity.ID\"\n (click)=\"SelectEntity(entity.Name)\">\n <i class=\"fa-solid fa-table\"></i>\n {{ entity.Name }}\n </button>\n }\n </div>\n }\n @if (FilteredEntityGroups.length === 0) {\n <div class=\"entity-picker-empty\">\n No entities matching \"{{ EntitySearchText }}\"\n </div>\n }\n </div>\n </div>\n }\n </div>\n </div>\n <div class=\"suggest-field\">\n <label class=\"suggest-label\">Use Case</label>\n <div class=\"use-case-options\">\n <button class=\"use-case-btn\"\n [class.use-case-btn-active]=\"SuggestUseCase === 'duplicate detection'\"\n (click)=\"SuggestUseCase = 'duplicate detection'\">\n <i class=\"fa-solid fa-clone\"></i>\n Duplicate Detection\n </button>\n <button class=\"use-case-btn\"\n [class.use-case-btn-active]=\"SuggestUseCase === 'search'\"\n (click)=\"SuggestUseCase = 'search'\">\n <i class=\"fa-solid fa-magnifying-glass\"></i>\n Search\n </button>\n </div>\n </div>\n <button class=\"suggest-submit-btn\"\n [disabled]=\"IsSuggesting || !SuggestEntityName\"\n (click)=\"RunSuggestion()\">\n @if (IsSuggesting) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Generating with AI...\n } @else {\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i> Generate Template\n }\n </button>\n @if (SuggestionError) {\n <mj-alert Variant=\"error\" Size=\"sm\">{{ SuggestionError }}</mj-alert>\n }\n </div>\n } @else {\n <div class=\"suggest-result\">\n <div class=\"result-section\">\n <h4 class=\"result-heading\">Suggested Template</h4>\n <div class=\"template-editor-wrapper\">\n <mj-code-editor\n [value]=\"EditableTemplate\"\n language=\"markdown\"\n [readonly]=\"false\"\n [lineWrapping]=\"true\"\n (change)=\"OnTemplateChange($event)\">\n </mj-code-editor>\n </div>\n </div>\n <div class=\"result-section\">\n <h4 class=\"result-heading\">Selected Fields</h4>\n <div class=\"result-tags\">\n @for (field of SuggestionResult.selectedFields; track field) {\n <span class=\"result-tag\">{{ field }}</span>\n }\n </div>\n </div>\n @if ((SuggestionResult.selectedRelationships?.length ?? 0) > 0) {\n <div class=\"result-section\">\n <h4 class=\"result-heading\">Related Entities</h4>\n @for (rel of SuggestionResult.selectedRelationships; track rel.name) {\n <div class=\"result-relationship\">\n <span class=\"rel-name\">{{ rel.name }}</span>\n <span class=\"rel-fields\">{{ rel.fields.join(', ') }}</span>\n </div>\n }\n </div>\n }\n <div class=\"result-section result-thresholds\">\n <div class=\"threshold-item\">\n <span class=\"threshold-label\">Potential Match</span>\n <span class=\"threshold-value\">{{ (SuggestionResult.potentialMatchThreshold * 100).toFixed(0) }}%</span>\n </div>\n <div class=\"threshold-item\">\n <span class=\"threshold-label\">Absolute Match</span>\n <span class=\"threshold-value\">{{ (SuggestionResult.absoluteMatchThreshold * 100).toFixed(0) }}%</span>\n </div>\n </div>\n <div class=\"result-section\">\n <h4 class=\"result-heading\">Reasoning</h4>\n <p class=\"result-reasoning\">{{ SuggestionResult.reasoning }}</p>\n </div>\n <div class=\"result-section\">\n <div class=\"suggest-field\">\n <label class=\"suggest-label\">Document Name</label>\n <input class=\"suggest-input\" type=\"text\" [(ngModel)]=\"SaveDocumentName\" />\n </div>\n <div class=\"suggest-field\" style=\"margin-top: 0.75rem\">\n <label class=\"suggest-label\">Embedding Model</label>\n <select class=\"suggest-select\" [(ngModel)]=\"SelectedEmbeddingModelID\">\n @for (model of AvailableEmbeddingModels; track model.ID) {\n <option [value]=\"model.ID\">{{ model.Name }}</option>\n }\n </select>\n </div>\n <div class=\"suggest-field\" style=\"margin-top: 0.75rem\">\n <label class=\"suggest-label\">Vector Database</label>\n <select class=\"suggest-select\" [(ngModel)]=\"SelectedVectorDBID\">\n @for (db of vectorDatabases; track db.ID) {\n <option [value]=\"db.ID\">{{ db.Name }}</option>\n }\n </select>\n </div>\n <div class=\"suggest-field\" style=\"margin-top: 0.75rem\">\n <label class=\"suggest-label\">Vector Index</label>\n @if (FilteredIndexesForSelectedDB.length > 0) {\n <select class=\"suggest-select\" [(ngModel)]=\"SelectedVectorIndexID\">\n <option value=\"\">Auto (create/find matching index)</option>\n @for (idx of FilteredIndexesForSelectedDB; track idx.ID) {\n <option [value]=\"idx.ID\">{{ idx.Name }}</option>\n }\n </select>\n } @else {\n <span class=\"edit-readonly-value\" style=\"font-size: 13px; color: var(--mj-text-muted);\">\n No indexes yet \u2014 create one in Configuration > Vector Database, or one will be created on sync\n </span>\n }\n </div>\n </div>\n <div class=\"result-actions\">\n @if (IsSavingDocument) {\n <div class=\"save-spinner\">\n <mj-loading text=\"Saving...\" size=\"small\"></mj-loading>\n </div>\n } @else {\n <button class=\"suggest-submit-btn\" (click)=\"SaveAsEntityDocument()\">\n <i class=\"fa-solid fa-floppy-disk\"></i> Save as Entity Document\n </button>\n <button class=\"suggest-submit-btn suggest-try-again-btn\" (click)=\"ClearSuggestion()\">\n <i class=\"fa-solid fa-rotate\"></i> Try Again\n </button>\n <button class=\"suggest-close-action\" (click)=\"CloseSuggestDialog()\">\n Close\n </button>\n }\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n }\n}\n</ng-template>\n", styles: ["/* ================================================================\n Vector Management Dashboard\n All colors use MJ design tokens from _tokens.scss\n ================================================================ */\n\n\n/* --- Loading state --- */\n.vector-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 400px;\n}\n\n/* --- View Mode Toggle --- */\n.view-mode-toggle {\n display: flex;\n gap: 0.25rem;\n padding: 0 24px 0;\n margin-bottom: -12px;\n}\n\n.view-mode-btn {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n padding: 0.4rem 0.85rem;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 0.82rem;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.view-mode-btn:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n}\n\n.view-mode-btn-active {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n/* --- Dashboard container --- */\n.vector-dashboard {\n display: flex;\n flex-direction: column;\n gap: 24px;\n padding: 24px;\n background: var(--mj-bg-page);\n min-height: 100%;\n}\n\n/* --- KPI cards row --- */\n.kpi-row {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 16px;\n}\n\n@media (max-width: 1200px) {\n .kpi-row {\n grid-template-columns: repeat(2, 1fr);\n }\n}\n\n@media (max-width: 600px) {\n .kpi-row {\n grid-template-columns: 1fr;\n }\n}\n\n/* --- Main content: table + sidebar --- */\n.content-area {\n display: grid;\n grid-template-columns: 1fr 300px;\n gap: 24px;\n align-items: start;\n}\n\n@media (max-width: 1024px) {\n .content-area {\n grid-template-columns: 1fr;\n }\n}\n\n/* --- Sync table panel --- */\n.sync-table-panel {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n overflow: hidden;\n}\n\n.panel-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.panel-title {\n margin: 0;\n font-size: 15px;\n font-weight: 600;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.panel-title i {\n color: var(--mj-brand-primary);\n font-size: 14px;\n}\n\n.refresh-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.refresh-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n border-color: var(--mj-border-strong);\n}\n\n/* --- Table --- */\n.table-wrapper {\n overflow-x: auto;\n}\n\n.sync-table {\n width: 100%;\n border-collapse: collapse;\n}\n\n.sync-table th {\n padding: 10px 16px;\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n text-align: left;\n white-space: nowrap;\n}\n\n.sync-table td {\n padding: 12px 16px;\n font-size: 13px;\n color: var(--mj-text-primary);\n border-bottom: 1px solid var(--mj-border-subtle);\n vertical-align: middle;\n}\n\n.sync-table tbody tr:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.sync-table tbody tr:last-child td {\n border-bottom: none;\n}\n\n.text-right {\n text-align: right;\n}\n\n.text-center {\n text-align: center;\n}\n\n.entity-name {\n font-weight: 600;\n}\n\n.document-name {\n color: var(--mj-text-secondary);\n}\n\n.document-type {\n color: var(--mj-text-secondary);\n white-space: nowrap;\n}\n\n.vector-count {\n font-variant-numeric: tabular-nums;\n font-weight: 600;\n}\n\n.last-synced {\n color: var(--mj-text-secondary);\n font-size: 12px;\n white-space: nowrap;\n}\n\n/* --- Action buttons in table --- */\n\n.actions-cell {\n display: flex;\n gap: 6px;\n align-items: center;\n justify-content: center;\n}\n\n.schedule-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 30px;\n height: 30px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: transparent;\n color: var(--mj-text-muted);\n font-size: 12px;\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.schedule-btn:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n}\n\n.edit-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 30px;\n height: 30px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: transparent;\n color: var(--mj-text-muted);\n font-size: 12px;\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.edit-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n border-color: var(--mj-border-strong);\n}\n\n/* --- Schedule Dialog --- */\n.schedule-dialog {\n width: 440px;\n max-width: 90vw;\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.2);\n overflow: hidden;\n}\n\n.schedule-cron-preview {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 0 0;\n font-size: 0.82rem;\n color: var(--mj-text-muted);\n}\n\n.schedule-toggle-row {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: 12px;\n}\n\n.edit-delete-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n border: 1px solid var(--mj-status-error-border);\n border-radius: 6px;\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n color: var(--mj-status-error-text);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.edit-delete-btn:hover {\n background: color-mix(in srgb, var(--mj-status-error) 20%, var(--mj-bg-surface));\n}\n\n.edit-readonly-value {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n padding: 8px 0;\n}\n\n/* --- Status badges --- */\n.status-badge {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 10px;\n border-radius: 999px;\n font-size: 11px;\n font-weight: 600;\n white-space: nowrap;\n}\n\n.status-synced {\n background: color-mix(in srgb, var(--mj-status-success) 12%, var(--mj-bg-surface));\n color: var(--mj-status-success-text, var(--mj-status-success));\n}\n\n.status-syncing {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.status-error {\n background: color-mix(in srgb, var(--mj-status-error) 12%, var(--mj-bg-surface));\n color: var(--mj-status-error-text, var(--mj-status-error));\n}\n\n.status-pending {\n background: color-mix(in srgb, var(--mj-status-warning) 12%, var(--mj-bg-surface));\n color: var(--mj-status-warning-text, var(--mj-status-warning));\n}\n\n/* --- Sync button --- */\n.sync-btn {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 5px 12px;\n border: 1px solid var(--mj-brand-primary);\n border-radius: 6px;\n background: transparent;\n color: var(--mj-brand-primary);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.sync-btn:hover:not(:disabled) {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.sync-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n/* ================================================================\n Sidebar\n ================================================================ */\n.sidebar {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.sidebar-card {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n padding: 16px 20px;\n}\n\n.sidebar-title {\n margin: 0 0 14px 0;\n font-size: 13px;\n font-weight: 700;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.sidebar-title i {\n color: var(--mj-brand-primary);\n font-size: 13px;\n}\n\n/* --- Vector DB Health --- */\n.health-row {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 6px;\n}\n\n.health-dot {\n width: 10px;\n height: 10px;\n border-radius: 50%;\n flex-shrink: 0;\n}\n\n.health-healthy {\n background: var(--mj-status-success);\n box-shadow: 0 0 6px color-mix(in srgb, var(--mj-status-success) 50%, transparent);\n}\n\n.health-degraded {\n background: var(--mj-status-warning);\n box-shadow: 0 0 6px color-mix(in srgb, var(--mj-status-warning) 50%, transparent);\n}\n\n.health-offline {\n background: var(--mj-status-error);\n box-shadow: 0 0 6px color-mix(in srgb, var(--mj-status-error) 50%, transparent);\n}\n\n.health-label {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.health-status {\n font-size: 12px;\n color: var(--mj-text-muted);\n padding-left: 18px;\n}\n\n.health-reason {\n font-size: 11px;\n line-height: 1.4;\n color: var(--mj-text-muted);\n padding-left: 18px;\n margin-top: 4px;\n}\n\n/* --- Model Info --- */\n.model-info {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.info-row {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.info-label {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.info-value {\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n/* --- Storage / Coverage Gauge --- */\n.gauge-container {\n margin-bottom: 8px;\n}\n\n.gauge-bar {\n height: 8px;\n border-radius: 4px;\n background: var(--mj-bg-surface-sunken);\n overflow: hidden;\n margin-bottom: 6px;\n}\n\n.gauge-fill {\n height: 100%;\n border-radius: 4px;\n background: var(--mj-brand-primary);\n transition: width 0.6s cubic-bezier(0.4, 0, 0.2, 1);\n min-width: 2px;\n}\n\n.gauge-label {\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n.storage-detail {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n/* --- Panel actions row --- */\n.panel-actions {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n/* --- Suggest Document Button --- */\n.suggest-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border: 1px solid var(--mj-brand-primary);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.suggest-btn:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary-hover);\n}\n\n/* --- Slide-in Panel Overlay --- */\n.slide-panel-overlay {\n position: fixed;\n inset: 0;\n background: var(--mj-bg-overlay);\n z-index: 100000;\n}\n\n.slide-panel {\n position: fixed;\n top: 0;\n right: 0;\n height: 100vh;\n width: 480px;\n max-width: 90vw;\n background: var(--mj-bg-surface);\n box-shadow: -4px 0 24px color-mix(in srgb, var(--mj-text-primary) 12%, transparent);\n transform: translateX(100%);\n transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n overflow-y: auto;\n}\n\n.slide-panel.open {\n transform: translateX(0);\n}\n\n.suggest-dialog-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px 24px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.suggest-dialog-title {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.suggest-dialog-title i {\n color: var(--mj-brand-primary);\n}\n\n.suggest-close-btn {\n border: none;\n background: none;\n color: var(--mj-text-muted);\n font-size: 16px;\n cursor: pointer;\n padding: 4px;\n}\n\n.suggest-close-btn:hover {\n color: var(--mj-text-primary);\n}\n\n.suggest-dialog-body {\n padding: 24px;\n}\n\n/* --- Suggest Form --- */\n.suggest-form {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.suggest-field {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.suggest-label {\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n.suggest-select {\n padding: 8px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n}\n\n.suggest-select:focus {\n outline: none;\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n/* ---- Use Case Button Group ---- */\n\n.use-case-options {\n display: flex;\n gap: 8px;\n flex-wrap: wrap;\n}\n\n.use-case-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.use-case-btn:hover {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-border-strong);\n color: var(--mj-text-primary);\n}\n\n.use-case-btn-active {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n.use-case-btn i {\n font-size: 12px;\n}\n\n/* ---- Entity Picker (grouped by schema) ---- */\n\n.entity-picker {\n position: relative;\n}\n\n.entity-picker-trigger {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n padding: 9px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n cursor: pointer;\n text-align: left;\n transition: border-color 0.15s;\n}\n\n.entity-picker-trigger:hover {\n border-color: var(--mj-border-strong);\n}\n\n.entity-picker-placeholder {\n color: var(--mj-text-muted);\n flex: 1;\n}\n\n.entity-picker-value {\n flex: 1;\n font-weight: 500;\n}\n\n.entity-picker-arrow {\n font-size: 10px;\n color: var(--mj-text-muted);\n transition: transform 0.2s;\n}\n\n.entity-picker-dropdown {\n position: absolute;\n top: calc(100% + 4px);\n left: 0;\n right: 0;\n background: var(--mj-bg-surface-elevated, var(--mj-bg-surface));\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n box-shadow: 0 8px 32px color-mix(in srgb, var(--mj-text-primary) 15%, transparent);\n z-index: 100;\n max-height: 350px;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n.entity-picker-search {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 14px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.entity-picker-search i {\n color: var(--mj-text-muted);\n font-size: 13px;\n}\n\n.entity-picker-search-input {\n flex: 1;\n border: none;\n background: transparent;\n color: var(--mj-text-primary);\n font-size: 13px;\n outline: none;\n}\n\n.entity-picker-search-input::placeholder {\n color: var(--mj-text-disabled);\n}\n\n.entity-picker-list {\n overflow-y: auto;\n max-height: 300px;\n padding: 4px 0;\n}\n\n.entity-picker-group-header {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 14px 4px;\n font-size: 11px;\n font-weight: 700;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n position: sticky;\n top: 0;\n background: var(--mj-bg-surface-elevated, var(--mj-bg-surface));\n}\n\n.entity-picker-group-header i {\n font-size: 10px;\n}\n\n.entity-picker-item {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n padding: 7px 14px 7px 28px;\n border: none;\n background: transparent;\n color: var(--mj-text-primary);\n font-size: 13px;\n cursor: pointer;\n text-align: left;\n transition: background 0.1s;\n}\n\n.entity-picker-item:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.entity-picker-item-selected {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n.entity-picker-item i {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.entity-picker-item-selected i {\n color: var(--mj-brand-primary);\n}\n\n.entity-picker-item-focused {\n background: var(--mj-bg-surface-hover);\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: -2px;\n}\n\n.entity-picker-empty {\n padding: 20px 14px;\n text-align: center;\n color: var(--mj-text-disabled);\n font-size: 13px;\n}\n\n/* ---- Template Editor ---- */\n\n.template-editor-wrapper {\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n min-height: 120px;\n max-height: 300px;\n}\n\n.template-editor-wrapper ::ng-deep .cm-editor {\n min-height: 120px;\n max-height: 300px;\n font-size: 13px;\n}\n\n.suggest-submit-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n padding: 10px 20px;\n border: none;\n border-radius: 6px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.2s ease;\n}\n\n.suggest-submit-btn:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n\n.suggest-submit-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n/* --- Suggestion Result --- */\n.suggest-result {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.result-section {\n border-bottom: 1px solid var(--mj-border-subtle);\n padding-bottom: 12px;\n}\n\n.result-section:last-child {\n border-bottom: none;\n}\n\n.result-heading {\n margin: 0 0 8px 0;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.result-template {\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 6px;\n padding: 12px;\n font-size: 12px;\n color: var(--mj-text-primary);\n white-space: pre-wrap;\n word-break: break-all;\n margin: 0;\n}\n\n.result-tags {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n}\n\n.result-tag {\n padding: 3px 10px;\n border-radius: 12px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 12px;\n font-weight: 500;\n}\n\n.result-relationship {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 4px 0;\n}\n\n.rel-name {\n font-weight: 600;\n font-size: 13px;\n color: var(--mj-text-primary);\n}\n\n.rel-fields {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.result-thresholds {\n display: flex;\n gap: 24px;\n}\n\n.threshold-item {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.threshold-label {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.threshold-value {\n font-size: 18px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.result-reasoning {\n margin: 0;\n font-size: 13px;\n color: var(--mj-text-secondary);\n line-height: 1.5;\n}\n\n.result-actions {\n display: flex;\n gap: 8px;\n padding-top: 8px;\n}\n\n.suggest-close-action {\n padding: 10px 20px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n}\n\n.suggest-close-action:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n/* --- Suggest Input --- */\n.suggest-input {\n padding: 8px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n width: 100%;\n box-sizing: border-box;\n}\n\n.suggest-input:focus {\n outline: none;\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n/* --- Try Again Button (secondary style) --- */\n.suggest-try-again-btn {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n border: 1px solid var(--mj-brand-primary);\n}\n\n.suggest-try-again-btn:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n/* --- Save Spinner --- */\n.save-spinner {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 8px 0;\n}\n\n/* --- Edit Panel Template Header --- */\n.edit-template-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n}\n\n.edit-regenerate-btn {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 10px;\n border: 1px solid var(--mj-brand-primary);\n border-radius: 6px;\n background: transparent;\n color: var(--mj-brand-primary);\n font-size: 11px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n white-space: nowrap;\n}\n\n.edit-regenerate-btn:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.edit-regenerate-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n/* --- No Vector Index Warning Dialog --- */\n.no-index-warning-dialog {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 440px;\n max-width: 90vw;\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: 0 20px 60px color-mix(in srgb, var(--mj-text-primary) 20%, transparent);\n padding: 32px;\n text-align: center;\n}\n\n.no-index-warning-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 56px;\n height: 56px;\n margin: 0 auto 16px;\n border-radius: 50%;\n background: color-mix(in srgb, var(--mj-status-warning) 12%, var(--mj-bg-surface));\n}\n\n.no-index-warning-icon i {\n font-size: 24px;\n color: var(--mj-status-warning);\n}\n\n.no-index-warning-title {\n margin: 0 0 8px 0;\n font-size: 18px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.no-index-warning-message {\n margin: 0 0 24px 0;\n font-size: 14px;\n line-height: 1.5;\n color: var(--mj-text-secondary);\n}\n\n.no-index-warning-actions {\n display: flex;\n gap: 8px;\n justify-content: center;\n}\n\n/* ================================================================\n Responsive \u2014 Vector Management\n ================================================================ */\n\n@media (max-width: 768px) {\n .panel-header {\n flex-direction: column;\n align-items: flex-start;\n gap: 12px;\n }\n\n .panel-actions {\n flex-wrap: wrap;\n }\n}\n\n@media (max-width: 600px) {\n .slide-panel {\n width: 100vw;\n max-width: 100vw;\n }\n}\n\n@media (max-width: 480px) {\n .vector-dashboard {\n padding: 12px;\n }\n\n .suggest-btn .suggest-btn-text {\n display: none;\n }\n}\n"] }]
|
|
2513
2711
|
}], null, { HideToolbar: [{
|
|
2514
2712
|
type: Input
|
|
2515
2713
|
}], EntitySearchInput: [{
|
|
2516
2714
|
type: ViewChild,
|
|
2517
2715
|
args: ['entitySearchInput']
|
|
2518
2716
|
}] }); })();
|
|
2519
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(VectorManagementResourceComponent, { className: "VectorManagementResourceComponent", filePath: "src/AI/components/vectors/vector-management-resource.component.ts", lineNumber:
|
|
2717
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(VectorManagementResourceComponent, { className: "VectorManagementResourceComponent", filePath: "src/AI/components/vectors/vector-management-resource.component.ts", lineNumber: 92 }); })();
|
|
2520
2718
|
export function LoadVectorManagementResource() {
|
|
2521
2719
|
// Prevents tree-shaking
|
|
2522
2720
|
}
|