@memberjunction/ng-dashboards 6.2.0-edge.3 → 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/analytics/realtime/realtime-transcripts-data.d.ts +4 -3
- package/dist/AI/components/analytics/realtime/realtime-transcripts-data.d.ts.map +1 -1
- package/dist/AI/components/analytics/realtime/realtime-transcripts-data.js +8 -5
- package/dist/AI/components/analytics/realtime/realtime-transcripts-data.js.map +1 -1
- package/dist/AI/components/duplicates/compare-value.component.d.ts +67 -0
- package/dist/AI/components/duplicates/compare-value.component.d.ts.map +1 -0
- package/dist/AI/components/duplicates/compare-value.component.js +168 -0
- package/dist/AI/components/duplicates/compare-value.component.js.map +1 -0
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts +49 -3
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts.map +1 -1
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.js +287 -169
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.js.map +1 -1
- package/dist/AI/components/duplicates/duplicate-detection-run-scope.d.ts +77 -0
- package/dist/AI/components/duplicates/duplicate-detection-run-scope.d.ts.map +1 -0
- package/dist/AI/components/duplicates/duplicate-detection-run-scope.js +116 -0
- package/dist/AI/components/duplicates/duplicate-detection-run-scope.js.map +1 -0
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.d.ts +1 -0
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.d.ts.map +1 -1
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js +16 -4
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js.map +1 -1
- package/dist/AI/components/tags/tags-resource.component.d.ts +2 -0
- package/dist/AI/components/tags/tags-resource.component.d.ts.map +1 -1
- package/dist/AI/components/tags/tags-resource.component.js +12 -6
- package/dist/AI/components/tags/tags-resource.component.js.map +1 -1
- 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-index-auto.d.ts +29 -0
- package/dist/AI/components/vectors/vector-index-auto.d.ts.map +1 -0
- package/dist/AI/components/vectors/vector-index-auto.js +59 -0
- package/dist/AI/components/vectors/vector-index-auto.js.map +1 -0
- package/dist/AI/components/vectors/vector-management-resource.component.d.ts +58 -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 +493 -250
- package/dist/AI/components/vectors/vector-management-resource.component.js.map +1 -1
- package/dist/Actions/components/actions-overview.component.d.ts.map +1 -1
- package/dist/Actions/components/actions-overview.component.js +7 -3
- package/dist/Actions/components/actions-overview.component.js.map +1 -1
- package/dist/Actions/components/categories-list-view.component.d.ts.map +1 -1
- package/dist/Actions/components/categories-list-view.component.js +3 -2
- package/dist/Actions/components/categories-list-view.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/ComponentStudio/component-studio-dashboard.component.d.ts.map +1 -1
- package/dist/ComponentStudio/component-studio-dashboard.component.js +1 -0
- package/dist/ComponentStudio/component-studio-dashboard.component.js.map +1 -1
- package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.d.ts +0 -3
- package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.js +5 -14
- package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.js.map +1 -1
- package/dist/ComponentStudio/components/artifact-load-dialog.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/artifact-load-dialog.component.js +1 -0
- package/dist/ComponentStudio/components/artifact-load-dialog.component.js.map +1 -1
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.js +1 -0
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.js.map +1 -1
- package/dist/Credentials/components/credentials-list-resource.component.d.ts +2 -0
- package/dist/Credentials/components/credentials-list-resource.component.d.ts.map +1 -1
- package/dist/Credentials/components/credentials-list-resource.component.js +12 -10
- package/dist/Credentials/components/credentials-list-resource.component.js.map +1 -1
- package/dist/DashboardBrowser/dashboard-browser-agent-context.d.ts +14 -43
- package/dist/DashboardBrowser/dashboard-browser-agent-context.d.ts.map +1 -1
- package/dist/DashboardBrowser/dashboard-browser-agent-context.js +6 -29
- package/dist/DashboardBrowser/dashboard-browser-agent-context.js.map +1 -1
- package/dist/DashboardBrowser/dashboard-browser-resource.component.d.ts +174 -321
- package/dist/DashboardBrowser/dashboard-browser-resource.component.d.ts.map +1 -1
- package/dist/DashboardBrowser/dashboard-browser-resource.component.js +522 -1195
- package/dist/DashboardBrowser/dashboard-browser-resource.component.js.map +1 -1
- package/dist/DashboardBrowser/dashboard-library-filter.d.ts +116 -0
- package/dist/DashboardBrowser/dashboard-library-filter.d.ts.map +1 -0
- package/dist/DashboardBrowser/dashboard-library-filter.js +277 -0
- package/dist/DashboardBrowser/dashboard-library-filter.js.map +1 -0
- package/dist/DashboardBrowser/dashboard-share-dialog.component.d.ts +1 -1
- package/dist/DashboardBrowser/dashboard-share-dialog.component.js.map +1 -1
- package/dist/DashboardBrowser/dashboards-agent-tools.d.ts +26 -0
- package/dist/DashboardBrowser/dashboards-agent-tools.d.ts.map +1 -0
- package/dist/DashboardBrowser/dashboards-agent-tools.js +32 -0
- package/dist/DashboardBrowser/dashboards-agent-tools.js.map +1 -0
- package/dist/DashboardBrowser/dashboards-categories-resource.component.d.ts +58 -0
- package/dist/DashboardBrowser/dashboards-categories-resource.component.d.ts.map +1 -0
- package/dist/DashboardBrowser/dashboards-categories-resource.component.js +391 -0
- package/dist/DashboardBrowser/dashboards-categories-resource.component.js.map +1 -0
- package/dist/DashboardBrowser/dashboards-categories.helpers.d.ts +37 -0
- package/dist/DashboardBrowser/dashboards-categories.helpers.d.ts.map +1 -0
- package/dist/DashboardBrowser/dashboards-categories.helpers.js +68 -0
- package/dist/DashboardBrowser/dashboards-categories.helpers.js.map +1 -0
- package/dist/DashboardEditor/dashboard-editor.component.d.ts +295 -0
- package/dist/DashboardEditor/dashboard-editor.component.d.ts.map +1 -0
- package/dist/DashboardEditor/dashboard-editor.component.js +1022 -0
- package/dist/DashboardEditor/dashboard-editor.component.js.map +1 -0
- package/dist/DashboardEditor/dashboard-editor.types.d.ts +23 -0
- package/dist/DashboardEditor/dashboard-editor.types.d.ts.map +1 -0
- package/dist/DashboardEditor/dashboard-editor.types.js +3 -0
- package/dist/DashboardEditor/dashboard-editor.types.js.map +1 -0
- package/dist/DashboardEditor/dashboard-viewer-factory.d.ts +11 -0
- package/dist/DashboardEditor/dashboard-viewer-factory.d.ts.map +1 -0
- package/dist/DashboardEditor/dashboard-viewer-factory.js +17 -0
- package/dist/DashboardEditor/dashboard-viewer-factory.js.map +1 -0
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +51 -0
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.js +375 -223
- package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
- package/dist/DataExplorer/services/explorer-state.service.d.ts +1 -1
- package/dist/DataExplorer/services/explorer-state.service.js +2 -5
- package/dist/DataExplorer/services/explorer-state.service.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/FormBuilder/form-builder-resource.component.d.ts +0 -14
- package/dist/FormBuilder/form-builder-resource.component.d.ts.map +1 -1
- package/dist/FormBuilder/form-builder-resource.component.js +7 -29
- package/dist/FormBuilder/form-builder-resource.component.js.map +1 -1
- package/dist/Home/home-agent-context.d.ts +29 -10
- package/dist/Home/home-agent-context.d.ts.map +1 -1
- package/dist/Home/home-agent-context.js +50 -24
- package/dist/Home/home-agent-context.js.map +1 -1
- package/dist/Home/home-dashboard-switcher.component.d.ts +95 -0
- package/dist/Home/home-dashboard-switcher.component.d.ts.map +1 -0
- package/dist/Home/home-dashboard-switcher.component.js +442 -0
- package/dist/Home/home-dashboard-switcher.component.js.map +1 -0
- package/dist/Home/home-dashboard.component.d.ts +330 -17
- package/dist/Home/home-dashboard.component.d.ts.map +1 -1
- package/dist/Home/home-dashboard.component.js +1702 -1014
- package/dist/Home/home-dashboard.component.js.map +1 -1
- package/dist/Home/home-menus.d.ts +38 -0
- package/dist/Home/home-menus.d.ts.map +1 -0
- package/dist/Home/home-menus.js +53 -0
- package/dist/Home/home-menus.js.map +1 -0
- package/dist/Home/home-pinned-dashboards.d.ts +33 -0
- package/dist/Home/home-pinned-dashboards.d.ts.map +1 -0
- package/dist/Home/home-pinned-dashboards.js +76 -0
- package/dist/Home/home-pinned-dashboards.js.map +1 -0
- 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/PredictiveStudio/components/ps-production.component.d.ts +5 -1
- package/dist/PredictiveStudio/components/ps-production.component.d.ts.map +1 -1
- package/dist/PredictiveStudio/components/ps-production.component.js +64 -41
- package/dist/PredictiveStudio/components/ps-production.component.js.map +1 -1
- package/dist/QueryBrowser/query-browser-resource.component.d.ts.map +1 -1
- package/dist/QueryBrowser/query-browser-resource.component.js +3 -2
- package/dist/QueryBrowser/query-browser-resource.component.js.map +1 -1
- package/dist/RealtimeRecordings/realtime-recordings-dashboard.component.js +2 -2
- package/dist/RealtimeRecordings/realtime-recordings-dashboard.component.js.map +1 -1
- package/dist/TelephonyOperations/telephony-operations-dashboard.component.d.ts +1 -0
- package/dist/TelephonyOperations/telephony-operations-dashboard.component.d.ts.map +1 -1
- package/dist/TelephonyOperations/telephony-operations-dashboard.component.js +7 -0
- package/dist/TelephonyOperations/telephony-operations-dashboard.component.js.map +1 -1
- package/dist/Testing/components/testing-explorer.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-explorer.component.js +7 -7
- package/dist/Testing/components/testing-explorer.component.js.map +1 -1
- 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/ai-dashboards.module.d.ts +21 -20
- package/dist/ai-dashboards.module.d.ts.map +1 -1
- package/dist/ai-dashboards.module.js +4 -1
- package/dist/ai-dashboards.module.js.map +1 -1
- package/dist/core-dashboards.module.d.ts +70 -62
- package/dist/core-dashboards.module.d.ts.map +1 -1
- package/dist/core-dashboards.module.js +33 -5
- package/dist/core-dashboards.module.js.map +1 -1
- package/dist/data-explorer-dashboards.module.d.ts +1 -1
- package/dist/data-explorer-dashboards.module.d.ts.map +1 -1
- package/dist/data-explorer-dashboards.module.js +3 -1
- package/dist/data-explorer-dashboards.module.js.map +1 -1
- package/dist/public-api.d.ts +3 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +4 -0
- package/dist/public-api.js.map +1 -1
- package/dist/shared/dashboard-library-changes.d.ts +23 -0
- package/dist/shared/dashboard-library-changes.d.ts.map +1 -0
- package/dist/shared/dashboard-library-changes.js +26 -0
- package/dist/shared/dashboard-library-changes.js.map +1 -0
- package/dist/shared/dashboard-owner-names.d.ts +17 -0
- package/dist/shared/dashboard-owner-names.d.ts.map +1 -0
- package/dist/shared/dashboard-owner-names.js +65 -0
- package/dist/shared/dashboard-owner-names.js.map +1 -0
- package/dist/shared/dashboard-recents.d.ts +34 -0
- package/dist/shared/dashboard-recents.d.ts.map +1 -0
- package/dist/shared/dashboard-recents.js +87 -0
- package/dist/shared/dashboard-recents.js.map +1 -0
- package/dist/shared/dashboards-app-install.d.ts +59 -0
- package/dist/shared/dashboards-app-install.d.ts.map +1 -0
- package/dist/shared/dashboards-app-install.js +97 -0
- package/dist/shared/dashboards-app-install.js.map +1 -0
- package/dist/shared/dashboards-app.helpers.d.ts +42 -0
- package/dist/shared/dashboards-app.helpers.d.ts.map +1 -0
- package/dist/shared/dashboards-app.helpers.js +143 -0
- package/dist/shared/dashboards-app.helpers.js.map +1 -0
- package/package.json +73 -69
|
@@ -17,15 +17,18 @@ 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';
|
|
24
24
|
import { MJNotificationService } from '@memberjunction/ng-notifications';
|
|
25
25
|
import { BuildSingleStaticParamConfiguration, ResolveActionJobTypeID } from '../../../shared/action-scheduled-job';
|
|
26
26
|
import { CronToHumanReadable } from '../autotagging/shared/classify.format';
|
|
27
|
+
import { BuildAutoVectorIndexName, FindMatchingVectorIndex } from './vector-index-auto';
|
|
27
28
|
import { BuildVectorAgentContext, ResolveSyncRow, } from './vector-management-agent-context';
|
|
28
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';
|
|
29
32
|
import * as i0 from "@angular/core";
|
|
30
33
|
import * as i1 from "@angular/common";
|
|
31
34
|
import * as i2 from "@angular/forms";
|
|
@@ -84,31 +87,31 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_For_3_Tem
|
|
|
84
87
|
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_18_Template(rf, ctx) { if (rf & 1) {
|
|
85
88
|
i0.ɵɵelement(0, "mj-empty-state", 23);
|
|
86
89
|
} }
|
|
87
|
-
function
|
|
90
|
+
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_19_For_20_Conditional_15_Template(rf, ctx) { if (rf & 1) {
|
|
88
91
|
i0.ɵɵtext(0);
|
|
89
92
|
} if (rf & 2) {
|
|
90
93
|
const row_r7 = i0.ɵɵnextContext().$implicit;
|
|
91
94
|
i0.ɵɵtextInterpolate1(" ", row_r7.PercentComplete, "% ");
|
|
92
95
|
} }
|
|
93
|
-
function
|
|
96
|
+
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_19_For_20_Conditional_16_Template(rf, ctx) { if (rf & 1) {
|
|
94
97
|
i0.ɵɵtext(0);
|
|
95
98
|
} if (rf & 2) {
|
|
96
99
|
const row_r7 = i0.ɵɵnextContext().$implicit;
|
|
97
100
|
i0.ɵɵtextInterpolate1(" ", row_r7.Status, " ");
|
|
98
101
|
} }
|
|
99
|
-
function
|
|
100
|
-
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);
|
|
101
104
|
i0.ɵɵtext(1);
|
|
102
105
|
} if (rf & 2) {
|
|
103
106
|
const row_r7 = i0.ɵɵnextContext().$implicit;
|
|
104
107
|
i0.ɵɵadvance();
|
|
105
108
|
i0.ɵɵtextInterpolate1(" ", row_r7.PercentComplete > 0 ? row_r7.PercentComplete + "%" : "Sync", " ");
|
|
106
109
|
} }
|
|
107
|
-
function
|
|
108
|
-
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);
|
|
109
112
|
i0.ɵɵtext(1, " Sync ");
|
|
110
113
|
} }
|
|
111
|
-
function
|
|
114
|
+
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_19_For_20_Template(rf, ctx) { if (rf & 1) {
|
|
112
115
|
const _r6 = i0.ɵɵgetCurrentView();
|
|
113
116
|
i0.ɵɵelementStart(0, "tr")(1, "td", 49);
|
|
114
117
|
i0.ɵɵtext(2);
|
|
@@ -118,26 +121,29 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
118
121
|
i0.ɵɵelementEnd();
|
|
119
122
|
i0.ɵɵelementStart(5, "td", 51);
|
|
120
123
|
i0.ɵɵtext(6);
|
|
121
|
-
i0.ɵɵpipe(7, "number");
|
|
122
124
|
i0.ɵɵelementEnd();
|
|
123
|
-
i0.ɵɵelementStart(
|
|
124
|
-
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);
|
|
125
131
|
i0.ɵɵelementEnd();
|
|
126
|
-
i0.ɵɵelementStart(
|
|
127
|
-
i0.ɵɵelement(
|
|
128
|
-
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);
|
|
129
135
|
i0.ɵɵelementEnd()();
|
|
130
|
-
i0.ɵɵelementStart(
|
|
131
|
-
i0.ɵɵlistener("click", function
|
|
132
|
-
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);
|
|
133
139
|
i0.ɵɵelementEnd();
|
|
134
|
-
i0.ɵɵelementStart(
|
|
135
|
-
i0.ɵɵlistener("click", function
|
|
136
|
-
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);
|
|
137
143
|
i0.ɵɵelementEnd();
|
|
138
|
-
i0.ɵɵelementStart(
|
|
139
|
-
i0.ɵɵlistener("click", function
|
|
140
|
-
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);
|
|
141
147
|
i0.ɵɵelementEnd()()();
|
|
142
148
|
} if (rf & 2) {
|
|
143
149
|
const row_r7 = ctx.$implicit;
|
|
@@ -147,7 +153,9 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
147
153
|
i0.ɵɵadvance(2);
|
|
148
154
|
i0.ɵɵtextInterpolate(row_r7.DocumentName);
|
|
149
155
|
i0.ɵɵadvance(2);
|
|
150
|
-
i0.ɵɵtextInterpolate(
|
|
156
|
+
i0.ɵɵtextInterpolate(row_r7.DocumentType);
|
|
157
|
+
i0.ɵɵadvance(2);
|
|
158
|
+
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind1(9, 12, row_r7.VectorCount));
|
|
151
159
|
i0.ɵɵadvance(3);
|
|
152
160
|
i0.ɵɵtextInterpolate(ctx_r1.FormatDate(row_r7.LastSynced));
|
|
153
161
|
i0.ɵɵadvance(2);
|
|
@@ -155,11 +163,11 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
155
163
|
i0.ɵɵadvance();
|
|
156
164
|
i0.ɵɵclassMap(ctx_r1.GetStatusIcon(row_r7.Status));
|
|
157
165
|
i0.ɵɵadvance();
|
|
158
|
-
i0.ɵɵconditional(row_r7.Status === "Syncing" && row_r7.PercentComplete > 0 ?
|
|
166
|
+
i0.ɵɵconditional(row_r7.Status === "Syncing" && row_r7.PercentComplete > 0 ? 15 : 16);
|
|
159
167
|
i0.ɵɵadvance(3);
|
|
160
168
|
i0.ɵɵproperty("disabled", ctx_r1.IsSyncing(row_r7.EntityDocumentID));
|
|
161
169
|
i0.ɵɵadvance();
|
|
162
|
-
i0.ɵɵconditional(ctx_r1.IsSyncing(row_r7.EntityDocumentID) ?
|
|
170
|
+
i0.ɵɵconditional(ctx_r1.IsSyncing(row_r7.EntityDocumentID) ? 19 : 20);
|
|
163
171
|
} }
|
|
164
172
|
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_19_Template(rf, ctx) { if (rf & 1) {
|
|
165
173
|
i0.ɵɵelementStart(0, "div", 24)(1, "table", 46)(2, "thead")(3, "tr")(4, "th");
|
|
@@ -168,24 +176,27 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
168
176
|
i0.ɵɵelementStart(6, "th");
|
|
169
177
|
i0.ɵɵtext(7, "Document");
|
|
170
178
|
i0.ɵɵelementEnd();
|
|
171
|
-
i0.ɵɵelementStart(8, "th"
|
|
172
|
-
i0.ɵɵtext(9, "
|
|
179
|
+
i0.ɵɵelementStart(8, "th");
|
|
180
|
+
i0.ɵɵtext(9, "Type");
|
|
173
181
|
i0.ɵɵelementEnd();
|
|
174
|
-
i0.ɵɵelementStart(10, "th");
|
|
175
|
-
i0.ɵɵtext(11, "
|
|
182
|
+
i0.ɵɵelementStart(10, "th", 47);
|
|
183
|
+
i0.ɵɵtext(11, "Vectors");
|
|
176
184
|
i0.ɵɵelementEnd();
|
|
177
185
|
i0.ɵɵelementStart(12, "th");
|
|
178
|
-
i0.ɵɵtext(13, "
|
|
186
|
+
i0.ɵɵtext(13, "Last Synced");
|
|
187
|
+
i0.ɵɵelementEnd();
|
|
188
|
+
i0.ɵɵelementStart(14, "th");
|
|
189
|
+
i0.ɵɵtext(15, "Status");
|
|
179
190
|
i0.ɵɵelementEnd();
|
|
180
|
-
i0.ɵɵelementStart(
|
|
181
|
-
i0.ɵɵtext(
|
|
191
|
+
i0.ɵɵelementStart(16, "th", 48);
|
|
192
|
+
i0.ɵɵtext(17, "Actions");
|
|
182
193
|
i0.ɵɵelementEnd()()();
|
|
183
|
-
i0.ɵɵelementStart(
|
|
184
|
-
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);
|
|
185
196
|
i0.ɵɵelementEnd()()();
|
|
186
197
|
} if (rf & 2) {
|
|
187
198
|
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
188
|
-
i0.ɵɵadvance(
|
|
199
|
+
i0.ɵɵadvance(19);
|
|
189
200
|
i0.ɵɵrepeater(ctx_r1.SyncRows);
|
|
190
201
|
} }
|
|
191
202
|
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_31_Template(rf, ctx) { if (rf & 1) {
|
|
@@ -201,7 +212,7 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
201
212
|
i0.ɵɵelementStart(0, "div", 36)(1, "span", 37);
|
|
202
213
|
i0.ɵɵtext(2, "Dimensions");
|
|
203
214
|
i0.ɵɵelementEnd();
|
|
204
|
-
i0.ɵɵelementStart(3, "span",
|
|
215
|
+
i0.ɵɵelementStart(3, "span", 63);
|
|
205
216
|
i0.ɵɵtext(4);
|
|
206
217
|
i0.ɵɵpipe(5, "number");
|
|
207
218
|
i0.ɵɵelementEnd()();
|
|
@@ -210,16 +221,16 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
210
221
|
i0.ɵɵadvance(4);
|
|
211
222
|
i0.ɵɵtextInterpolate(i0.ɵɵpipeBind1(5, 1, ctx_r1.EmbeddingModel.Dimensions));
|
|
212
223
|
} }
|
|
213
|
-
function
|
|
214
|
-
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);
|
|
215
226
|
i0.ɵɵtext(1, " Regenerating... ");
|
|
216
227
|
} }
|
|
217
|
-
function
|
|
228
|
+
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_26_Template(rf, ctx) { if (rf & 1) {
|
|
218
229
|
i0.ɵɵelement(0, "i", 19);
|
|
219
230
|
i0.ɵɵtext(1, " Regenerate with AI ");
|
|
220
231
|
} }
|
|
221
|
-
function
|
|
222
|
-
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);
|
|
223
234
|
i0.ɵɵtext(1);
|
|
224
235
|
i0.ɵɵelementEnd();
|
|
225
236
|
} if (rf & 2) {
|
|
@@ -227,20 +238,20 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
227
238
|
i0.ɵɵadvance();
|
|
228
239
|
i0.ɵɵtextInterpolate(field_r9);
|
|
229
240
|
} }
|
|
230
|
-
function
|
|
231
|
-
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);
|
|
232
243
|
i0.ɵɵtext(2, "Selected Fields");
|
|
233
244
|
i0.ɵɵelementEnd();
|
|
234
|
-
i0.ɵɵelementStart(3, "div",
|
|
235
|
-
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);
|
|
236
247
|
i0.ɵɵelementEnd()();
|
|
237
248
|
} if (rf & 2) {
|
|
238
249
|
const ctx_r1 = i0.ɵɵnextContext(4);
|
|
239
250
|
i0.ɵɵadvance(4);
|
|
240
251
|
i0.ɵɵrepeater(ctx_r1.EditDocSelectedFields);
|
|
241
252
|
} }
|
|
242
|
-
function
|
|
243
|
-
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);
|
|
244
255
|
i0.ɵɵtext(1);
|
|
245
256
|
i0.ɵɵelementEnd();
|
|
246
257
|
} if (rf & 2) {
|
|
@@ -249,8 +260,8 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
249
260
|
i0.ɵɵadvance();
|
|
250
261
|
i0.ɵɵtextInterpolate(model_r10.Name);
|
|
251
262
|
} }
|
|
252
|
-
function
|
|
253
|
-
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);
|
|
254
265
|
i0.ɵɵtext(1);
|
|
255
266
|
i0.ɵɵelementEnd();
|
|
256
267
|
} if (rf & 2) {
|
|
@@ -259,8 +270,8 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
259
270
|
i0.ɵɵadvance();
|
|
260
271
|
i0.ɵɵtextInterpolate(db_r11.Name);
|
|
261
272
|
} }
|
|
262
|
-
function
|
|
263
|
-
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);
|
|
264
275
|
i0.ɵɵtext(1);
|
|
265
276
|
i0.ɵɵelementEnd();
|
|
266
277
|
} if (rf & 2) {
|
|
@@ -269,14 +280,14 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
269
280
|
i0.ɵɵadvance();
|
|
270
281
|
i0.ɵɵtextInterpolate(idx_r13.Name);
|
|
271
282
|
} }
|
|
272
|
-
function
|
|
283
|
+
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_49_Template(rf, ctx) { if (rf & 1) {
|
|
273
284
|
const _r12 = i0.ɵɵgetCurrentView();
|
|
274
|
-
i0.ɵɵelementStart(0, "select",
|
|
275
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
276
|
-
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);
|
|
277
288
|
i0.ɵɵtext(2, "Auto (create/find matching index)");
|
|
278
289
|
i0.ɵɵelementEnd();
|
|
279
|
-
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);
|
|
280
291
|
i0.ɵɵelementEnd();
|
|
281
292
|
} if (rf & 2) {
|
|
282
293
|
const ctx_r1 = i0.ɵɵnextContext(4);
|
|
@@ -284,113 +295,121 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
284
295
|
i0.ɵɵadvance(3);
|
|
285
296
|
i0.ɵɵrepeater(ctx_r1.EditFilteredIndexes);
|
|
286
297
|
} }
|
|
287
|
-
function
|
|
288
|
-
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);
|
|
289
300
|
i0.ɵɵtext(1, " No indexes for this database \u2014 one will be created automatically on sync ");
|
|
290
301
|
i0.ɵɵelementEnd();
|
|
291
302
|
} }
|
|
292
|
-
function
|
|
293
|
-
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);
|
|
294
305
|
} }
|
|
295
|
-
function
|
|
306
|
+
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_61_Template(rf, ctx) { if (rf & 1) {
|
|
296
307
|
const _r14 = i0.ɵɵgetCurrentView();
|
|
297
|
-
i0.ɵɵelementStart(0, "button",
|
|
298
|
-
i0.ɵɵlistener("click", function
|
|
299
|
-
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);
|
|
300
311
|
i0.ɵɵtext(2, " Save Changes ");
|
|
301
312
|
i0.ɵɵelementEnd();
|
|
302
|
-
i0.ɵɵelementStart(3, "button",
|
|
303
|
-
i0.ɵɵlistener("click", function
|
|
304
|
-
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);
|
|
305
316
|
i0.ɵɵtext(5, " Delete ");
|
|
306
317
|
i0.ɵɵelementEnd();
|
|
307
|
-
i0.ɵɵelementStart(6, "button",
|
|
308
|
-
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()); });
|
|
309
320
|
i0.ɵɵtext(7, " Cancel ");
|
|
310
321
|
i0.ɵɵelementEnd();
|
|
311
322
|
} }
|
|
312
323
|
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Template(rf, ctx) { if (rf & 1) {
|
|
313
324
|
const _r8 = i0.ɵɵgetCurrentView();
|
|
314
|
-
i0.ɵɵelementStart(0, "div",
|
|
325
|
+
i0.ɵɵelementStart(0, "div", 64);
|
|
315
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()); });
|
|
316
|
-
i0.ɵɵelementStart(1, "div",
|
|
327
|
+
i0.ɵɵelementStart(1, "div", 65);
|
|
317
328
|
i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Template_div_click_1_listener($event) { return $event.stopPropagation(); });
|
|
318
|
-
i0.ɵɵelementStart(2, "div",
|
|
319
|
-
i0.ɵɵelement(4, "i",
|
|
329
|
+
i0.ɵɵelementStart(2, "div", 66)(3, "h3", 67);
|
|
330
|
+
i0.ɵɵelement(4, "i", 60);
|
|
320
331
|
i0.ɵɵtext(5, " Edit Entity Document ");
|
|
321
332
|
i0.ɵɵelementEnd();
|
|
322
|
-
i0.ɵɵelementStart(6, "button",
|
|
333
|
+
i0.ɵɵelementStart(6, "button", 68);
|
|
323
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()); });
|
|
324
|
-
i0.ɵɵelement(7, "i",
|
|
335
|
+
i0.ɵɵelement(7, "i", 69);
|
|
325
336
|
i0.ɵɵelementEnd()();
|
|
326
|
-
i0.ɵɵelementStart(8, "div",
|
|
337
|
+
i0.ɵɵelementStart(8, "div", 70)(9, "div", 71)(10, "div", 72)(11, "label", 73);
|
|
327
338
|
i0.ɵɵtext(12, "Entity");
|
|
328
339
|
i0.ɵɵelementEnd();
|
|
329
|
-
i0.ɵɵelementStart(13, "span",
|
|
340
|
+
i0.ɵɵelementStart(13, "span", 74);
|
|
330
341
|
i0.ɵɵtext(14);
|
|
331
342
|
i0.ɵɵelementEnd()();
|
|
332
|
-
i0.ɵɵelementStart(15, "div",
|
|
333
|
-
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");
|
|
334
351
|
i0.ɵɵelementEnd();
|
|
335
|
-
i0.ɵɵelementStart(
|
|
336
|
-
i0.ɵɵlistener("click", function
|
|
337
|
-
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);
|
|
338
355
|
i0.ɵɵelementEnd()();
|
|
339
|
-
i0.ɵɵelementStart(
|
|
340
|
-
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)); });
|
|
341
358
|
i0.ɵɵelementEnd()()();
|
|
342
|
-
i0.ɵɵconditionalCreate(
|
|
343
|
-
i0.ɵɵelementStart(
|
|
344
|
-
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");
|
|
345
362
|
i0.ɵɵelementEnd();
|
|
346
|
-
i0.ɵɵelementStart(
|
|
347
|
-
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); });
|
|
348
365
|
i0.ɵɵelementEnd()();
|
|
349
|
-
i0.ɵɵelementStart(
|
|
350
|
-
i0.ɵɵtext(
|
|
366
|
+
i0.ɵɵelementStart(34, "div", 72)(35, "label", 73);
|
|
367
|
+
i0.ɵɵtext(36, "Embedding Model");
|
|
351
368
|
i0.ɵɵelementEnd();
|
|
352
|
-
i0.ɵɵelementStart(
|
|
353
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
354
|
-
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);
|
|
355
372
|
i0.ɵɵelementEnd()();
|
|
356
|
-
i0.ɵɵelementStart(
|
|
357
|
-
i0.ɵɵtext(
|
|
373
|
+
i0.ɵɵelementStart(40, "div", 72)(41, "label", 73);
|
|
374
|
+
i0.ɵɵtext(42, "Vector Database");
|
|
358
375
|
i0.ɵɵelementEnd();
|
|
359
|
-
i0.ɵɵelementStart(
|
|
360
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
361
|
-
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);
|
|
362
379
|
i0.ɵɵelementEnd()();
|
|
363
|
-
i0.ɵɵelementStart(
|
|
364
|
-
i0.ɵɵtext(
|
|
380
|
+
i0.ɵɵelementStart(46, "div", 72)(47, "label", 73);
|
|
381
|
+
i0.ɵɵtext(48, "Vector Index");
|
|
365
382
|
i0.ɵɵelementEnd();
|
|
366
|
-
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);
|
|
367
384
|
i0.ɵɵelementEnd();
|
|
368
|
-
i0.ɵɵelementStart(
|
|
369
|
-
i0.ɵɵtext(
|
|
385
|
+
i0.ɵɵelementStart(51, "div", 72)(52, "label", 73);
|
|
386
|
+
i0.ɵɵtext(53, "Status");
|
|
370
387
|
i0.ɵɵelementEnd();
|
|
371
|
-
i0.ɵɵelementStart(
|
|
372
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
373
|
-
i0.ɵɵelementStart(
|
|
374
|
-
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");
|
|
375
392
|
i0.ɵɵelementEnd();
|
|
376
|
-
i0.ɵɵelementStart(
|
|
377
|
-
i0.ɵɵtext(
|
|
393
|
+
i0.ɵɵelementStart(57, "option", 85);
|
|
394
|
+
i0.ɵɵtext(58, "Inactive");
|
|
378
395
|
i0.ɵɵelementEnd()()();
|
|
379
|
-
i0.ɵɵelementStart(
|
|
380
|
-
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);
|
|
381
398
|
i0.ɵɵelementEnd()()()()();
|
|
382
399
|
} if (rf & 2) {
|
|
383
400
|
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
384
401
|
i0.ɵɵadvance(14);
|
|
385
402
|
i0.ɵɵtextInterpolate(ctx_r1.EditDocEntityName);
|
|
386
403
|
i0.ɵɵadvance(5);
|
|
404
|
+
i0.ɵɵtextInterpolate(ctx_r1.EditDocType);
|
|
405
|
+
i0.ɵɵadvance(5);
|
|
387
406
|
i0.ɵɵproperty("disabled", ctx_r1.IsEditRegenerating);
|
|
388
407
|
i0.ɵɵadvance();
|
|
389
|
-
i0.ɵɵconditional(ctx_r1.IsEditRegenerating ?
|
|
408
|
+
i0.ɵɵconditional(ctx_r1.IsEditRegenerating ? 25 : 26);
|
|
390
409
|
i0.ɵɵadvance(3);
|
|
391
410
|
i0.ɵɵproperty("value", ctx_r1.EditDocTemplate)("readonly", false)("lineWrapping", true);
|
|
392
411
|
i0.ɵɵadvance();
|
|
393
|
-
i0.ɵɵconditional(ctx_r1.EditDocSelectedFields.length > 0 ?
|
|
412
|
+
i0.ɵɵconditional(ctx_r1.EditDocSelectedFields.length > 0 ? 29 : -1);
|
|
394
413
|
i0.ɵɵadvance(4);
|
|
395
414
|
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.EditDocName);
|
|
396
415
|
i0.ɵɵadvance(4);
|
|
@@ -402,71 +421,71 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
402
421
|
i0.ɵɵadvance();
|
|
403
422
|
i0.ɵɵrepeater(ctx_r1.vectorDatabases);
|
|
404
423
|
i0.ɵɵadvance(5);
|
|
405
|
-
i0.ɵɵconditional(ctx_r1.EditFilteredIndexes.length > 0 ?
|
|
424
|
+
i0.ɵɵconditional(ctx_r1.EditFilteredIndexes.length > 0 ? 49 : 50);
|
|
406
425
|
i0.ɵɵadvance(5);
|
|
407
426
|
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.EditDocStatus);
|
|
408
427
|
i0.ɵɵadvance(6);
|
|
409
|
-
i0.ɵɵconditional(ctx_r1.IsEditSaving || ctx_r1.IsEditDeleting ?
|
|
428
|
+
i0.ɵɵconditional(ctx_r1.IsEditSaving || ctx_r1.IsEditDeleting ? 60 : 61);
|
|
410
429
|
} }
|
|
411
430
|
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_56_Conditional_32_Template(rf, ctx) { if (rf & 1) {
|
|
412
|
-
i0.ɵɵelement(0, "mj-loading",
|
|
431
|
+
i0.ɵɵelement(0, "mj-loading", 87);
|
|
413
432
|
} }
|
|
414
433
|
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_56_Conditional_33_Template(rf, ctx) { if (rf & 1) {
|
|
415
434
|
const _r16 = i0.ɵɵgetCurrentView();
|
|
416
|
-
i0.ɵɵelementStart(0, "button",
|
|
435
|
+
i0.ɵɵelementStart(0, "button", 91);
|
|
417
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()); });
|
|
418
|
-
i0.ɵɵelement(1, "i",
|
|
437
|
+
i0.ɵɵelement(1, "i", 102);
|
|
419
438
|
i0.ɵɵtext(2, " Create Schedule ");
|
|
420
439
|
i0.ɵɵelementEnd();
|
|
421
|
-
i0.ɵɵelementStart(3, "button",
|
|
440
|
+
i0.ɵɵelementStart(3, "button", 95);
|
|
422
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()); });
|
|
423
442
|
i0.ɵɵtext(4, " Cancel ");
|
|
424
443
|
i0.ɵɵelementEnd();
|
|
425
444
|
} }
|
|
426
445
|
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_56_Template(rf, ctx) { if (rf & 1) {
|
|
427
446
|
const _r15 = i0.ɵɵgetCurrentView();
|
|
428
|
-
i0.ɵɵelementStart(0, "div",
|
|
447
|
+
i0.ɵɵelementStart(0, "div", 64);
|
|
429
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()); });
|
|
430
|
-
i0.ɵɵelementStart(1, "div",
|
|
449
|
+
i0.ɵɵelementStart(1, "div", 96);
|
|
431
450
|
i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_56_Template_div_click_1_listener($event) { return $event.stopPropagation(); });
|
|
432
|
-
i0.ɵɵelementStart(2, "div",
|
|
433
|
-
i0.ɵɵelement(4, "i",
|
|
451
|
+
i0.ɵɵelementStart(2, "div", 66)(3, "h3", 67);
|
|
452
|
+
i0.ɵɵelement(4, "i", 58);
|
|
434
453
|
i0.ɵɵtext(5, " Schedule Vector Sync ");
|
|
435
454
|
i0.ɵɵelementEnd();
|
|
436
|
-
i0.ɵɵelementStart(6, "button",
|
|
455
|
+
i0.ɵɵelementStart(6, "button", 68);
|
|
437
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()); });
|
|
438
|
-
i0.ɵɵelement(7, "i",
|
|
457
|
+
i0.ɵɵelement(7, "i", 69);
|
|
439
458
|
i0.ɵɵelementEnd()();
|
|
440
|
-
i0.ɵɵelementStart(8, "div",
|
|
459
|
+
i0.ɵɵelementStart(8, "div", 70)(9, "div", 71)(10, "div", 72)(11, "label", 73);
|
|
441
460
|
i0.ɵɵtext(12, "Entity Document");
|
|
442
461
|
i0.ɵɵelementEnd();
|
|
443
|
-
i0.ɵɵelementStart(13, "span",
|
|
462
|
+
i0.ɵɵelementStart(13, "span", 74);
|
|
444
463
|
i0.ɵɵtext(14);
|
|
445
464
|
i0.ɵɵelementEnd()();
|
|
446
|
-
i0.ɵɵelementStart(15, "div",
|
|
465
|
+
i0.ɵɵelementStart(15, "div", 72)(16, "label", 73);
|
|
447
466
|
i0.ɵɵtext(17, "Action");
|
|
448
467
|
i0.ɵɵelementEnd();
|
|
449
|
-
i0.ɵɵelementStart(18, "span",
|
|
468
|
+
i0.ɵɵelementStart(18, "span", 74);
|
|
450
469
|
i0.ɵɵtext(19, "__VectorizeEntity");
|
|
451
470
|
i0.ɵɵelementEnd()();
|
|
452
|
-
i0.ɵɵelementStart(20, "div",
|
|
471
|
+
i0.ɵɵelementStart(20, "div", 72)(21, "label", 73);
|
|
453
472
|
i0.ɵɵtext(22, "Cron Expression");
|
|
454
473
|
i0.ɵɵelementEnd();
|
|
455
|
-
i0.ɵɵelementStart(23, "input",
|
|
474
|
+
i0.ɵɵelementStart(23, "input", 97);
|
|
456
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); });
|
|
457
476
|
i0.ɵɵelementEnd();
|
|
458
|
-
i0.ɵɵelementStart(24, "div",
|
|
459
|
-
i0.ɵɵelement(25, "i",
|
|
477
|
+
i0.ɵɵelementStart(24, "div", 98);
|
|
478
|
+
i0.ɵɵelement(25, "i", 99);
|
|
460
479
|
i0.ɵɵtext(26);
|
|
461
480
|
i0.ɵɵelementEnd()();
|
|
462
|
-
i0.ɵɵelementStart(27, "div",
|
|
481
|
+
i0.ɵɵelementStart(27, "div", 100)(28, "label", 73);
|
|
463
482
|
i0.ɵɵtext(29, "Enabled");
|
|
464
483
|
i0.ɵɵelementEnd();
|
|
465
|
-
i0.ɵɵelementStart(30, "input",
|
|
484
|
+
i0.ɵɵelementStart(30, "input", 101);
|
|
466
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); });
|
|
467
486
|
i0.ɵɵelementEnd()();
|
|
468
|
-
i0.ɵɵelementStart(31, "div",
|
|
469
|
-
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);
|
|
470
489
|
i0.ɵɵelementEnd()()()()();
|
|
471
490
|
} if (rf & 2) {
|
|
472
491
|
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
@@ -483,25 +502,25 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
483
502
|
} }
|
|
484
503
|
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_57_Template(rf, ctx) { if (rf & 1) {
|
|
485
504
|
const _r17 = i0.ɵɵgetCurrentView();
|
|
486
|
-
i0.ɵɵelementStart(0, "div",
|
|
505
|
+
i0.ɵɵelementStart(0, "div", 64);
|
|
487
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()); });
|
|
488
|
-
i0.ɵɵelementStart(1, "div",
|
|
507
|
+
i0.ɵɵelementStart(1, "div", 103);
|
|
489
508
|
i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_57_Template_div_click_1_listener($event) { return $event.stopPropagation(); });
|
|
490
|
-
i0.ɵɵelementStart(2, "div",
|
|
491
|
-
i0.ɵɵelement(3, "i",
|
|
509
|
+
i0.ɵɵelementStart(2, "div", 104);
|
|
510
|
+
i0.ɵɵelement(3, "i", 105);
|
|
492
511
|
i0.ɵɵelementEnd();
|
|
493
|
-
i0.ɵɵelementStart(4, "h3",
|
|
512
|
+
i0.ɵɵelementStart(4, "h3", 106);
|
|
494
513
|
i0.ɵɵtext(5, "Vector Index Required");
|
|
495
514
|
i0.ɵɵelementEnd();
|
|
496
|
-
i0.ɵɵelementStart(6, "p",
|
|
515
|
+
i0.ɵɵelementStart(6, "p", 107);
|
|
497
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. ");
|
|
498
517
|
i0.ɵɵelementEnd();
|
|
499
|
-
i0.ɵɵelementStart(8, "div",
|
|
518
|
+
i0.ɵɵelementStart(8, "div", 108)(9, "button", 91);
|
|
500
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()); });
|
|
501
|
-
i0.ɵɵelement(10, "i",
|
|
520
|
+
i0.ɵɵelement(10, "i", 109);
|
|
502
521
|
i0.ɵɵtext(11, " Go to Configuration ");
|
|
503
522
|
i0.ɵɵelementEnd();
|
|
504
|
-
i0.ɵɵelementStart(12, "button",
|
|
523
|
+
i0.ɵɵelementStart(12, "button", 95);
|
|
505
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()); });
|
|
506
525
|
i0.ɵɵtext(13, " Close ");
|
|
507
526
|
i0.ɵɵelementEnd()()()();
|
|
@@ -582,15 +601,15 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
582
601
|
i0.ɵɵadvance(2);
|
|
583
602
|
i0.ɵɵconditional(ctx_r1.FilteredEntityGroups.length === 0 ? 8 : -1);
|
|
584
603
|
} }
|
|
585
|
-
function
|
|
586
|
-
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);
|
|
587
606
|
i0.ɵɵtext(1, " Generating with AI... ");
|
|
588
607
|
} }
|
|
589
|
-
function
|
|
608
|
+
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_9_Conditional_22_Template(rf, ctx) { if (rf & 1) {
|
|
590
609
|
i0.ɵɵelement(0, "i", 19);
|
|
591
610
|
i0.ɵɵtext(1, " Generate Template ");
|
|
592
611
|
} }
|
|
593
|
-
function
|
|
612
|
+
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_9_Conditional_23_Template(rf, ctx) { if (rf & 1) {
|
|
594
613
|
i0.ɵɵelementStart(0, "mj-alert", 121);
|
|
595
614
|
i0.ɵɵtext(1);
|
|
596
615
|
i0.ɵɵelementEnd();
|
|
@@ -601,39 +620,34 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
601
620
|
} }
|
|
602
621
|
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
603
622
|
const _r19 = i0.ɵɵgetCurrentView();
|
|
604
|
-
i0.ɵɵelementStart(0, "div",
|
|
623
|
+
i0.ɵɵelementStart(0, "div", 71)(1, "div", 72)(2, "label", 73);
|
|
605
624
|
i0.ɵɵtext(3, "Entity");
|
|
606
625
|
i0.ɵɵelementEnd();
|
|
607
|
-
i0.ɵɵelementStart(4, "div",
|
|
626
|
+
i0.ɵɵelementStart(4, "div", 112)(5, "button", 113);
|
|
608
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()); });
|
|
609
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);
|
|
610
|
-
i0.ɵɵelement(8, "i",
|
|
629
|
+
i0.ɵɵelement(8, "i", 114);
|
|
611
630
|
i0.ɵɵelementEnd();
|
|
612
|
-
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);
|
|
613
632
|
i0.ɵɵelementEnd()();
|
|
614
|
-
i0.ɵɵelementStart(10, "div",
|
|
633
|
+
i0.ɵɵelementStart(10, "div", 72)(11, "label", 73);
|
|
615
634
|
i0.ɵɵtext(12, "Use Case");
|
|
616
635
|
i0.ɵɵelementEnd();
|
|
617
|
-
i0.ɵɵelementStart(13, "div",
|
|
636
|
+
i0.ɵɵelementStart(13, "div", 116)(14, "button", 117);
|
|
618
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"); });
|
|
619
|
-
i0.ɵɵelement(15, "i",
|
|
638
|
+
i0.ɵɵelement(15, "i", 118);
|
|
620
639
|
i0.ɵɵtext(16, " Duplicate Detection ");
|
|
621
640
|
i0.ɵɵelementEnd();
|
|
622
|
-
i0.ɵɵelementStart(17, "button",
|
|
641
|
+
i0.ɵɵelementStart(17, "button", 117);
|
|
623
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"); });
|
|
624
|
-
i0.ɵɵelement(18, "i",
|
|
643
|
+
i0.ɵɵelement(18, "i", 119);
|
|
625
644
|
i0.ɵɵtext(19, " Search ");
|
|
626
|
-
i0.ɵɵelementEnd();
|
|
627
|
-
i0.ɵɵelementStart(20, "button", 116);
|
|
628
|
-
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"); });
|
|
629
|
-
i0.ɵɵelement(21, "i", 119);
|
|
630
|
-
i0.ɵɵtext(22, " Classification ");
|
|
631
645
|
i0.ɵɵelementEnd()()();
|
|
632
|
-
i0.ɵɵelementStart(
|
|
633
|
-
i0.ɵɵlistener("click", function
|
|
634
|
-
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);
|
|
635
649
|
i0.ɵɵelementEnd();
|
|
636
|
-
i0.ɵɵconditionalCreate(
|
|
650
|
+
i0.ɵɵconditionalCreate(23, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_9_Conditional_23_Template, 2, 1, "mj-alert", 121);
|
|
637
651
|
i0.ɵɵelementEnd();
|
|
638
652
|
} if (rf & 2) {
|
|
639
653
|
const ctx_r1 = i0.ɵɵnextContext(4);
|
|
@@ -646,16 +660,14 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
646
660
|
i0.ɵɵadvance(3);
|
|
647
661
|
i0.ɵɵclassProp("use-case-btn-active", ctx_r1.SuggestUseCase === "search");
|
|
648
662
|
i0.ɵɵadvance(3);
|
|
649
|
-
i0.ɵɵclassProp("use-case-btn-active", ctx_r1.SuggestUseCase === "classification");
|
|
650
|
-
i0.ɵɵadvance(3);
|
|
651
663
|
i0.ɵɵproperty("disabled", ctx_r1.IsSuggesting || !ctx_r1.SuggestEntityName);
|
|
652
664
|
i0.ɵɵadvance();
|
|
653
|
-
i0.ɵɵconditional(ctx_r1.IsSuggesting ?
|
|
665
|
+
i0.ɵɵconditional(ctx_r1.IsSuggesting ? 21 : 22);
|
|
654
666
|
i0.ɵɵadvance(2);
|
|
655
|
-
i0.ɵɵconditional(ctx_r1.SuggestionError ?
|
|
667
|
+
i0.ɵɵconditional(ctx_r1.SuggestionError ? 23 : -1);
|
|
656
668
|
} }
|
|
657
669
|
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_For_11_Template(rf, ctx) { if (rf & 1) {
|
|
658
|
-
i0.ɵɵelementStart(0, "span",
|
|
670
|
+
i0.ɵɵelementStart(0, "span", 89);
|
|
659
671
|
i0.ɵɵtext(1);
|
|
660
672
|
i0.ɵɵelementEnd();
|
|
661
673
|
} if (rf & 2) {
|
|
@@ -689,7 +701,7 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
689
701
|
i0.ɵɵrepeater(ctx_r1.SuggestionResult.selectedRelationships);
|
|
690
702
|
} }
|
|
691
703
|
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_For_39_Template(rf, ctx) { if (rf & 1) {
|
|
692
|
-
i0.ɵɵelementStart(0, "option",
|
|
704
|
+
i0.ɵɵelementStart(0, "option", 81);
|
|
693
705
|
i0.ɵɵtext(1);
|
|
694
706
|
i0.ɵɵelementEnd();
|
|
695
707
|
} if (rf & 2) {
|
|
@@ -699,7 +711,7 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
699
711
|
i0.ɵɵtextInterpolate(model_r27.Name);
|
|
700
712
|
} }
|
|
701
713
|
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_For_45_Template(rf, ctx) { if (rf & 1) {
|
|
702
|
-
i0.ɵɵelementStart(0, "option",
|
|
714
|
+
i0.ɵɵelementStart(0, "option", 81);
|
|
703
715
|
i0.ɵɵtext(1);
|
|
704
716
|
i0.ɵɵelementEnd();
|
|
705
717
|
} if (rf & 2) {
|
|
@@ -709,7 +721,7 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
709
721
|
i0.ɵɵtextInterpolate(db_r28.Name);
|
|
710
722
|
} }
|
|
711
723
|
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Conditional_49_For_4_Template(rf, ctx) { if (rf & 1) {
|
|
712
|
-
i0.ɵɵelementStart(0, "option",
|
|
724
|
+
i0.ɵɵelementStart(0, "option", 81);
|
|
713
725
|
i0.ɵɵtext(1);
|
|
714
726
|
i0.ɵɵelementEnd();
|
|
715
727
|
} if (rf & 2) {
|
|
@@ -720,12 +732,12 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
720
732
|
} }
|
|
721
733
|
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Conditional_49_Template(rf, ctx) { if (rf & 1) {
|
|
722
734
|
const _r29 = i0.ɵɵgetCurrentView();
|
|
723
|
-
i0.ɵɵelementStart(0, "select",
|
|
735
|
+
i0.ɵɵelementStart(0, "select", 80);
|
|
724
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); });
|
|
725
|
-
i0.ɵɵelementStart(1, "option",
|
|
737
|
+
i0.ɵɵelementStart(1, "option", 90);
|
|
726
738
|
i0.ɵɵtext(2, "Auto (create/find matching index)");
|
|
727
739
|
i0.ɵɵelementEnd();
|
|
728
|
-
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);
|
|
729
741
|
i0.ɵɵelementEnd();
|
|
730
742
|
} if (rf & 2) {
|
|
731
743
|
const ctx_r1 = i0.ɵɵnextContext(5);
|
|
@@ -734,18 +746,18 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
734
746
|
i0.ɵɵrepeater(ctx_r1.FilteredIndexesForSelectedDB);
|
|
735
747
|
} }
|
|
736
748
|
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Conditional_50_Template(rf, ctx) { if (rf & 1) {
|
|
737
|
-
i0.ɵɵelementStart(0, "span",
|
|
749
|
+
i0.ɵɵelementStart(0, "span", 83);
|
|
738
750
|
i0.ɵɵtext(1, " No indexes yet \u2014 create one in Configuration > Vector Database, or one will be created on sync ");
|
|
739
751
|
i0.ɵɵelementEnd();
|
|
740
752
|
} }
|
|
741
753
|
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Conditional_52_Template(rf, ctx) { if (rf & 1) {
|
|
742
754
|
i0.ɵɵelementStart(0, "div", 145);
|
|
743
|
-
i0.ɵɵelement(1, "mj-loading",
|
|
755
|
+
i0.ɵɵelement(1, "mj-loading", 87);
|
|
744
756
|
i0.ɵɵelementEnd();
|
|
745
757
|
} }
|
|
746
758
|
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Conditional_53_Template(rf, ctx) { if (rf & 1) {
|
|
747
759
|
const _r31 = i0.ɵɵgetCurrentView();
|
|
748
|
-
i0.ɵɵelementStart(0, "button",
|
|
760
|
+
i0.ɵɵelementStart(0, "button", 91);
|
|
749
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()); });
|
|
750
762
|
i0.ɵɵelement(1, "i", 149);
|
|
751
763
|
i0.ɵɵtext(2, " Save as Entity Document ");
|
|
@@ -755,24 +767,24 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
755
767
|
i0.ɵɵelement(4, "i", 151);
|
|
756
768
|
i0.ɵɵtext(5, " Try Again ");
|
|
757
769
|
i0.ɵɵelementEnd();
|
|
758
|
-
i0.ɵɵelementStart(6, "button",
|
|
770
|
+
i0.ɵɵelementStart(6, "button", 95);
|
|
759
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()); });
|
|
760
772
|
i0.ɵɵtext(7, " Close ");
|
|
761
773
|
i0.ɵɵelementEnd();
|
|
762
774
|
} }
|
|
763
775
|
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
764
776
|
const _r24 = i0.ɵɵgetCurrentView();
|
|
765
|
-
i0.ɵɵelementStart(0, "div",
|
|
777
|
+
i0.ɵɵelementStart(0, "div", 111)(1, "div", 136)(2, "h4", 137);
|
|
766
778
|
i0.ɵɵtext(3, "Suggested Template");
|
|
767
779
|
i0.ɵɵelementEnd();
|
|
768
|
-
i0.ɵɵelementStart(4, "div",
|
|
780
|
+
i0.ɵɵelementStart(4, "div", 77)(5, "mj-code-editor", 78);
|
|
769
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)); });
|
|
770
782
|
i0.ɵɵelementEnd()()();
|
|
771
783
|
i0.ɵɵelementStart(6, "div", 136)(7, "h4", 137);
|
|
772
784
|
i0.ɵɵtext(8, "Selected Fields");
|
|
773
785
|
i0.ɵɵelementEnd();
|
|
774
|
-
i0.ɵɵelementStart(9, "div",
|
|
775
|
-
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);
|
|
776
788
|
i0.ɵɵelementEnd()();
|
|
777
789
|
i0.ɵɵconditionalCreate(12, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Conditional_12_Template, 5, 0, "div", 136);
|
|
778
790
|
i0.ɵɵelementStart(13, "div", 138)(14, "div", 139)(15, "span", 140);
|
|
@@ -793,30 +805,30 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
793
805
|
i0.ɵɵelementStart(27, "p", 142);
|
|
794
806
|
i0.ɵɵtext(28);
|
|
795
807
|
i0.ɵɵelementEnd()();
|
|
796
|
-
i0.ɵɵelementStart(29, "div", 136)(30, "div",
|
|
808
|
+
i0.ɵɵelementStart(29, "div", 136)(30, "div", 72)(31, "label", 73);
|
|
797
809
|
i0.ɵɵtext(32, "Document Name");
|
|
798
810
|
i0.ɵɵelementEnd();
|
|
799
|
-
i0.ɵɵelementStart(33, "input",
|
|
811
|
+
i0.ɵɵelementStart(33, "input", 79);
|
|
800
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); });
|
|
801
813
|
i0.ɵɵelementEnd()();
|
|
802
|
-
i0.ɵɵelementStart(34, "div", 143)(35, "label",
|
|
814
|
+
i0.ɵɵelementStart(34, "div", 143)(35, "label", 73);
|
|
803
815
|
i0.ɵɵtext(36, "Embedding Model");
|
|
804
816
|
i0.ɵɵelementEnd();
|
|
805
|
-
i0.ɵɵelementStart(37, "select",
|
|
817
|
+
i0.ɵɵelementStart(37, "select", 80);
|
|
806
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); });
|
|
807
|
-
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);
|
|
808
820
|
i0.ɵɵelementEnd()();
|
|
809
|
-
i0.ɵɵelementStart(40, "div", 143)(41, "label",
|
|
821
|
+
i0.ɵɵelementStart(40, "div", 143)(41, "label", 73);
|
|
810
822
|
i0.ɵɵtext(42, "Vector Database");
|
|
811
823
|
i0.ɵɵelementEnd();
|
|
812
|
-
i0.ɵɵelementStart(43, "select",
|
|
824
|
+
i0.ɵɵelementStart(43, "select", 80);
|
|
813
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); });
|
|
814
|
-
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);
|
|
815
827
|
i0.ɵɵelementEnd()();
|
|
816
|
-
i0.ɵɵelementStart(46, "div", 143)(47, "label",
|
|
828
|
+
i0.ɵɵelementStart(46, "div", 143)(47, "label", 73);
|
|
817
829
|
i0.ɵɵtext(48, "Vector Index");
|
|
818
830
|
i0.ɵɵelementEnd();
|
|
819
|
-
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);
|
|
820
832
|
i0.ɵɵelementEnd()();
|
|
821
833
|
i0.ɵɵelementStart(51, "div", 144);
|
|
822
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);
|
|
@@ -852,20 +864,20 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
|
|
|
852
864
|
} }
|
|
853
865
|
function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Template(rf, ctx) { if (rf & 1) {
|
|
854
866
|
const _r18 = i0.ɵɵgetCurrentView();
|
|
855
|
-
i0.ɵɵelementStart(0, "div",
|
|
867
|
+
i0.ɵɵelementStart(0, "div", 64);
|
|
856
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()); });
|
|
857
|
-
i0.ɵɵelementStart(1, "div",
|
|
869
|
+
i0.ɵɵelementStart(1, "div", 110);
|
|
858
870
|
i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Template_div_click_1_listener($event) { return $event.stopPropagation(); });
|
|
859
|
-
i0.ɵɵelementStart(2, "div",
|
|
871
|
+
i0.ɵɵelementStart(2, "div", 66)(3, "h3", 67);
|
|
860
872
|
i0.ɵɵelement(4, "i", 19);
|
|
861
873
|
i0.ɵɵtext(5, " AI Document Suggestion ");
|
|
862
874
|
i0.ɵɵelementEnd();
|
|
863
|
-
i0.ɵɵelementStart(6, "button",
|
|
875
|
+
i0.ɵɵelementStart(6, "button", 68);
|
|
864
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()); });
|
|
865
|
-
i0.ɵɵelement(7, "i",
|
|
877
|
+
i0.ɵɵelement(7, "i", 69);
|
|
866
878
|
i0.ɵɵelementEnd()();
|
|
867
|
-
i0.ɵɵelementStart(8, "div",
|
|
868
|
-
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);
|
|
869
881
|
i0.ɵɵelementEnd()()();
|
|
870
882
|
} if (rf & 2) {
|
|
871
883
|
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
@@ -894,7 +906,7 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Template(
|
|
|
894
906
|
i0.ɵɵelement(16, "i", 22);
|
|
895
907
|
i0.ɵɵtext(17, " Refresh ");
|
|
896
908
|
i0.ɵɵelementEnd()()();
|
|
897
|
-
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);
|
|
898
910
|
i0.ɵɵelementEnd();
|
|
899
911
|
i0.ɵɵelementStart(20, "div", 25)(21, "div", 26)(22, "h4", 27);
|
|
900
912
|
i0.ɵɵelement(23, "i", 28);
|
|
@@ -936,7 +948,7 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Template(
|
|
|
936
948
|
i0.ɵɵtext(53);
|
|
937
949
|
i0.ɵɵpipe(54, "number");
|
|
938
950
|
i0.ɵɵelementEnd()()()()();
|
|
939
|
-
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);
|
|
940
952
|
i0.ɵɵconditionalCreate(56, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_56_Template, 34, 5, "div", 45);
|
|
941
953
|
i0.ɵɵconditionalCreate(57, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_57_Template, 14, 0, "div", 45);
|
|
942
954
|
i0.ɵɵconditionalCreate(58, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Template, 11, 3, "div", 45);
|
|
@@ -1032,6 +1044,8 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
|
|
|
1032
1044
|
EditDocVectorIndexID = '';
|
|
1033
1045
|
EditDocStatus = '';
|
|
1034
1046
|
EditDocTemplate = '';
|
|
1047
|
+
/** Entity Document Type of the document being edited. Fixed at creation, shown read-only. */
|
|
1048
|
+
EditDocType = '';
|
|
1035
1049
|
IsEditRegenerating = false;
|
|
1036
1050
|
/** Parse {{ FieldName }} patterns from the edit panel's template */
|
|
1037
1051
|
get EditDocSelectedFields() {
|
|
@@ -1056,6 +1070,7 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
|
|
|
1056
1070
|
this.EditDocAIModelID = doc.AIModelID ?? '';
|
|
1057
1071
|
this.EditDocVectorIndexID = doc.VectorIndexID || '';
|
|
1058
1072
|
this.EditDocStatus = doc.Status;
|
|
1073
|
+
this.EditDocType = doc.Type || '';
|
|
1059
1074
|
this.EditDocTemplate = '';
|
|
1060
1075
|
this.IsEditRegenerating = false;
|
|
1061
1076
|
this.ShowEditPanel = true;
|
|
@@ -1100,9 +1115,17 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
|
|
|
1100
1115
|
if (!loaded)
|
|
1101
1116
|
throw new Error('Could not load entity document');
|
|
1102
1117
|
doc.Name = this.EditDocName;
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
doc.
|
|
1118
|
+
const vectorDatabaseID = this.EditDocVectorDBID || null;
|
|
1119
|
+
const aiModelID = this.EditDocAIModelID || null;
|
|
1120
|
+
doc.VectorDatabaseID = vectorDatabaseID;
|
|
1121
|
+
doc.AIModelID = aiModelID;
|
|
1122
|
+
// "Auto (create/find matching index)" resolves to a real index for this DB + model, so the
|
|
1123
|
+
// syncer always has one to write into; without both parts there is nothing to match.
|
|
1124
|
+
doc.VectorIndexID = this.EditDocVectorIndexID
|
|
1125
|
+
? this.EditDocVectorIndexID
|
|
1126
|
+
: (vectorDatabaseID && aiModelID
|
|
1127
|
+
? await this.resolveOrCreateVectorIndex(vectorDatabaseID, aiModelID, this.EditDocEntityName)
|
|
1128
|
+
: null);
|
|
1106
1129
|
doc.Status = this.EditDocStatus;
|
|
1107
1130
|
const saved = await doc.Save();
|
|
1108
1131
|
if (saved) {
|
|
@@ -1153,10 +1176,17 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
|
|
|
1153
1176
|
async RegenerateTemplate() {
|
|
1154
1177
|
if (!this.EditDocEntityName || this.IsEditRegenerating)
|
|
1155
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
|
+
}
|
|
1156
1186
|
this.IsEditRegenerating = true;
|
|
1157
1187
|
this.cdr.detectChanges();
|
|
1158
1188
|
try {
|
|
1159
|
-
const result = await this.callSuggestionPrompt(this.EditDocEntityName,
|
|
1189
|
+
const result = await this.callSuggestionPrompt(this.EditDocEntityName, useCase);
|
|
1160
1190
|
if (result) {
|
|
1161
1191
|
this.EditDocTemplate = result.template;
|
|
1162
1192
|
MJNotificationService.Instance.CreateSimpleNotification('Template regenerated with AI. Review and save to apply.', 'info', 3000);
|
|
@@ -1887,6 +1917,15 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
|
|
|
1887
1917
|
try {
|
|
1888
1918
|
const result = await this.callSuggestionPrompt(this.SuggestEntityName, this.SuggestUseCase);
|
|
1889
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;
|
|
1890
1929
|
this.SuggestionResult = result;
|
|
1891
1930
|
this.EditableTemplate = result.template;
|
|
1892
1931
|
this.SaveDocumentName = `${this.SuggestEntityName} - ${this.SuggestUseCase}`;
|
|
@@ -1911,8 +1950,7 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
|
|
|
1911
1950
|
this.cdr.detectChanges();
|
|
1912
1951
|
try {
|
|
1913
1952
|
const md = this.ProviderToUse;
|
|
1914
|
-
const entityDoc = await
|
|
1915
|
-
entityDoc.NewRecord();
|
|
1953
|
+
const entityDoc = await this.findOrCreateEntityDocument();
|
|
1916
1954
|
entityDoc.Name = this.SaveDocumentName;
|
|
1917
1955
|
const matchingEntity = md.Entities.find(e => e.Name === this.SuggestEntityName);
|
|
1918
1956
|
if (matchingEntity) {
|
|
@@ -2007,7 +2045,9 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
|
|
|
2007
2045
|
}
|
|
2008
2046
|
this.entityDocuments = engine.EntityDocuments;
|
|
2009
2047
|
this.vectorDatabases = AIEngineBase.Instance.VectorDatabases;
|
|
2010
|
-
|
|
2048
|
+
// A copy: resolveOrCreateVectorIndex() appends the index it creates, and the engine's getter
|
|
2049
|
+
// hands out its own cached array, which this component must not mutate.
|
|
2050
|
+
this.vectorIndexes = [...AIEngineBase.Instance.VectorIndexes];
|
|
2011
2051
|
// Build per-EntityDocument aggregate stats (vector count + last synced).
|
|
2012
2052
|
// Each query fetches only the most recent row (MaxRows: 1) and uses
|
|
2013
2053
|
// TotalRowCount for the actual vector count — avoids loading all rows.
|
|
@@ -2058,6 +2098,7 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
|
|
|
2058
2098
|
EntityDocumentID: doc.ID,
|
|
2059
2099
|
EntityName: doc.Entity || '',
|
|
2060
2100
|
DocumentName: doc.Name,
|
|
2101
|
+
DocumentType: doc.Type || '',
|
|
2061
2102
|
VectorCount: vectorCount,
|
|
2062
2103
|
LastSynced: lastSynced,
|
|
2063
2104
|
Status: status,
|
|
@@ -2210,41 +2251,95 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
|
|
|
2210
2251
|
missing.push('Embedding Model');
|
|
2211
2252
|
throw new Error(`Prerequisites not configured: ${missing.join(', ')}. Go to the Configuration tab to set these up.`);
|
|
2212
2253
|
}
|
|
2213
|
-
// 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
|
+
}
|
|
2214
2265
|
const rv = RunView.FromMetadataProvider(this.ProviderToUse);
|
|
2215
2266
|
const typeResult = await rv.RunView({
|
|
2216
2267
|
EntityName: 'MJ: Entity Document Types',
|
|
2217
|
-
ExtraFilter: "Name = 'Record Duplicate'",
|
|
2218
2268
|
ResultType: 'simple',
|
|
2219
|
-
Fields: ['ID']
|
|
2269
|
+
Fields: ['ID', 'Name']
|
|
2220
2270
|
});
|
|
2221
|
-
|
|
2222
|
-
|
|
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;
|
|
2223
2278
|
}
|
|
2224
2279
|
else {
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
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.'));
|
|
2287
|
+
}
|
|
2288
|
+
// An explicitly chosen index fixes the DB + model. "Auto (create/find matching index)" resolves
|
|
2289
|
+
// (or creates) the index for the chosen DB + model, so the syncer always has a VectorIndexID:
|
|
2290
|
+
// it refuses to run without one, which made the Auto choice a dead end before.
|
|
2291
|
+
const chosen = this.SelectedVectorIndexID
|
|
2292
|
+
? this.AvailableVectorIndexes.find(i => UUIDsEqual(i.ID, this.SelectedVectorIndexID))
|
|
2293
|
+
: undefined;
|
|
2294
|
+
if (chosen) {
|
|
2295
|
+
entityDoc.VectorDatabaseID = chosen.VectorDatabaseID;
|
|
2296
|
+
entityDoc.AIModelID = chosen.EmbeddingModelID;
|
|
2297
|
+
entityDoc.VectorIndexID = chosen.ID;
|
|
2240
2298
|
}
|
|
2241
2299
|
else {
|
|
2242
|
-
|
|
2243
|
-
|
|
2300
|
+
const vectorDatabaseID = this.SelectedVectorDBID || this.vectorDatabases[0].ID;
|
|
2301
|
+
const aiModelID = this.SelectedEmbeddingModelID || this.findEmbeddingModel().ID;
|
|
2302
|
+
entityDoc.VectorDatabaseID = vectorDatabaseID;
|
|
2303
|
+
entityDoc.AIModelID = aiModelID;
|
|
2304
|
+
entityDoc.VectorIndexID = await this.resolveOrCreateVectorIndex(vectorDatabaseID, aiModelID, this.SuggestEntityName);
|
|
2244
2305
|
}
|
|
2245
2306
|
// TemplateID — create a Template record with the generated template content
|
|
2246
2307
|
await this.createTemplateForDocument(entityDoc);
|
|
2247
2308
|
}
|
|
2309
|
+
/**
|
|
2310
|
+
* "Auto (create/find matching index)": reuse the index already built for this vector database +
|
|
2311
|
+
* embedding model, or create the `MJ: Vector Indexes` record for one. Only the metadata row is
|
|
2312
|
+
* written here and the save returns as soon as it is stored; the server-side entity hook then
|
|
2313
|
+
* provisions the index in the provider (bounded by its own timeout) and writes the provider
|
|
2314
|
+
* metadata back, so this request is never held while the provider works.
|
|
2315
|
+
* Returns the index ID to store on the document.
|
|
2316
|
+
*/
|
|
2317
|
+
async resolveOrCreateVectorIndex(vectorDatabaseID, aiModelID, entityName) {
|
|
2318
|
+
const existing = FindMatchingVectorIndex(this.vectorIndexes, vectorDatabaseID, aiModelID);
|
|
2319
|
+
if (existing) {
|
|
2320
|
+
return existing.ID;
|
|
2321
|
+
}
|
|
2322
|
+
const md = this.ProviderToUse;
|
|
2323
|
+
const modelName = this.aiModels.find(m => UUIDsEqual(m.ID, aiModelID))?.Name ?? null;
|
|
2324
|
+
const index = await md.GetEntityObject('MJ: Vector Indexes');
|
|
2325
|
+
index.NewRecord();
|
|
2326
|
+
index.Name = BuildAutoVectorIndexName(entityName, modelName);
|
|
2327
|
+
index.VectorDatabaseID = vectorDatabaseID;
|
|
2328
|
+
index.EmbeddingModelID = aiModelID;
|
|
2329
|
+
index.Description = `Auto-created for the "${entityName}" entity document (${modelName ?? 'embedding model'})`;
|
|
2330
|
+
const saved = await index.Save();
|
|
2331
|
+
if (!saved) {
|
|
2332
|
+
throw new Error(`Could not create a vector index for "${entityName}": ${index.LatestResult?.CompleteMessage || 'unknown error'}`);
|
|
2333
|
+
}
|
|
2334
|
+
this.vectorIndexes.push(index);
|
|
2335
|
+
this.AvailableVectorIndexes.push({
|
|
2336
|
+
ID: index.ID,
|
|
2337
|
+
Name: index.Name,
|
|
2338
|
+
VectorDatabaseID: index.VectorDatabaseID,
|
|
2339
|
+
EmbeddingModelID: index.EmbeddingModelID,
|
|
2340
|
+
});
|
|
2341
|
+
return index.ID;
|
|
2342
|
+
}
|
|
2248
2343
|
/** Create a Template + TemplateContent record for the entity document */
|
|
2249
2344
|
async createTemplateForDocument(entityDoc) {
|
|
2250
2345
|
const md = this.ProviderToUse;
|
|
@@ -2252,12 +2347,33 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
|
|
|
2252
2347
|
if (!templateText) {
|
|
2253
2348
|
throw new Error('No template content to save');
|
|
2254
2349
|
}
|
|
2255
|
-
//
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
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;
|
|
2259
2372
|
template.Description = `Auto-generated template for entity document: ${this.SaveDocumentName}`;
|
|
2260
|
-
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
|
+
}
|
|
2261
2377
|
template.IsActive = true;
|
|
2262
2378
|
const templateSaved = await template.Save();
|
|
2263
2379
|
if (!templateSaved) {
|
|
@@ -2277,8 +2393,7 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
|
|
|
2277
2393
|
// Create TemplateContent record with the template text
|
|
2278
2394
|
// Server-side MJTemplateContentEntityServer hook auto-creates Scalar params
|
|
2279
2395
|
// for each {{FieldName}} — GetTemplateData() handles them via the flat convention.
|
|
2280
|
-
const content = await
|
|
2281
|
-
content.NewRecord();
|
|
2396
|
+
const content = await this.findOrCreateTemplateContent(template.ID);
|
|
2282
2397
|
content.TemplateID = template.ID;
|
|
2283
2398
|
content.TypeID = contentTypeResult.Results[0].ID;
|
|
2284
2399
|
content.TemplateText = templateText;
|
|
@@ -2289,11 +2404,136 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
|
|
|
2289
2404
|
throw new Error(`Failed to create template content: ${content.LatestResult?.CompleteMessage || 'unknown error'}`);
|
|
2290
2405
|
}
|
|
2291
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
|
+
}
|
|
2292
2526
|
/** Build grouped entity list from metadata, grouped by SchemaName */
|
|
2293
2527
|
loadEntityGroups() {
|
|
2294
2528
|
const md = this.ProviderToUse;
|
|
2295
2529
|
const groupMap = new Map();
|
|
2296
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
|
+
}
|
|
2297
2537
|
const schema = entity.SchemaName || '__default';
|
|
2298
2538
|
const existing = groupMap.get(schema);
|
|
2299
2539
|
if (existing) {
|
|
@@ -2408,7 +2648,9 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
|
|
|
2408
2648
|
}
|
|
2409
2649
|
/** Build the data payload for the suggestion prompt */
|
|
2410
2650
|
buildPromptData(entity, useCase) {
|
|
2411
|
-
|
|
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 => ({
|
|
2412
2654
|
Name: f.Name,
|
|
2413
2655
|
Type: f.Type,
|
|
2414
2656
|
IsPrimaryKey: f.IsPrimaryKey,
|
|
@@ -2423,8 +2665,9 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
|
|
|
2423
2665
|
.slice(0, 20)
|
|
2424
2666
|
.map(r => {
|
|
2425
2667
|
const relatedEntity = md.Entities.find(e => e.Name === r.RelatedEntity);
|
|
2668
|
+
// Layer 1 covers related entities too: their fields reach the model here.
|
|
2426
2669
|
const relFields = relatedEntity
|
|
2427
|
-
? relatedEntity.Fields
|
|
2670
|
+
? WithoutSensitiveFields(relatedEntity.Fields)
|
|
2428
2671
|
.filter(f => !f.IsPrimaryKey && f.Type !== 'datetimeoffset')
|
|
2429
2672
|
.map(f => f.Name)
|
|
2430
2673
|
: [];
|
|
@@ -2448,7 +2691,7 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
|
|
|
2448
2691
|
} if (rf & 2) {
|
|
2449
2692
|
let _t;
|
|
2450
2693
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.EntitySearchInput = _t.first);
|
|
2451
|
-
} }, 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) {
|
|
2452
2695
|
i0.ɵɵconditionalCreate(0, VectorManagementResourceComponent_Conditional_0_Template, 6, 4, "mj-page-layout");
|
|
2453
2696
|
i0.ɵɵconditionalCreate(1, VectorManagementResourceComponent_Conditional_1_Template, 1, 1, "ng-container");
|
|
2454
2697
|
i0.ɵɵtemplate(2, VectorManagementResourceComponent_ng_template_2_Template, 2, 1, "ng-template", null, 0, i0.ɵɵtemplateRefExtractor);
|
|
@@ -2456,7 +2699,7 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
|
|
|
2456
2699
|
i0.ɵɵconditional(!ctx.HideToolbar ? 0 : -1);
|
|
2457
2700
|
i0.ɵɵadvance();
|
|
2458
2701
|
i0.ɵɵconditional(ctx.HideToolbar ? 1 : -1);
|
|
2459
|
-
} }, 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}"] });
|
|
2460
2703
|
};
|
|
2461
2704
|
VectorManagementResourceComponent = __decorate([
|
|
2462
2705
|
RegisterClass(BaseResourceComponent, 'VectorManagementResource')
|
|
@@ -2464,14 +2707,14 @@ VectorManagementResourceComponent = __decorate([
|
|
|
2464
2707
|
export { VectorManagementResourceComponent };
|
|
2465
2708
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(VectorManagementResourceComponent, [{
|
|
2466
2709
|
type: Component,
|
|
2467
|
-
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"] }]
|
|
2468
2711
|
}], null, { HideToolbar: [{
|
|
2469
2712
|
type: Input
|
|
2470
2713
|
}], EntitySearchInput: [{
|
|
2471
2714
|
type: ViewChild,
|
|
2472
2715
|
args: ['entitySearchInput']
|
|
2473
2716
|
}] }); })();
|
|
2474
|
-
(() => { (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 }); })();
|
|
2475
2718
|
export function LoadVectorManagementResource() {
|
|
2476
2719
|
// Prevents tree-shaking
|
|
2477
2720
|
}
|