@memberjunction/ng-dashboards 6.2.0-edge.4 → 6.2.0-edge.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (205) hide show
  1. package/README.md +28 -0
  2. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts +1 -1
  3. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts.map +1 -1
  4. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js +15 -7
  5. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js.map +1 -1
  6. package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts +7 -1
  7. package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts.map +1 -1
  8. package/dist/AI/components/duplicates/duplicate-detection-resource.component.js +209 -57
  9. package/dist/AI/components/duplicates/duplicate-detection-resource.component.js.map +1 -1
  10. package/dist/AI/components/duplicates/duplicate-detection-run-scope.d.ts +12 -11
  11. package/dist/AI/components/duplicates/duplicate-detection-run-scope.d.ts.map +1 -1
  12. package/dist/AI/components/duplicates/duplicate-detection-run-scope.js +15 -15
  13. package/dist/AI/components/duplicates/duplicate-detection-run-scope.js.map +1 -1
  14. package/dist/AI/components/execution-monitoring.component.d.ts.map +1 -1
  15. package/dist/AI/components/execution-monitoring.component.js +28 -16
  16. package/dist/AI/components/execution-monitoring.component.js.map +1 -1
  17. package/dist/AI/components/prompts/model-prompt-priority-matrix.component.d.ts +1 -0
  18. package/dist/AI/components/prompts/model-prompt-priority-matrix.component.d.ts.map +1 -1
  19. package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js +30 -6
  20. package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js.map +1 -1
  21. package/dist/AI/components/tags/tags-resource.component.d.ts +1 -1
  22. package/dist/AI/components/tags/tags-resource.component.d.ts.map +1 -1
  23. package/dist/AI/components/tags/tags-resource.component.js +15 -7
  24. package/dist/AI/components/tags/tags-resource.component.js.map +1 -1
  25. package/dist/AI/components/vectors/sensitive-fields.d.ts +58 -0
  26. package/dist/AI/components/vectors/sensitive-fields.d.ts.map +1 -0
  27. package/dist/AI/components/vectors/sensitive-fields.js +251 -0
  28. package/dist/AI/components/vectors/sensitive-fields.js.map +1 -0
  29. package/dist/AI/components/vectors/vector-document-rules.d.ts +139 -0
  30. package/dist/AI/components/vectors/vector-document-rules.d.ts.map +1 -0
  31. package/dist/AI/components/vectors/vector-document-rules.js +182 -0
  32. package/dist/AI/components/vectors/vector-document-rules.js.map +1 -0
  33. package/dist/AI/components/vectors/vector-management-resource.component.d.ts +83 -14
  34. package/dist/AI/components/vectors/vector-management-resource.component.d.ts.map +1 -1
  35. package/dist/AI/components/vectors/vector-management-resource.component.js +546 -271
  36. package/dist/AI/components/vectors/vector-management-resource.component.js.map +1 -1
  37. package/dist/AI/components/vectors/vector-store-selection.d.ts +32 -0
  38. package/dist/AI/components/vectors/vector-store-selection.d.ts.map +1 -0
  39. package/dist/AI/components/vectors/vector-store-selection.js +57 -0
  40. package/dist/AI/components/vectors/vector-store-selection.js.map +1 -0
  41. package/dist/ChiefOfStaff/chief-of-staff-agent-context.d.ts +236 -0
  42. package/dist/ChiefOfStaff/chief-of-staff-agent-context.d.ts.map +1 -0
  43. package/dist/ChiefOfStaff/chief-of-staff-agent-context.js +374 -0
  44. package/dist/ChiefOfStaff/chief-of-staff-agent-context.js.map +1 -0
  45. package/dist/ChiefOfStaff/chief-of-staff-dashboard.component.d.ts +195 -0
  46. package/dist/ChiefOfStaff/chief-of-staff-dashboard.component.d.ts.map +1 -0
  47. package/dist/ChiefOfStaff/chief-of-staff-dashboard.component.js +2910 -0
  48. package/dist/ChiefOfStaff/chief-of-staff-dashboard.component.js.map +1 -0
  49. package/dist/ChiefOfStaff/index.d.ts +3 -0
  50. package/dist/ChiefOfStaff/index.d.ts.map +1 -0
  51. package/dist/ChiefOfStaff/index.js +3 -0
  52. package/dist/ChiefOfStaff/index.js.map +1 -0
  53. package/dist/Communication/communication-agent-context.d.ts +11 -1
  54. package/dist/Communication/communication-agent-context.d.ts.map +1 -1
  55. package/dist/Communication/communication-agent-context.js +15 -0
  56. package/dist/Communication/communication-agent-context.js.map +1 -1
  57. package/dist/Communication/communication-dashboard.component.d.ts.map +1 -1
  58. package/dist/Communication/communication-dashboard.component.js +5 -0
  59. package/dist/Communication/communication-dashboard.component.js.map +1 -1
  60. package/dist/Communication/communication-logs-resource.component.d.ts.map +1 -1
  61. package/dist/Communication/communication-logs-resource.component.js +2 -1
  62. package/dist/Communication/communication-logs-resource.component.js.map +1 -1
  63. package/dist/Communication/communication-monitor-resource.component.d.ts.map +1 -1
  64. package/dist/Communication/communication-monitor-resource.component.js +23 -18
  65. package/dist/Communication/communication-monitor-resource.component.js.map +1 -1
  66. package/dist/Communication/communication-providers-resource.component.d.ts +27 -1
  67. package/dist/Communication/communication-providers-resource.component.d.ts.map +1 -1
  68. package/dist/Communication/communication-providers-resource.component.js +722 -78
  69. package/dist/Communication/communication-providers-resource.component.js.map +1 -1
  70. package/dist/Communication/communication-runs-resource.component.d.ts.map +1 -1
  71. package/dist/Communication/communication-runs-resource.component.js +11 -10
  72. package/dist/Communication/communication-runs-resource.component.js.map +1 -1
  73. package/dist/DashboardEditor/dashboard-editor.component.d.ts +17 -2
  74. package/dist/DashboardEditor/dashboard-editor.component.d.ts.map +1 -1
  75. package/dist/DashboardEditor/dashboard-editor.component.js +94 -43
  76. package/dist/DashboardEditor/dashboard-editor.component.js.map +1 -1
  77. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +49 -0
  78. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
  79. package/dist/DataExplorer/data-explorer-dashboard.component.js +220 -55
  80. package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
  81. package/dist/DataExplorer/models/explorer-state.interface.d.ts +2 -0
  82. package/dist/DataExplorer/models/explorer-state.interface.d.ts.map +1 -1
  83. package/dist/DataExplorer/models/explorer-state.interface.js.map +1 -1
  84. package/dist/DevTools/app-state-inspector.component.d.ts.map +1 -1
  85. package/dist/DevTools/app-state-inspector.component.js +1 -0
  86. package/dist/DevTools/app-state-inspector.component.js.map +1 -1
  87. package/dist/DevTools/class-registry.component.d.ts.map +1 -1
  88. package/dist/DevTools/class-registry.component.js +1 -0
  89. package/dist/DevTools/class-registry.component.js.map +1 -1
  90. package/dist/DevTools/event-monitor.component.d.ts.map +1 -1
  91. package/dist/DevTools/event-monitor.component.js +2 -0
  92. package/dist/DevTools/event-monitor.component.js.map +1 -1
  93. package/dist/DevTools/graphql-console.component.d.ts.map +1 -1
  94. package/dist/DevTools/graphql-console.component.js.map +1 -1
  95. package/dist/DevTools/grid-width-lab.component.d.ts.map +1 -1
  96. package/dist/DevTools/grid-width-lab.component.js +1 -0
  97. package/dist/DevTools/grid-width-lab.component.js.map +1 -1
  98. package/dist/DevTools/layout-inspector.component.d.ts.map +1 -1
  99. package/dist/DevTools/layout-inspector.component.js +1 -0
  100. package/dist/DevTools/layout-inspector.component.js.map +1 -1
  101. package/dist/DevTools/lazy-module-status.component.d.ts.map +1 -1
  102. package/dist/DevTools/lazy-module-status.component.js +1 -0
  103. package/dist/DevTools/lazy-module-status.component.js.map +1 -1
  104. package/dist/DevTools/settings-explorer.component.d.ts.map +1 -1
  105. package/dist/DevTools/settings-explorer.component.js +1 -0
  106. package/dist/DevTools/settings-explorer.component.js.map +1 -1
  107. package/dist/DevTools/tab-strip-lab.component.d.ts.map +1 -1
  108. package/dist/DevTools/tab-strip-lab.component.js +1 -0
  109. package/dist/DevTools/tab-strip-lab.component.js.map +1 -1
  110. package/dist/EntityAdmin/entity-admin-dashboard.component.d.ts +5 -0
  111. package/dist/EntityAdmin/entity-admin-dashboard.component.d.ts.map +1 -1
  112. package/dist/EntityAdmin/entity-admin-dashboard.component.js +8 -5
  113. package/dist/EntityAdmin/entity-admin-dashboard.component.js.map +1 -1
  114. package/dist/Integration/components/overview/overview.component.js +2 -2
  115. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js +2 -2
  116. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js.map +1 -1
  117. package/dist/KnowledgeHub/components/feature-pipelines/feature-pipeline.engine.d.ts +11 -1
  118. package/dist/KnowledgeHub/components/feature-pipelines/feature-pipeline.engine.d.ts.map +1 -1
  119. package/dist/KnowledgeHub/components/feature-pipelines/feature-pipeline.engine.js +24 -2
  120. package/dist/KnowledgeHub/components/feature-pipelines/feature-pipeline.engine.js.map +1 -1
  121. package/dist/KnowledgeHub/components/feature-pipelines/feature-pipelines-resource.component.d.ts +16 -2
  122. package/dist/KnowledgeHub/components/feature-pipelines/feature-pipelines-resource.component.d.ts.map +1 -1
  123. package/dist/KnowledgeHub/components/feature-pipelines/feature-pipelines-resource.component.js +87 -33
  124. package/dist/KnowledgeHub/components/feature-pipelines/feature-pipelines-resource.component.js.map +1 -1
  125. package/dist/LoginStudio/login-studio-inspector.component.d.ts +130 -0
  126. package/dist/LoginStudio/login-studio-inspector.component.d.ts.map +1 -0
  127. package/dist/LoginStudio/login-studio-inspector.component.js +781 -0
  128. package/dist/LoginStudio/login-studio-inspector.component.js.map +1 -0
  129. package/dist/LoginStudio/login-studio-resource.component.d.ts +161 -0
  130. package/dist/LoginStudio/login-studio-resource.component.d.ts.map +1 -0
  131. package/dist/LoginStudio/login-studio-resource.component.js +890 -0
  132. package/dist/LoginStudio/login-studio-resource.component.js.map +1 -0
  133. package/dist/MCP/mcp-dashboard.component.d.ts +24 -4
  134. package/dist/MCP/mcp-dashboard.component.d.ts.map +1 -1
  135. package/dist/MCP/mcp-dashboard.component.js +118 -65
  136. package/dist/MCP/mcp-dashboard.component.js.map +1 -1
  137. package/dist/PredictiveStudio/business-predictions.view-models.d.ts +1 -1
  138. package/dist/PredictiveStudio/business-predictions.view-models.d.ts.map +1 -1
  139. package/dist/PredictiveStudio/business-predictions.view-models.js +3 -3
  140. package/dist/PredictiveStudio/business-predictions.view-models.js.map +1 -1
  141. package/dist/PredictiveStudio/components/ps-experiments.component.d.ts +6 -63
  142. package/dist/PredictiveStudio/components/ps-experiments.component.d.ts.map +1 -1
  143. package/dist/PredictiveStudio/components/ps-experiments.component.js +256 -521
  144. package/dist/PredictiveStudio/components/ps-experiments.component.js.map +1 -1
  145. package/dist/PredictiveStudio/components/ps-pipeline-wizard.component.d.ts +0 -18
  146. package/dist/PredictiveStudio/components/ps-pipeline-wizard.component.d.ts.map +1 -1
  147. package/dist/PredictiveStudio/components/ps-pipeline-wizard.component.js +122 -249
  148. package/dist/PredictiveStudio/components/ps-pipeline-wizard.component.js.map +1 -1
  149. package/dist/PredictiveStudio/components/ps-pipelines.component.d.ts +5 -9
  150. package/dist/PredictiveStudio/components/ps-pipelines.component.d.ts.map +1 -1
  151. package/dist/PredictiveStudio/components/ps-pipelines.component.js +98 -130
  152. package/dist/PredictiveStudio/components/ps-pipelines.component.js.map +1 -1
  153. package/dist/PredictiveStudio/components/ps-predictions-grid.component.d.ts +53 -4
  154. package/dist/PredictiveStudio/components/ps-predictions-grid.component.d.ts.map +1 -1
  155. package/dist/PredictiveStudio/components/ps-predictions-grid.component.js +335 -326
  156. package/dist/PredictiveStudio/components/ps-predictions-grid.component.js.map +1 -1
  157. package/dist/PredictiveStudio/components/ps-row-drivers.component.d.ts +19 -0
  158. package/dist/PredictiveStudio/components/ps-row-drivers.component.d.ts.map +1 -0
  159. package/dist/PredictiveStudio/components/ps-row-drivers.component.js +85 -0
  160. package/dist/PredictiveStudio/components/ps-row-drivers.component.js.map +1 -0
  161. package/dist/PredictiveStudio/engine/predictive-studio.engine.d.ts +19 -1
  162. package/dist/PredictiveStudio/engine/predictive-studio.engine.d.ts.map +1 -1
  163. package/dist/PredictiveStudio/engine/predictive-studio.engine.js +51 -2
  164. package/dist/PredictiveStudio/engine/predictive-studio.engine.js.map +1 -1
  165. package/dist/PredictiveStudio/predictive-studio-agent-context.d.ts +3 -1
  166. package/dist/PredictiveStudio/predictive-studio-agent-context.d.ts.map +1 -1
  167. package/dist/PredictiveStudio/predictive-studio-agent-context.js +3 -0
  168. package/dist/PredictiveStudio/predictive-studio-agent-context.js.map +1 -1
  169. package/dist/PredictiveStudio/predictive-studio-score-history.service.d.ts +27 -4
  170. package/dist/PredictiveStudio/predictive-studio-score-history.service.d.ts.map +1 -1
  171. package/dist/PredictiveStudio/predictive-studio-score-history.service.js +94 -61
  172. package/dist/PredictiveStudio/predictive-studio-score-history.service.js.map +1 -1
  173. package/dist/PredictiveStudio/resources/ps-predictions-resource.component.d.ts +29 -5
  174. package/dist/PredictiveStudio/resources/ps-predictions-resource.component.d.ts.map +1 -1
  175. package/dist/PredictiveStudio/resources/ps-predictions-resource.component.js +185 -103
  176. package/dist/PredictiveStudio/resources/ps-predictions-resource.component.js.map +1 -1
  177. package/dist/PredictiveStudio/resources/ps-studio-resource.component.js +1 -1
  178. package/dist/PredictiveStudio/resources/ps-studio-resource.component.js.map +1 -1
  179. package/dist/Workflows/components/workflow-runs-resource.component.js +4 -4
  180. package/dist/Workflows/components/workflow-runs-resource.component.js.map +1 -1
  181. package/dist/ai-dashboards.module.d.ts +22 -21
  182. package/dist/ai-dashboards.module.d.ts.map +1 -1
  183. package/dist/ai-dashboards.module.js +8 -2
  184. package/dist/ai-dashboards.module.js.map +1 -1
  185. package/dist/core-dashboards.module.d.ts +2 -1
  186. package/dist/core-dashboards.module.d.ts.map +1 -1
  187. package/dist/core-dashboards.module.js +11 -3
  188. package/dist/core-dashboards.module.js.map +1 -1
  189. package/dist/public-api.d.ts +3 -0
  190. package/dist/public-api.d.ts.map +1 -1
  191. package/dist/public-api.js +4 -0
  192. package/dist/public-api.js.map +1 -1
  193. package/package.json +72 -69
  194. package/dist/PredictiveStudio/at-risk.view-models.d.ts +0 -120
  195. package/dist/PredictiveStudio/at-risk.view-models.d.ts.map +0 -1
  196. package/dist/PredictiveStudio/at-risk.view-models.js +0 -261
  197. package/dist/PredictiveStudio/at-risk.view-models.js.map +0 -1
  198. package/dist/PredictiveStudio/components/ps-confirm-modal.component.d.ts +0 -109
  199. package/dist/PredictiveStudio/components/ps-confirm-modal.component.d.ts.map +0 -1
  200. package/dist/PredictiveStudio/components/ps-confirm-modal.component.js +0 -323
  201. package/dist/PredictiveStudio/components/ps-confirm-modal.component.js.map +0 -1
  202. package/dist/PredictiveStudio/components/ps-run-experiment-modal.component.d.ts +0 -137
  203. package/dist/PredictiveStudio/components/ps-run-experiment-modal.component.d.ts.map +0 -1
  204. package/dist/PredictiveStudio/components/ps-run-experiment-modal.component.js +0 -826
  205. package/dist/PredictiveStudio/components/ps-run-experiment-modal.component.js.map +0 -1
@@ -4,6 +4,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
4
4
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
+ var VectorManagementResourceComponent_1;
7
8
  /**
8
9
  * @fileoverview Vector Management Resource Component
9
10
  *
@@ -17,7 +18,7 @@ import { Subject } from 'rxjs';
17
18
  import { takeUntil } from 'rxjs/operators';
18
19
  import { RunView } from '@memberjunction/core';
19
20
  import { KnowledgeHubMetadataEngine } from '@memberjunction/core-entities';
20
- import { RegisterClass, UUIDsEqual } from '@memberjunction/global';
21
+ import { RegisterClass, UUIDsEqual, EscapeSQLString } from '@memberjunction/global';
21
22
  import { BaseResourceComponent, NavigationService, ActivityService } from '@memberjunction/ng-shared';
22
23
  import { GraphQLAIClient } from '@memberjunction/graphql-dataprovider';
23
24
  import { AIEngineBase } from '@memberjunction/ai-engine-base';
@@ -25,8 +26,11 @@ import { MJNotificationService } from '@memberjunction/ng-notifications';
25
26
  import { BuildSingleStaticParamConfiguration, ResolveActionJobTypeID } from '../../../shared/action-scheduled-job';
26
27
  import { CronToHumanReadable } from '../autotagging/shared/classify.format';
27
28
  import { BuildAutoVectorIndexName, FindMatchingVectorIndex } from './vector-index-auto';
29
+ import { ChosenIndexForSave, IndexesForSelection, SelectDatabase, SelectEmbeddingModel, SelectIndex, } from './vector-store-selection';
28
30
  import { BuildVectorAgentContext, ResolveSyncRow, } from './vector-management-agent-context';
29
31
  import { ValidateStringParam } from '../../../shared/agent-tool-validation';
32
+ import { WithoutSensitiveFields, SensitiveFieldsInTemplate } from './sensitive-fields';
33
+ import { ENTITY_DOCUMENT_TYPE_BY_USE_CASE, MAX_TEMPLATE_FIELDS, CapSelectedFields, EntityDocumentTypeForUseCase, SuggestionUseCaseForDocumentType, IsVectorizableEntity, SuggestedMatchThresholds, TemplateFieldCapRefusal, } from './vector-document-rules';
30
34
  import * as i0 from "@angular/core";
31
35
  import * as i1 from "@angular/common";
32
36
  import * as i2 from "@angular/forms";
@@ -85,31 +89,31 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_For_3_Tem
85
89
  function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_18_Template(rf, ctx) { if (rf & 1) {
86
90
  i0.ɵɵelement(0, "mj-empty-state", 23);
87
91
  } }
88
- function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_19_For_18_Conditional_13_Template(rf, ctx) { if (rf & 1) {
92
+ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_19_For_20_Conditional_15_Template(rf, ctx) { if (rf & 1) {
89
93
  i0.ɵɵtext(0);
90
94
  } if (rf & 2) {
91
95
  const row_r7 = i0.ɵɵnextContext().$implicit;
92
96
  i0.ɵɵtextInterpolate1(" ", row_r7.PercentComplete, "% ");
93
97
  } }
94
- function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_19_For_18_Conditional_14_Template(rf, ctx) { if (rf & 1) {
98
+ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_19_For_20_Conditional_16_Template(rf, ctx) { if (rf & 1) {
95
99
  i0.ɵɵtext(0);
96
100
  } if (rf & 2) {
97
101
  const row_r7 = i0.ɵɵnextContext().$implicit;
98
102
  i0.ɵɵtextInterpolate1(" ", row_r7.Status, " ");
99
103
  } }
100
- function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_19_For_18_Conditional_17_Template(rf, ctx) { if (rf & 1) {
101
- i0.ɵɵelement(0, "i", 60);
104
+ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_19_For_20_Conditional_19_Template(rf, ctx) { if (rf & 1) {
105
+ i0.ɵɵelement(0, "i", 61);
102
106
  i0.ɵɵtext(1);
103
107
  } if (rf & 2) {
104
108
  const row_r7 = i0.ɵɵnextContext().$implicit;
105
109
  i0.ɵɵadvance();
106
110
  i0.ɵɵtextInterpolate1(" ", row_r7.PercentComplete > 0 ? row_r7.PercentComplete + "%" : "Sync", " ");
107
111
  } }
108
- function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_19_For_18_Conditional_18_Template(rf, ctx) { if (rf & 1) {
109
- i0.ɵɵelement(0, "i", 61);
112
+ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_19_For_20_Conditional_20_Template(rf, ctx) { if (rf & 1) {
113
+ i0.ɵɵelement(0, "i", 62);
110
114
  i0.ɵɵtext(1, " Sync ");
111
115
  } }
112
- function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_19_For_18_Template(rf, ctx) { if (rf & 1) {
116
+ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_19_For_20_Template(rf, ctx) { if (rf & 1) {
113
117
  const _r6 = i0.ɵɵgetCurrentView();
114
118
  i0.ɵɵelementStart(0, "tr")(1, "td", 49);
115
119
  i0.ɵɵtext(2);
@@ -119,26 +123,29 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
119
123
  i0.ɵɵelementEnd();
120
124
  i0.ɵɵelementStart(5, "td", 51);
121
125
  i0.ɵɵtext(6);
122
- i0.ɵɵpipe(7, "number");
123
126
  i0.ɵɵelementEnd();
124
- i0.ɵɵelementStart(8, "td", 52);
125
- i0.ɵɵtext(9);
127
+ i0.ɵɵelementStart(7, "td", 52);
128
+ i0.ɵɵtext(8);
129
+ i0.ɵɵpipe(9, "number");
130
+ i0.ɵɵelementEnd();
131
+ i0.ɵɵelementStart(10, "td", 53);
132
+ i0.ɵɵtext(11);
126
133
  i0.ɵɵelementEnd();
127
- i0.ɵɵelementStart(10, "td")(11, "span", 53);
128
- i0.ɵɵelement(12, "i");
129
- i0.ɵɵconditionalCreate(13, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_19_For_18_Conditional_13_Template, 1, 1)(14, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_19_For_18_Conditional_14_Template, 1, 1);
134
+ i0.ɵɵelementStart(12, "td")(13, "span", 54);
135
+ i0.ɵɵelement(14, "i");
136
+ i0.ɵɵconditionalCreate(15, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_19_For_20_Conditional_15_Template, 1, 1)(16, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_19_For_20_Conditional_16_Template, 1, 1);
130
137
  i0.ɵɵelementEnd()();
131
- i0.ɵɵelementStart(15, "td", 54)(16, "button", 55);
132
- i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_19_For_18_Template_button_click_16_listener() { const row_r7 = i0.ɵɵrestoreView(_r6).$implicit; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.SyncEntity(row_r7.EntityDocumentID)); });
133
- i0.ɵɵconditionalCreate(17, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_19_For_18_Conditional_17_Template, 2, 1)(18, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_19_For_18_Conditional_18_Template, 2, 0);
138
+ i0.ɵɵelementStart(17, "td", 55)(18, "button", 56);
139
+ 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)); });
140
+ i0.ɵɵconditionalCreate(19, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_19_For_20_Conditional_19_Template, 2, 1)(20, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_19_For_20_Conditional_20_Template, 2, 0);
134
141
  i0.ɵɵelementEnd();
135
- i0.ɵɵelementStart(19, "button", 56);
136
- i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_19_For_18_Template_button_click_19_listener() { const row_r7 = i0.ɵɵrestoreView(_r6).$implicit; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.OpenScheduleSyncDialog(row_r7.EntityDocumentID)); });
137
- i0.ɵɵelement(20, "i", 57);
142
+ i0.ɵɵelementStart(21, "button", 57);
143
+ 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)); });
144
+ i0.ɵɵelement(22, "i", 58);
138
145
  i0.ɵɵelementEnd();
139
- i0.ɵɵelementStart(21, "button", 58);
140
- i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_19_For_18_Template_button_click_21_listener() { const row_r7 = i0.ɵɵrestoreView(_r6).$implicit; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.OpenEditPanel(row_r7.EntityDocumentID)); });
141
- i0.ɵɵelement(22, "i", 59);
146
+ i0.ɵɵelementStart(23, "button", 59);
147
+ 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)); });
148
+ i0.ɵɵelement(24, "i", 60);
142
149
  i0.ɵɵelementEnd()()();
143
150
  } if (rf & 2) {
144
151
  const row_r7 = ctx.$implicit;
@@ -148,7 +155,9 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
148
155
  i0.ɵɵadvance(2);
149
156
  i0.ɵɵtextInterpolate(row_r7.DocumentName);
150
157
  i0.ɵɵadvance(2);
151
- i0.ɵɵtextInterpolate(i0.ɵɵpipeBind1(7, 11, row_r7.VectorCount));
158
+ i0.ɵɵtextInterpolate(row_r7.DocumentType);
159
+ i0.ɵɵadvance(2);
160
+ i0.ɵɵtextInterpolate(i0.ɵɵpipeBind1(9, 12, row_r7.VectorCount));
152
161
  i0.ɵɵadvance(3);
153
162
  i0.ɵɵtextInterpolate(ctx_r1.FormatDate(row_r7.LastSynced));
154
163
  i0.ɵɵadvance(2);
@@ -156,11 +165,11 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
156
165
  i0.ɵɵadvance();
157
166
  i0.ɵɵclassMap(ctx_r1.GetStatusIcon(row_r7.Status));
158
167
  i0.ɵɵadvance();
159
- i0.ɵɵconditional(row_r7.Status === "Syncing" && row_r7.PercentComplete > 0 ? 13 : 14);
168
+ i0.ɵɵconditional(row_r7.Status === "Syncing" && row_r7.PercentComplete > 0 ? 15 : 16);
160
169
  i0.ɵɵadvance(3);
161
170
  i0.ɵɵproperty("disabled", ctx_r1.IsSyncing(row_r7.EntityDocumentID));
162
171
  i0.ɵɵadvance();
163
- i0.ɵɵconditional(ctx_r1.IsSyncing(row_r7.EntityDocumentID) ? 17 : 18);
172
+ i0.ɵɵconditional(ctx_r1.IsSyncing(row_r7.EntityDocumentID) ? 19 : 20);
164
173
  } }
165
174
  function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_19_Template(rf, ctx) { if (rf & 1) {
166
175
  i0.ɵɵelementStart(0, "div", 24)(1, "table", 46)(2, "thead")(3, "tr")(4, "th");
@@ -169,24 +178,27 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
169
178
  i0.ɵɵelementStart(6, "th");
170
179
  i0.ɵɵtext(7, "Document");
171
180
  i0.ɵɵelementEnd();
172
- i0.ɵɵelementStart(8, "th", 47);
173
- i0.ɵɵtext(9, "Vectors");
181
+ i0.ɵɵelementStart(8, "th");
182
+ i0.ɵɵtext(9, "Type");
174
183
  i0.ɵɵelementEnd();
175
- i0.ɵɵelementStart(10, "th");
176
- i0.ɵɵtext(11, "Last Synced");
184
+ i0.ɵɵelementStart(10, "th", 47);
185
+ i0.ɵɵtext(11, "Vectors");
177
186
  i0.ɵɵelementEnd();
178
187
  i0.ɵɵelementStart(12, "th");
179
- i0.ɵɵtext(13, "Status");
188
+ i0.ɵɵtext(13, "Last Synced");
189
+ i0.ɵɵelementEnd();
190
+ i0.ɵɵelementStart(14, "th");
191
+ i0.ɵɵtext(15, "Status");
180
192
  i0.ɵɵelementEnd();
181
- i0.ɵɵelementStart(14, "th", 48);
182
- i0.ɵɵtext(15, "Actions");
193
+ i0.ɵɵelementStart(16, "th", 48);
194
+ i0.ɵɵtext(17, "Actions");
183
195
  i0.ɵɵelementEnd()()();
184
- i0.ɵɵelementStart(16, "tbody");
185
- i0.ɵɵrepeaterCreate(17, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_19_For_18_Template, 23, 13, "tr", null, _forTrack1);
196
+ i0.ɵɵelementStart(18, "tbody");
197
+ i0.ɵɵrepeaterCreate(19, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_19_For_20_Template, 25, 14, "tr", null, _forTrack1);
186
198
  i0.ɵɵelementEnd()()();
187
199
  } if (rf & 2) {
188
200
  const ctx_r1 = i0.ɵɵnextContext(3);
189
- i0.ɵɵadvance(17);
201
+ i0.ɵɵadvance(19);
190
202
  i0.ɵɵrepeater(ctx_r1.SyncRows);
191
203
  } }
192
204
  function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_31_Template(rf, ctx) { if (rf & 1) {
@@ -202,7 +214,7 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
202
214
  i0.ɵɵelementStart(0, "div", 36)(1, "span", 37);
203
215
  i0.ɵɵtext(2, "Dimensions");
204
216
  i0.ɵɵelementEnd();
205
- i0.ɵɵelementStart(3, "span", 62);
217
+ i0.ɵɵelementStart(3, "span", 63);
206
218
  i0.ɵɵtext(4);
207
219
  i0.ɵɵpipe(5, "number");
208
220
  i0.ɵɵelementEnd()();
@@ -211,16 +223,16 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
211
223
  i0.ɵɵadvance(4);
212
224
  i0.ɵɵtextInterpolate(i0.ɵɵpipeBind1(5, 1, ctx_r1.EmbeddingModel.Dimensions));
213
225
  } }
214
- function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_20_Template(rf, ctx) { if (rf & 1) {
215
- i0.ɵɵelement(0, "i", 60);
226
+ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_25_Template(rf, ctx) { if (rf & 1) {
227
+ i0.ɵɵelement(0, "i", 61);
216
228
  i0.ɵɵtext(1, " Regenerating... ");
217
229
  } }
218
- function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_21_Template(rf, ctx) { if (rf & 1) {
230
+ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_26_Template(rf, ctx) { if (rf & 1) {
219
231
  i0.ɵɵelement(0, "i", 19);
220
232
  i0.ɵɵtext(1, " Regenerate with AI ");
221
233
  } }
222
- function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_24_For_5_Template(rf, ctx) { if (rf & 1) {
223
- i0.ɵɵelementStart(0, "span", 88);
234
+ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_29_For_5_Template(rf, ctx) { if (rf & 1) {
235
+ i0.ɵɵelementStart(0, "span", 89);
224
236
  i0.ɵɵtext(1);
225
237
  i0.ɵɵelementEnd();
226
238
  } if (rf & 2) {
@@ -228,20 +240,20 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
228
240
  i0.ɵɵadvance();
229
241
  i0.ɵɵtextInterpolate(field_r9);
230
242
  } }
231
- function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_24_Template(rf, ctx) { if (rf & 1) {
232
- i0.ɵɵelementStart(0, "div", 71)(1, "label", 72);
243
+ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_29_Template(rf, ctx) { if (rf & 1) {
244
+ i0.ɵɵelementStart(0, "div", 72)(1, "label", 73);
233
245
  i0.ɵɵtext(2, "Selected Fields");
234
246
  i0.ɵɵelementEnd();
235
- i0.ɵɵelementStart(3, "div", 87);
236
- i0.ɵɵrepeaterCreate(4, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_24_For_5_Template, 2, 1, "span", 88, i0.ɵɵrepeaterTrackByIdentity);
247
+ i0.ɵɵelementStart(3, "div", 88);
248
+ i0.ɵɵrepeaterCreate(4, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_29_For_5_Template, 2, 1, "span", 89, i0.ɵɵrepeaterTrackByIdentity);
237
249
  i0.ɵɵelementEnd()();
238
250
  } if (rf & 2) {
239
251
  const ctx_r1 = i0.ɵɵnextContext(4);
240
252
  i0.ɵɵadvance(4);
241
253
  i0.ɵɵrepeater(ctx_r1.EditDocSelectedFields);
242
254
  } }
243
- function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_For_34_Template(rf, ctx) { if (rf & 1) {
244
- i0.ɵɵelementStart(0, "option", 80);
255
+ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_For_39_Template(rf, ctx) { if (rf & 1) {
256
+ i0.ɵɵelementStart(0, "option", 81);
245
257
  i0.ɵɵtext(1);
246
258
  i0.ɵɵelementEnd();
247
259
  } if (rf & 2) {
@@ -250,8 +262,8 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
250
262
  i0.ɵɵadvance();
251
263
  i0.ɵɵtextInterpolate(model_r10.Name);
252
264
  } }
253
- function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_For_40_Template(rf, ctx) { if (rf & 1) {
254
- i0.ɵɵelementStart(0, "option", 80);
265
+ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_For_45_Template(rf, ctx) { if (rf & 1) {
266
+ i0.ɵɵelementStart(0, "option", 81);
255
267
  i0.ɵɵtext(1);
256
268
  i0.ɵɵelementEnd();
257
269
  } if (rf & 2) {
@@ -260,8 +272,8 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
260
272
  i0.ɵɵadvance();
261
273
  i0.ɵɵtextInterpolate(db_r11.Name);
262
274
  } }
263
- function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_44_For_4_Template(rf, ctx) { if (rf & 1) {
264
- i0.ɵɵelementStart(0, "option", 80);
275
+ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_49_For_4_Template(rf, ctx) { if (rf & 1) {
276
+ i0.ɵɵelementStart(0, "option", 81);
265
277
  i0.ɵɵtext(1);
266
278
  i0.ɵɵelementEnd();
267
279
  } if (rf & 2) {
@@ -270,204 +282,212 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
270
282
  i0.ɵɵadvance();
271
283
  i0.ɵɵtextInterpolate(idx_r13.Name);
272
284
  } }
273
- function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_44_Template(rf, ctx) { if (rf & 1) {
285
+ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_49_Template(rf, ctx) { if (rf & 1) {
274
286
  const _r12 = i0.ɵɵgetCurrentView();
275
- i0.ɵɵelementStart(0, "select", 79);
276
- i0.ɵɵtwoWayListener("ngModelChange", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_44_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); });
277
- i0.ɵɵelementStart(1, "option", 89);
287
+ i0.ɵɵelementStart(0, "select", 80);
288
+ i0.ɵɵlistener("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); return i0.ɵɵresetView(ctx_r1.OnEditVectorIndexChange($event)); });
289
+ i0.ɵɵelementStart(1, "option", 90);
278
290
  i0.ɵɵtext(2, "Auto (create/find matching index)");
279
291
  i0.ɵɵelementEnd();
280
- i0.ɵɵrepeaterCreate(3, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_44_For_4_Template, 2, 2, "option", 80, _forTrack2);
292
+ i0.ɵɵrepeaterCreate(3, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_49_For_4_Template, 2, 2, "option", 81, _forTrack2);
281
293
  i0.ɵɵelementEnd();
282
294
  } if (rf & 2) {
283
295
  const ctx_r1 = i0.ɵɵnextContext(4);
284
- i0.ɵɵtwoWayProperty("ngModel", ctx_r1.EditDocVectorIndexID);
296
+ i0.ɵɵproperty("ngModel", ctx_r1.EditDocVectorIndexID);
285
297
  i0.ɵɵadvance(3);
286
298
  i0.ɵɵrepeater(ctx_r1.EditFilteredIndexes);
287
299
  } }
288
- function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_45_Template(rf, ctx) { if (rf & 1) {
289
- i0.ɵɵelementStart(0, "span", 82);
300
+ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_50_Template(rf, ctx) { if (rf & 1) {
301
+ i0.ɵɵelementStart(0, "span", 83);
290
302
  i0.ɵɵtext(1, " No indexes for this database \u2014 one will be created automatically on sync ");
291
303
  i0.ɵɵelementEnd();
292
304
  } }
293
- function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_55_Template(rf, ctx) { if (rf & 1) {
294
- i0.ɵɵelement(0, "mj-loading", 86);
305
+ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_60_Template(rf, ctx) { if (rf & 1) {
306
+ i0.ɵɵelement(0, "mj-loading", 87);
295
307
  } }
296
- function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_56_Template(rf, ctx) { if (rf & 1) {
308
+ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_61_Template(rf, ctx) { if (rf & 1) {
297
309
  const _r14 = i0.ɵɵgetCurrentView();
298
- i0.ɵɵelementStart(0, "button", 90);
299
- i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_56_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.SaveEditedDocument()); });
300
- i0.ɵɵelement(1, "i", 91);
310
+ i0.ɵɵelementStart(0, "button", 91);
311
+ 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()); });
312
+ i0.ɵɵelement(1, "i", 92);
301
313
  i0.ɵɵtext(2, " Save Changes ");
302
314
  i0.ɵɵelementEnd();
303
- i0.ɵɵelementStart(3, "button", 92);
304
- i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_56_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.DeleteEntityDocument()); });
305
- i0.ɵɵelement(4, "i", 93);
315
+ i0.ɵɵelementStart(3, "button", 93);
316
+ 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()); });
317
+ i0.ɵɵelement(4, "i", 94);
306
318
  i0.ɵɵtext(5, " Delete ");
307
319
  i0.ɵɵelementEnd();
308
- i0.ɵɵelementStart(6, "button", 94);
309
- i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_56_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.CloseEditPanel()); });
320
+ i0.ɵɵelementStart(6, "button", 95);
321
+ i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_61_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.CloseEditPanel()); });
310
322
  i0.ɵɵtext(7, " Cancel ");
311
323
  i0.ɵɵelementEnd();
312
324
  } }
313
325
  function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Template(rf, ctx) { if (rf & 1) {
314
326
  const _r8 = i0.ɵɵgetCurrentView();
315
- i0.ɵɵelementStart(0, "div", 63);
327
+ i0.ɵɵelementStart(0, "div", 64);
316
328
  i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.CloseEditPanel()); });
317
- i0.ɵɵelementStart(1, "div", 64);
329
+ i0.ɵɵelementStart(1, "div", 65);
318
330
  i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Template_div_click_1_listener($event) { return $event.stopPropagation(); });
319
- i0.ɵɵelementStart(2, "div", 65)(3, "h3", 66);
320
- i0.ɵɵelement(4, "i", 59);
331
+ i0.ɵɵelementStart(2, "div", 66)(3, "h3", 67);
332
+ i0.ɵɵelement(4, "i", 60);
321
333
  i0.ɵɵtext(5, " Edit Entity Document ");
322
334
  i0.ɵɵelementEnd();
323
- i0.ɵɵelementStart(6, "button", 67);
335
+ i0.ɵɵelementStart(6, "button", 68);
324
336
  i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.CloseEditPanel()); });
325
- i0.ɵɵelement(7, "i", 68);
337
+ i0.ɵɵelement(7, "i", 69);
326
338
  i0.ɵɵelementEnd()();
327
- i0.ɵɵelementStart(8, "div", 69)(9, "div", 70)(10, "div", 71)(11, "label", 72);
339
+ i0.ɵɵelementStart(8, "div", 70)(9, "div", 71)(10, "div", 72)(11, "label", 73);
328
340
  i0.ɵɵtext(12, "Entity");
329
341
  i0.ɵɵelementEnd();
330
- i0.ɵɵelementStart(13, "span", 73);
342
+ i0.ɵɵelementStart(13, "span", 74);
331
343
  i0.ɵɵtext(14);
332
344
  i0.ɵɵelementEnd()();
333
- i0.ɵɵelementStart(15, "div", 71)(16, "div", 74)(17, "label", 72);
334
- i0.ɵɵtext(18, "Template");
345
+ i0.ɵɵelementStart(15, "div", 72)(16, "label", 73);
346
+ i0.ɵɵtext(17, "Type");
335
347
  i0.ɵɵelementEnd();
336
- i0.ɵɵelementStart(19, "button", 75);
337
- i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Template_button_click_19_listener() { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.RegenerateTemplate()); });
338
- i0.ɵɵconditionalCreate(20, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_20_Template, 2, 0)(21, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_21_Template, 2, 0);
348
+ i0.ɵɵelementStart(18, "span", 74);
349
+ i0.ɵɵtext(19);
339
350
  i0.ɵɵelementEnd()();
340
- i0.ɵɵelementStart(22, "div", 76)(23, "mj-code-editor", 77);
341
- i0.ɵɵlistener("change", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Template_mj_code_editor_change_23_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnEditTemplateChange($event)); });
351
+ i0.ɵɵelementStart(20, "div", 72)(21, "div", 75)(22, "label", 73);
352
+ i0.ɵɵtext(23, "Template");
353
+ i0.ɵɵelementEnd();
354
+ i0.ɵɵelementStart(24, "button", 76);
355
+ 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()); });
356
+ 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);
357
+ i0.ɵɵelementEnd()();
358
+ i0.ɵɵelementStart(27, "div", 77)(28, "mj-code-editor", 78);
359
+ i0.ɵɵlistener("change", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Template_mj_code_editor_change_28_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnEditTemplateChange($event)); });
342
360
  i0.ɵɵelementEnd()()();
343
- i0.ɵɵconditionalCreate(24, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_24_Template, 6, 0, "div", 71);
344
- i0.ɵɵelementStart(25, "div", 71)(26, "label", 72);
345
- i0.ɵɵtext(27, "Document Name");
361
+ i0.ɵɵconditionalCreate(29, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_29_Template, 6, 0, "div", 72);
362
+ i0.ɵɵelementStart(30, "div", 72)(31, "label", 73);
363
+ i0.ɵɵtext(32, "Document Name");
346
364
  i0.ɵɵelementEnd();
347
- i0.ɵɵelementStart(28, "input", 78);
348
- i0.ɵɵtwoWayListener("ngModelChange", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Template_input_ngModelChange_28_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); });
365
+ i0.ɵɵelementStart(33, "input", 79);
366
+ i0.ɵɵtwoWayListener("ngModelChange", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Template_input_ngModelChange_33_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(3); i0.ɵɵtwoWayBindingSet(ctx_r1.EditDocName, $event) || (ctx_r1.EditDocName = $event); return i0.ɵɵresetView($event); });
349
367
  i0.ɵɵelementEnd()();
350
- i0.ɵɵelementStart(29, "div", 71)(30, "label", 72);
351
- i0.ɵɵtext(31, "Embedding Model");
368
+ i0.ɵɵelementStart(34, "div", 72)(35, "label", 73);
369
+ i0.ɵɵtext(36, "Embedding Model");
352
370
  i0.ɵɵelementEnd();
353
- i0.ɵɵelementStart(32, "select", 79);
354
- i0.ɵɵtwoWayListener("ngModelChange", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Template_select_ngModelChange_32_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); });
355
- i0.ɵɵrepeaterCreate(33, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_For_34_Template, 2, 2, "option", 80, _forTrack2);
371
+ i0.ɵɵelementStart(37, "select", 80);
372
+ i0.ɵɵlistener("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); return i0.ɵɵresetView(ctx_r1.OnEditEmbeddingModelChange($event)); });
373
+ i0.ɵɵrepeaterCreate(38, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_For_39_Template, 2, 2, "option", 81, _forTrack2);
356
374
  i0.ɵɵelementEnd()();
357
- i0.ɵɵelementStart(35, "div", 71)(36, "label", 72);
358
- i0.ɵɵtext(37, "Vector Database");
375
+ i0.ɵɵelementStart(40, "div", 72)(41, "label", 73);
376
+ i0.ɵɵtext(42, "Vector Database");
359
377
  i0.ɵɵelementEnd();
360
- i0.ɵɵelementStart(38, "select", 79);
361
- i0.ɵɵtwoWayListener("ngModelChange", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Template_select_ngModelChange_38_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); });
362
- i0.ɵɵrepeaterCreate(39, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_For_40_Template, 2, 2, "option", 80, _forTrack2);
378
+ i0.ɵɵelementStart(43, "select", 80);
379
+ i0.ɵɵlistener("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); return i0.ɵɵresetView(ctx_r1.OnEditVectorDBChange($event)); });
380
+ i0.ɵɵrepeaterCreate(44, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_For_45_Template, 2, 2, "option", 81, _forTrack2);
363
381
  i0.ɵɵelementEnd()();
364
- i0.ɵɵelementStart(41, "div", 71)(42, "label", 72);
365
- i0.ɵɵtext(43, "Vector Index");
382
+ i0.ɵɵelementStart(46, "div", 72)(47, "label", 73);
383
+ i0.ɵɵtext(48, "Vector Index");
366
384
  i0.ɵɵelementEnd();
367
- i0.ɵɵconditionalCreate(44, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_44_Template, 5, 1, "select", 81)(45, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_45_Template, 2, 0, "span", 82);
385
+ i0.ɵɵconditionalCreate(49, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_49_Template, 5, 1, "select", 82)(50, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_50_Template, 2, 0, "span", 83);
368
386
  i0.ɵɵelementEnd();
369
- i0.ɵɵelementStart(46, "div", 71)(47, "label", 72);
370
- i0.ɵɵtext(48, "Status");
387
+ i0.ɵɵelementStart(51, "div", 72)(52, "label", 73);
388
+ i0.ɵɵtext(53, "Status");
371
389
  i0.ɵɵelementEnd();
372
- i0.ɵɵelementStart(49, "select", 79);
373
- i0.ɵɵtwoWayListener("ngModelChange", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Template_select_ngModelChange_49_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); });
374
- i0.ɵɵelementStart(50, "option", 83);
375
- i0.ɵɵtext(51, "Active");
390
+ i0.ɵɵelementStart(54, "select", 80);
391
+ 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); });
392
+ i0.ɵɵelementStart(55, "option", 84);
393
+ i0.ɵɵtext(56, "Active");
376
394
  i0.ɵɵelementEnd();
377
- i0.ɵɵelementStart(52, "option", 84);
378
- i0.ɵɵtext(53, "Inactive");
395
+ i0.ɵɵelementStart(57, "option", 85);
396
+ i0.ɵɵtext(58, "Inactive");
379
397
  i0.ɵɵelementEnd()()();
380
- i0.ɵɵelementStart(54, "div", 85);
381
- i0.ɵɵconditionalCreate(55, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_55_Template, 1, 0, "mj-loading", 86)(56, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_56_Template, 8, 0);
398
+ i0.ɵɵelementStart(59, "div", 86);
399
+ i0.ɵɵconditionalCreate(60, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_60_Template, 1, 0, "mj-loading", 87)(61, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Conditional_61_Template, 8, 0);
382
400
  i0.ɵɵelementEnd()()()()();
383
401
  } if (rf & 2) {
384
402
  const ctx_r1 = i0.ɵɵnextContext(3);
385
403
  i0.ɵɵadvance(14);
386
404
  i0.ɵɵtextInterpolate(ctx_r1.EditDocEntityName);
387
405
  i0.ɵɵadvance(5);
406
+ i0.ɵɵtextInterpolate(ctx_r1.EditDocType);
407
+ i0.ɵɵadvance(5);
388
408
  i0.ɵɵproperty("disabled", ctx_r1.IsEditRegenerating);
389
409
  i0.ɵɵadvance();
390
- i0.ɵɵconditional(ctx_r1.IsEditRegenerating ? 20 : 21);
410
+ i0.ɵɵconditional(ctx_r1.IsEditRegenerating ? 25 : 26);
391
411
  i0.ɵɵadvance(3);
392
412
  i0.ɵɵproperty("value", ctx_r1.EditDocTemplate)("readonly", false)("lineWrapping", true);
393
413
  i0.ɵɵadvance();
394
- i0.ɵɵconditional(ctx_r1.EditDocSelectedFields.length > 0 ? 24 : -1);
414
+ i0.ɵɵconditional(ctx_r1.EditDocSelectedFields.length > 0 ? 29 : -1);
395
415
  i0.ɵɵadvance(4);
396
416
  i0.ɵɵtwoWayProperty("ngModel", ctx_r1.EditDocName);
397
417
  i0.ɵɵadvance(4);
398
- i0.ɵɵtwoWayProperty("ngModel", ctx_r1.EditDocAIModelID);
418
+ i0.ɵɵproperty("ngModel", ctx_r1.EditDocAIModelID);
399
419
  i0.ɵɵadvance();
400
420
  i0.ɵɵrepeater(ctx_r1.AvailableEmbeddingModels);
401
421
  i0.ɵɵadvance(5);
402
- i0.ɵɵtwoWayProperty("ngModel", ctx_r1.EditDocVectorDBID);
422
+ i0.ɵɵproperty("ngModel", ctx_r1.EditDocVectorDBID);
403
423
  i0.ɵɵadvance();
404
424
  i0.ɵɵrepeater(ctx_r1.vectorDatabases);
405
425
  i0.ɵɵadvance(5);
406
- i0.ɵɵconditional(ctx_r1.EditFilteredIndexes.length > 0 ? 44 : 45);
426
+ i0.ɵɵconditional(ctx_r1.EditFilteredIndexes.length > 0 ? 49 : 50);
407
427
  i0.ɵɵadvance(5);
408
428
  i0.ɵɵtwoWayProperty("ngModel", ctx_r1.EditDocStatus);
409
429
  i0.ɵɵadvance(6);
410
- i0.ɵɵconditional(ctx_r1.IsEditSaving || ctx_r1.IsEditDeleting ? 55 : 56);
430
+ i0.ɵɵconditional(ctx_r1.IsEditSaving || ctx_r1.IsEditDeleting ? 60 : 61);
411
431
  } }
412
432
  function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_56_Conditional_32_Template(rf, ctx) { if (rf & 1) {
413
- i0.ɵɵelement(0, "mj-loading", 86);
433
+ i0.ɵɵelement(0, "mj-loading", 87);
414
434
  } }
415
435
  function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_56_Conditional_33_Template(rf, ctx) { if (rf & 1) {
416
436
  const _r16 = i0.ɵɵgetCurrentView();
417
- i0.ɵɵelementStart(0, "button", 90);
437
+ i0.ɵɵelementStart(0, "button", 91);
418
438
  i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_56_Conditional_33_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r16); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.SaveScheduleSync()); });
419
- i0.ɵɵelement(1, "i", 101);
439
+ i0.ɵɵelement(1, "i", 102);
420
440
  i0.ɵɵtext(2, " Create Schedule ");
421
441
  i0.ɵɵelementEnd();
422
- i0.ɵɵelementStart(3, "button", 94);
442
+ i0.ɵɵelementStart(3, "button", 95);
423
443
  i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_56_Conditional_33_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r16); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.CloseScheduleSyncDialog()); });
424
444
  i0.ɵɵtext(4, " Cancel ");
425
445
  i0.ɵɵelementEnd();
426
446
  } }
427
447
  function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_56_Template(rf, ctx) { if (rf & 1) {
428
448
  const _r15 = i0.ɵɵgetCurrentView();
429
- i0.ɵɵelementStart(0, "div", 63);
449
+ i0.ɵɵelementStart(0, "div", 64);
430
450
  i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_56_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r15); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.CloseScheduleSyncDialog()); });
431
- i0.ɵɵelementStart(1, "div", 95);
451
+ i0.ɵɵelementStart(1, "div", 96);
432
452
  i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_56_Template_div_click_1_listener($event) { return $event.stopPropagation(); });
433
- i0.ɵɵelementStart(2, "div", 65)(3, "h3", 66);
434
- i0.ɵɵelement(4, "i", 57);
453
+ i0.ɵɵelementStart(2, "div", 66)(3, "h3", 67);
454
+ i0.ɵɵelement(4, "i", 58);
435
455
  i0.ɵɵtext(5, " Schedule Vector Sync ");
436
456
  i0.ɵɵelementEnd();
437
- i0.ɵɵelementStart(6, "button", 67);
457
+ i0.ɵɵelementStart(6, "button", 68);
438
458
  i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_56_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r15); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.CloseScheduleSyncDialog()); });
439
- i0.ɵɵelement(7, "i", 68);
459
+ i0.ɵɵelement(7, "i", 69);
440
460
  i0.ɵɵelementEnd()();
441
- i0.ɵɵelementStart(8, "div", 69)(9, "div", 70)(10, "div", 71)(11, "label", 72);
461
+ i0.ɵɵelementStart(8, "div", 70)(9, "div", 71)(10, "div", 72)(11, "label", 73);
442
462
  i0.ɵɵtext(12, "Entity Document");
443
463
  i0.ɵɵelementEnd();
444
- i0.ɵɵelementStart(13, "span", 73);
464
+ i0.ɵɵelementStart(13, "span", 74);
445
465
  i0.ɵɵtext(14);
446
466
  i0.ɵɵelementEnd()();
447
- i0.ɵɵelementStart(15, "div", 71)(16, "label", 72);
467
+ i0.ɵɵelementStart(15, "div", 72)(16, "label", 73);
448
468
  i0.ɵɵtext(17, "Action");
449
469
  i0.ɵɵelementEnd();
450
- i0.ɵɵelementStart(18, "span", 73);
470
+ i0.ɵɵelementStart(18, "span", 74);
451
471
  i0.ɵɵtext(19, "__VectorizeEntity");
452
472
  i0.ɵɵelementEnd()();
453
- i0.ɵɵelementStart(20, "div", 71)(21, "label", 72);
473
+ i0.ɵɵelementStart(20, "div", 72)(21, "label", 73);
454
474
  i0.ɵɵtext(22, "Cron Expression");
455
475
  i0.ɵɵelementEnd();
456
- i0.ɵɵelementStart(23, "input", 96);
476
+ i0.ɵɵelementStart(23, "input", 97);
457
477
  i0.ɵɵtwoWayListener("ngModelChange", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_56_Template_input_ngModelChange_23_listener($event) { i0.ɵɵrestoreView(_r15); const ctx_r1 = i0.ɵɵnextContext(3); i0.ɵɵtwoWayBindingSet(ctx_r1.ScheduleSyncCron, $event) || (ctx_r1.ScheduleSyncCron = $event); return i0.ɵɵresetView($event); });
458
478
  i0.ɵɵelementEnd();
459
- i0.ɵɵelementStart(24, "div", 97);
460
- i0.ɵɵelement(25, "i", 98);
479
+ i0.ɵɵelementStart(24, "div", 98);
480
+ i0.ɵɵelement(25, "i", 99);
461
481
  i0.ɵɵtext(26);
462
482
  i0.ɵɵelementEnd()();
463
- i0.ɵɵelementStart(27, "div", 99)(28, "label", 72);
483
+ i0.ɵɵelementStart(27, "div", 100)(28, "label", 73);
464
484
  i0.ɵɵtext(29, "Enabled");
465
485
  i0.ɵɵelementEnd();
466
- i0.ɵɵelementStart(30, "input", 100);
486
+ i0.ɵɵelementStart(30, "input", 101);
467
487
  i0.ɵɵtwoWayListener("ngModelChange", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_56_Template_input_ngModelChange_30_listener($event) { i0.ɵɵrestoreView(_r15); const ctx_r1 = i0.ɵɵnextContext(3); i0.ɵɵtwoWayBindingSet(ctx_r1.ScheduleSyncEnabled, $event) || (ctx_r1.ScheduleSyncEnabled = $event); return i0.ɵɵresetView($event); });
468
488
  i0.ɵɵelementEnd()();
469
- i0.ɵɵelementStart(31, "div", 85);
470
- i0.ɵɵconditionalCreate(32, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_56_Conditional_32_Template, 1, 0, "mj-loading", 86)(33, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_56_Conditional_33_Template, 5, 0);
489
+ i0.ɵɵelementStart(31, "div", 86);
490
+ i0.ɵɵconditionalCreate(32, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_56_Conditional_32_Template, 1, 0, "mj-loading", 87)(33, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_56_Conditional_33_Template, 5, 0);
471
491
  i0.ɵɵelementEnd()()()()();
472
492
  } if (rf & 2) {
473
493
  const ctx_r1 = i0.ɵɵnextContext(3);
@@ -484,25 +504,25 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
484
504
  } }
485
505
  function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_57_Template(rf, ctx) { if (rf & 1) {
486
506
  const _r17 = i0.ɵɵgetCurrentView();
487
- i0.ɵɵelementStart(0, "div", 63);
507
+ i0.ɵɵelementStart(0, "div", 64);
488
508
  i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_57_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r17); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.CloseNoIndexWarning()); });
489
- i0.ɵɵelementStart(1, "div", 102);
509
+ i0.ɵɵelementStart(1, "div", 103);
490
510
  i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_57_Template_div_click_1_listener($event) { return $event.stopPropagation(); });
491
- i0.ɵɵelementStart(2, "div", 103);
492
- i0.ɵɵelement(3, "i", 104);
511
+ i0.ɵɵelementStart(2, "div", 104);
512
+ i0.ɵɵelement(3, "i", 105);
493
513
  i0.ɵɵelementEnd();
494
- i0.ɵɵelementStart(4, "h3", 105);
514
+ i0.ɵɵelementStart(4, "h3", 106);
495
515
  i0.ɵɵtext(5, "Vector Index Required");
496
516
  i0.ɵɵelementEnd();
497
- i0.ɵɵelementStart(6, "p", 106);
517
+ i0.ɵɵelementStart(6, "p", 107);
498
518
  i0.ɵɵtext(7, " You need to create at least one vector database and index before creating entity documents. Go to the Configuration section to set up a vector database and create an index. ");
499
519
  i0.ɵɵelementEnd();
500
- i0.ɵɵelementStart(8, "div", 107)(9, "button", 90);
520
+ i0.ɵɵelementStart(8, "div", 108)(9, "button", 91);
501
521
  i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_57_Template_button_click_9_listener() { i0.ɵɵrestoreView(_r17); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.GoToConfiguration()); });
502
- i0.ɵɵelement(10, "i", 108);
522
+ i0.ɵɵelement(10, "i", 109);
503
523
  i0.ɵɵtext(11, " Go to Configuration ");
504
524
  i0.ɵɵelementEnd();
505
- i0.ɵɵelementStart(12, "button", 94);
525
+ i0.ɵɵelementStart(12, "button", 95);
506
526
  i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_57_Template_button_click_12_listener() { i0.ɵɵrestoreView(_r17); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.CloseNoIndexWarning()); });
507
527
  i0.ɵɵtext(13, " Close ");
508
528
  i0.ɵɵelementEnd()()()();
@@ -583,15 +603,15 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
583
603
  i0.ɵɵadvance(2);
584
604
  i0.ɵɵconditional(ctx_r1.FilteredEntityGroups.length === 0 ? 8 : -1);
585
605
  } }
586
- function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_9_Conditional_24_Template(rf, ctx) { if (rf & 1) {
587
- i0.ɵɵelement(0, "i", 60);
606
+ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_9_Conditional_21_Template(rf, ctx) { if (rf & 1) {
607
+ i0.ɵɵelement(0, "i", 61);
588
608
  i0.ɵɵtext(1, " Generating with AI... ");
589
609
  } }
590
- function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_9_Conditional_25_Template(rf, ctx) { if (rf & 1) {
610
+ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_9_Conditional_22_Template(rf, ctx) { if (rf & 1) {
591
611
  i0.ɵɵelement(0, "i", 19);
592
612
  i0.ɵɵtext(1, " Generate Template ");
593
613
  } }
594
- function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_9_Conditional_26_Template(rf, ctx) { if (rf & 1) {
614
+ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_9_Conditional_23_Template(rf, ctx) { if (rf & 1) {
595
615
  i0.ɵɵelementStart(0, "mj-alert", 121);
596
616
  i0.ɵɵtext(1);
597
617
  i0.ɵɵelementEnd();
@@ -602,39 +622,34 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
602
622
  } }
603
623
  function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_9_Template(rf, ctx) { if (rf & 1) {
604
624
  const _r19 = i0.ɵɵgetCurrentView();
605
- i0.ɵɵelementStart(0, "div", 70)(1, "div", 71)(2, "label", 72);
625
+ i0.ɵɵelementStart(0, "div", 71)(1, "div", 72)(2, "label", 73);
606
626
  i0.ɵɵtext(3, "Entity");
607
627
  i0.ɵɵelementEnd();
608
- i0.ɵɵelementStart(4, "div", 111)(5, "button", 112);
628
+ i0.ɵɵelementStart(4, "div", 112)(5, "button", 113);
609
629
  i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_9_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r19); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.ToggleEntityPicker()); });
610
630
  i0.ɵɵconditionalCreate(6, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_9_Conditional_6_Template, 3, 1)(7, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_9_Conditional_7_Template, 3, 0);
611
- i0.ɵɵelement(8, "i", 113);
631
+ i0.ɵɵelement(8, "i", 114);
612
632
  i0.ɵɵelementEnd();
613
- i0.ɵɵconditionalCreate(9, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_9_Conditional_9_Template, 9, 2, "div", 114);
633
+ i0.ɵɵconditionalCreate(9, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_9_Conditional_9_Template, 9, 2, "div", 115);
614
634
  i0.ɵɵelementEnd()();
615
- i0.ɵɵelementStart(10, "div", 71)(11, "label", 72);
635
+ i0.ɵɵelementStart(10, "div", 72)(11, "label", 73);
616
636
  i0.ɵɵtext(12, "Use Case");
617
637
  i0.ɵɵelementEnd();
618
- i0.ɵɵelementStart(13, "div", 115)(14, "button", 116);
638
+ i0.ɵɵelementStart(13, "div", 116)(14, "button", 117);
619
639
  i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_9_Template_button_click_14_listener() { i0.ɵɵrestoreView(_r19); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.SuggestUseCase = "duplicate detection"); });
620
- i0.ɵɵelement(15, "i", 117);
640
+ i0.ɵɵelement(15, "i", 118);
621
641
  i0.ɵɵtext(16, " Duplicate Detection ");
622
642
  i0.ɵɵelementEnd();
623
- i0.ɵɵelementStart(17, "button", 116);
643
+ i0.ɵɵelementStart(17, "button", 117);
624
644
  i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_9_Template_button_click_17_listener() { i0.ɵɵrestoreView(_r19); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.SuggestUseCase = "search"); });
625
- i0.ɵɵelement(18, "i", 118);
645
+ i0.ɵɵelement(18, "i", 119);
626
646
  i0.ɵɵtext(19, " Search ");
627
- i0.ɵɵelementEnd();
628
- i0.ɵɵelementStart(20, "button", 116);
629
- i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_9_Template_button_click_20_listener() { i0.ɵɵrestoreView(_r19); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.SuggestUseCase = "classification"); });
630
- i0.ɵɵelement(21, "i", 119);
631
- i0.ɵɵtext(22, " Classification ");
632
647
  i0.ɵɵelementEnd()()();
633
- i0.ɵɵelementStart(23, "button", 120);
634
- i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_9_Template_button_click_23_listener() { i0.ɵɵrestoreView(_r19); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.RunSuggestion()); });
635
- i0.ɵɵconditionalCreate(24, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_9_Conditional_24_Template, 2, 0)(25, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_9_Conditional_25_Template, 2, 0);
648
+ i0.ɵɵelementStart(20, "button", 120);
649
+ 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()); });
650
+ i0.ɵɵconditionalCreate(21, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_9_Conditional_21_Template, 2, 0)(22, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_9_Conditional_22_Template, 2, 0);
636
651
  i0.ɵɵelementEnd();
637
- i0.ɵɵconditionalCreate(26, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_9_Conditional_26_Template, 2, 1, "mj-alert", 121);
652
+ i0.ɵɵconditionalCreate(23, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_9_Conditional_23_Template, 2, 1, "mj-alert", 121);
638
653
  i0.ɵɵelementEnd();
639
654
  } if (rf & 2) {
640
655
  const ctx_r1 = i0.ɵɵnextContext(4);
@@ -647,16 +662,14 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
647
662
  i0.ɵɵadvance(3);
648
663
  i0.ɵɵclassProp("use-case-btn-active", ctx_r1.SuggestUseCase === "search");
649
664
  i0.ɵɵadvance(3);
650
- i0.ɵɵclassProp("use-case-btn-active", ctx_r1.SuggestUseCase === "classification");
651
- i0.ɵɵadvance(3);
652
665
  i0.ɵɵproperty("disabled", ctx_r1.IsSuggesting || !ctx_r1.SuggestEntityName);
653
666
  i0.ɵɵadvance();
654
- i0.ɵɵconditional(ctx_r1.IsSuggesting ? 24 : 25);
667
+ i0.ɵɵconditional(ctx_r1.IsSuggesting ? 21 : 22);
655
668
  i0.ɵɵadvance(2);
656
- i0.ɵɵconditional(ctx_r1.SuggestionError ? 26 : -1);
669
+ i0.ɵɵconditional(ctx_r1.SuggestionError ? 23 : -1);
657
670
  } }
658
671
  function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_For_11_Template(rf, ctx) { if (rf & 1) {
659
- i0.ɵɵelementStart(0, "span", 88);
672
+ i0.ɵɵelementStart(0, "span", 89);
660
673
  i0.ɵɵtext(1);
661
674
  i0.ɵɵelementEnd();
662
675
  } if (rf & 2) {
@@ -690,7 +703,7 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
690
703
  i0.ɵɵrepeater(ctx_r1.SuggestionResult.selectedRelationships);
691
704
  } }
692
705
  function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_For_39_Template(rf, ctx) { if (rf & 1) {
693
- i0.ɵɵelementStart(0, "option", 80);
706
+ i0.ɵɵelementStart(0, "option", 81);
694
707
  i0.ɵɵtext(1);
695
708
  i0.ɵɵelementEnd();
696
709
  } if (rf & 2) {
@@ -700,7 +713,7 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
700
713
  i0.ɵɵtextInterpolate(model_r27.Name);
701
714
  } }
702
715
  function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_For_45_Template(rf, ctx) { if (rf & 1) {
703
- i0.ɵɵelementStart(0, "option", 80);
716
+ i0.ɵɵelementStart(0, "option", 81);
704
717
  i0.ɵɵtext(1);
705
718
  i0.ɵɵelementEnd();
706
719
  } if (rf & 2) {
@@ -710,7 +723,7 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
710
723
  i0.ɵɵtextInterpolate(db_r28.Name);
711
724
  } }
712
725
  function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Conditional_49_For_4_Template(rf, ctx) { if (rf & 1) {
713
- i0.ɵɵelementStart(0, "option", 80);
726
+ i0.ɵɵelementStart(0, "option", 81);
714
727
  i0.ɵɵtext(1);
715
728
  i0.ɵɵelementEnd();
716
729
  } if (rf & 2) {
@@ -721,32 +734,32 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
721
734
  } }
722
735
  function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Conditional_49_Template(rf, ctx) { if (rf & 1) {
723
736
  const _r29 = i0.ɵɵgetCurrentView();
724
- i0.ɵɵelementStart(0, "select", 79);
725
- i0.ɵɵtwoWayListener("ngModelChange", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Conditional_49_Template_select_ngModelChange_0_listener($event) { i0.ɵɵrestoreView(_r29); const ctx_r1 = i0.ɵɵnextContext(5); i0.ɵɵtwoWayBindingSet(ctx_r1.SelectedVectorIndexID, $event) || (ctx_r1.SelectedVectorIndexID = $event); return i0.ɵɵresetView($event); });
726
- i0.ɵɵelementStart(1, "option", 89);
737
+ i0.ɵɵelementStart(0, "select", 80);
738
+ i0.ɵɵlistener("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); return i0.ɵɵresetView(ctx_r1.OnSuggestVectorIndexChange($event)); });
739
+ i0.ɵɵelementStart(1, "option", 90);
727
740
  i0.ɵɵtext(2, "Auto (create/find matching index)");
728
741
  i0.ɵɵelementEnd();
729
- i0.ɵɵrepeaterCreate(3, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Conditional_49_For_4_Template, 2, 2, "option", 80, _forTrack2);
742
+ i0.ɵɵrepeaterCreate(3, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Conditional_49_For_4_Template, 2, 2, "option", 81, _forTrack2);
730
743
  i0.ɵɵelementEnd();
731
744
  } if (rf & 2) {
732
745
  const ctx_r1 = i0.ɵɵnextContext(5);
733
- i0.ɵɵtwoWayProperty("ngModel", ctx_r1.SelectedVectorIndexID);
746
+ i0.ɵɵproperty("ngModel", ctx_r1.SelectedVectorIndexID);
734
747
  i0.ɵɵadvance(3);
735
748
  i0.ɵɵrepeater(ctx_r1.FilteredIndexesForSelectedDB);
736
749
  } }
737
750
  function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Conditional_50_Template(rf, ctx) { if (rf & 1) {
738
- i0.ɵɵelementStart(0, "span", 82);
751
+ i0.ɵɵelementStart(0, "span", 83);
739
752
  i0.ɵɵtext(1, " No indexes yet \u2014 create one in Configuration > Vector Database, or one will be created on sync ");
740
753
  i0.ɵɵelementEnd();
741
754
  } }
742
755
  function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Conditional_52_Template(rf, ctx) { if (rf & 1) {
743
756
  i0.ɵɵelementStart(0, "div", 145);
744
- i0.ɵɵelement(1, "mj-loading", 86);
757
+ i0.ɵɵelement(1, "mj-loading", 87);
745
758
  i0.ɵɵelementEnd();
746
759
  } }
747
760
  function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Conditional_53_Template(rf, ctx) { if (rf & 1) {
748
761
  const _r31 = i0.ɵɵgetCurrentView();
749
- i0.ɵɵelementStart(0, "button", 90);
762
+ i0.ɵɵelementStart(0, "button", 91);
750
763
  i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Conditional_53_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r31); const ctx_r1 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r1.SaveAsEntityDocument()); });
751
764
  i0.ɵɵelement(1, "i", 149);
752
765
  i0.ɵɵtext(2, " Save as Entity Document ");
@@ -756,24 +769,24 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
756
769
  i0.ɵɵelement(4, "i", 151);
757
770
  i0.ɵɵtext(5, " Try Again ");
758
771
  i0.ɵɵelementEnd();
759
- i0.ɵɵelementStart(6, "button", 94);
772
+ i0.ɵɵelementStart(6, "button", 95);
760
773
  i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Conditional_53_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r31); const ctx_r1 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r1.CloseSuggestDialog()); });
761
774
  i0.ɵɵtext(7, " Close ");
762
775
  i0.ɵɵelementEnd();
763
776
  } }
764
777
  function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Template(rf, ctx) { if (rf & 1) {
765
778
  const _r24 = i0.ɵɵgetCurrentView();
766
- i0.ɵɵelementStart(0, "div", 110)(1, "div", 136)(2, "h4", 137);
779
+ i0.ɵɵelementStart(0, "div", 111)(1, "div", 136)(2, "h4", 137);
767
780
  i0.ɵɵtext(3, "Suggested Template");
768
781
  i0.ɵɵelementEnd();
769
- i0.ɵɵelementStart(4, "div", 76)(5, "mj-code-editor", 77);
782
+ i0.ɵɵelementStart(4, "div", 77)(5, "mj-code-editor", 78);
770
783
  i0.ɵɵlistener("change", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Template_mj_code_editor_change_5_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.OnTemplateChange($event)); });
771
784
  i0.ɵɵelementEnd()()();
772
785
  i0.ɵɵelementStart(6, "div", 136)(7, "h4", 137);
773
786
  i0.ɵɵtext(8, "Selected Fields");
774
787
  i0.ɵɵelementEnd();
775
- i0.ɵɵelementStart(9, "div", 87);
776
- i0.ɵɵrepeaterCreate(10, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_For_11_Template, 2, 1, "span", 88, i0.ɵɵrepeaterTrackByIdentity);
788
+ i0.ɵɵelementStart(9, "div", 88);
789
+ i0.ɵɵrepeaterCreate(10, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_For_11_Template, 2, 1, "span", 89, i0.ɵɵrepeaterTrackByIdentity);
777
790
  i0.ɵɵelementEnd()();
778
791
  i0.ɵɵconditionalCreate(12, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Conditional_12_Template, 5, 0, "div", 136);
779
792
  i0.ɵɵelementStart(13, "div", 138)(14, "div", 139)(15, "span", 140);
@@ -794,30 +807,30 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
794
807
  i0.ɵɵelementStart(27, "p", 142);
795
808
  i0.ɵɵtext(28);
796
809
  i0.ɵɵelementEnd()();
797
- i0.ɵɵelementStart(29, "div", 136)(30, "div", 71)(31, "label", 72);
810
+ i0.ɵɵelementStart(29, "div", 136)(30, "div", 72)(31, "label", 73);
798
811
  i0.ɵɵtext(32, "Document Name");
799
812
  i0.ɵɵelementEnd();
800
- i0.ɵɵelementStart(33, "input", 78);
813
+ i0.ɵɵelementStart(33, "input", 79);
801
814
  i0.ɵɵtwoWayListener("ngModelChange", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Template_input_ngModelChange_33_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r1 = i0.ɵɵnextContext(4); i0.ɵɵtwoWayBindingSet(ctx_r1.SaveDocumentName, $event) || (ctx_r1.SaveDocumentName = $event); return i0.ɵɵresetView($event); });
802
815
  i0.ɵɵelementEnd()();
803
- i0.ɵɵelementStart(34, "div", 143)(35, "label", 72);
816
+ i0.ɵɵelementStart(34, "div", 143)(35, "label", 73);
804
817
  i0.ɵɵtext(36, "Embedding Model");
805
818
  i0.ɵɵelementEnd();
806
- i0.ɵɵelementStart(37, "select", 79);
807
- i0.ɵɵtwoWayListener("ngModelChange", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Template_select_ngModelChange_37_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r1 = i0.ɵɵnextContext(4); i0.ɵɵtwoWayBindingSet(ctx_r1.SelectedEmbeddingModelID, $event) || (ctx_r1.SelectedEmbeddingModelID = $event); return i0.ɵɵresetView($event); });
808
- i0.ɵɵrepeaterCreate(38, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_For_39_Template, 2, 2, "option", 80, _forTrack2);
819
+ i0.ɵɵelementStart(37, "select", 80);
820
+ i0.ɵɵlistener("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); return i0.ɵɵresetView(ctx_r1.OnSuggestEmbeddingModelChange($event)); });
821
+ i0.ɵɵrepeaterCreate(38, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_For_39_Template, 2, 2, "option", 81, _forTrack2);
809
822
  i0.ɵɵelementEnd()();
810
- i0.ɵɵelementStart(40, "div", 143)(41, "label", 72);
823
+ i0.ɵɵelementStart(40, "div", 143)(41, "label", 73);
811
824
  i0.ɵɵtext(42, "Vector Database");
812
825
  i0.ɵɵelementEnd();
813
- i0.ɵɵelementStart(43, "select", 79);
814
- i0.ɵɵtwoWayListener("ngModelChange", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Template_select_ngModelChange_43_listener($event) { i0.ɵɵrestoreView(_r24); const ctx_r1 = i0.ɵɵnextContext(4); i0.ɵɵtwoWayBindingSet(ctx_r1.SelectedVectorDBID, $event) || (ctx_r1.SelectedVectorDBID = $event); return i0.ɵɵresetView($event); });
815
- i0.ɵɵrepeaterCreate(44, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_For_45_Template, 2, 2, "option", 80, _forTrack2);
826
+ i0.ɵɵelementStart(43, "select", 80);
827
+ i0.ɵɵlistener("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); return i0.ɵɵresetView(ctx_r1.OnSuggestVectorDBChange($event)); });
828
+ i0.ɵɵrepeaterCreate(44, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_For_45_Template, 2, 2, "option", 81, _forTrack2);
816
829
  i0.ɵɵelementEnd()();
817
- i0.ɵɵelementStart(46, "div", 143)(47, "label", 72);
830
+ i0.ɵɵelementStart(46, "div", 143)(47, "label", 73);
818
831
  i0.ɵɵtext(48, "Vector Index");
819
832
  i0.ɵɵelementEnd();
820
- i0.ɵɵconditionalCreate(49, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Conditional_49_Template, 5, 1, "select", 81)(50, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Conditional_50_Template, 2, 0, "span", 82);
833
+ i0.ɵɵconditionalCreate(49, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Conditional_49_Template, 5, 1, "select", 82)(50, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Conditional_50_Template, 2, 0, "span", 83);
821
834
  i0.ɵɵelementEnd()();
822
835
  i0.ɵɵelementStart(51, "div", 144);
823
836
  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);
@@ -839,11 +852,11 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
839
852
  i0.ɵɵadvance(5);
840
853
  i0.ɵɵtwoWayProperty("ngModel", ctx_r1.SaveDocumentName);
841
854
  i0.ɵɵadvance(4);
842
- i0.ɵɵtwoWayProperty("ngModel", ctx_r1.SelectedEmbeddingModelID);
855
+ i0.ɵɵproperty("ngModel", ctx_r1.SelectedEmbeddingModelID);
843
856
  i0.ɵɵadvance();
844
857
  i0.ɵɵrepeater(ctx_r1.AvailableEmbeddingModels);
845
858
  i0.ɵɵadvance(5);
846
- i0.ɵɵtwoWayProperty("ngModel", ctx_r1.SelectedVectorDBID);
859
+ i0.ɵɵproperty("ngModel", ctx_r1.SelectedVectorDBID);
847
860
  i0.ɵɵadvance();
848
861
  i0.ɵɵrepeater(ctx_r1.vectorDatabases);
849
862
  i0.ɵɵadvance(5);
@@ -853,20 +866,20 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Condition
853
866
  } }
854
867
  function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Template(rf, ctx) { if (rf & 1) {
855
868
  const _r18 = i0.ɵɵgetCurrentView();
856
- i0.ɵɵelementStart(0, "div", 63);
869
+ i0.ɵɵelementStart(0, "div", 64);
857
870
  i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r18); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.CloseSuggestDialog()); });
858
- i0.ɵɵelementStart(1, "div", 109);
871
+ i0.ɵɵelementStart(1, "div", 110);
859
872
  i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Template_div_click_1_listener($event) { return $event.stopPropagation(); });
860
- i0.ɵɵelementStart(2, "div", 65)(3, "h3", 66);
873
+ i0.ɵɵelementStart(2, "div", 66)(3, "h3", 67);
861
874
  i0.ɵɵelement(4, "i", 19);
862
875
  i0.ɵɵtext(5, " AI Document Suggestion ");
863
876
  i0.ɵɵelementEnd();
864
- i0.ɵɵelementStart(6, "button", 67);
877
+ i0.ɵɵelementStart(6, "button", 68);
865
878
  i0.ɵɵlistener("click", function VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r18); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.CloseSuggestDialog()); });
866
- i0.ɵɵelement(7, "i", 68);
879
+ i0.ɵɵelement(7, "i", 69);
867
880
  i0.ɵɵelementEnd()();
868
- i0.ɵɵelementStart(8, "div", 69);
869
- i0.ɵɵconditionalCreate(9, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_9_Template, 27, 11, "div", 70)(10, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Template, 54, 12, "div", 110);
881
+ i0.ɵɵelementStart(8, "div", 70);
882
+ i0.ɵɵconditionalCreate(9, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_9_Template, 24, 9, "div", 71)(10, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Conditional_10_Template, 54, 12, "div", 111);
870
883
  i0.ɵɵelementEnd()()();
871
884
  } if (rf & 2) {
872
885
  const ctx_r1 = i0.ɵɵnextContext(3);
@@ -895,7 +908,7 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Template(
895
908
  i0.ɵɵelement(16, "i", 22);
896
909
  i0.ɵɵtext(17, " Refresh ");
897
910
  i0.ɵɵelementEnd()()();
898
- i0.ɵɵconditionalCreate(18, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_18_Template, 1, 0, "mj-empty-state", 23)(19, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_19_Template, 19, 0, "div", 24);
911
+ i0.ɵɵconditionalCreate(18, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_18_Template, 1, 0, "mj-empty-state", 23)(19, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_19_Template, 21, 0, "div", 24);
899
912
  i0.ɵɵelementEnd();
900
913
  i0.ɵɵelementStart(20, "div", 25)(21, "div", 26)(22, "h4", 27);
901
914
  i0.ɵɵelement(23, "i", 28);
@@ -937,7 +950,7 @@ function VectorManagementResourceComponent_ng_template_2_Conditional_1_Template(
937
950
  i0.ɵɵtext(53);
938
951
  i0.ɵɵpipe(54, "number");
939
952
  i0.ɵɵelementEnd()()()()();
940
- i0.ɵɵconditionalCreate(55, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Template, 57, 13, "div", 45);
953
+ i0.ɵɵconditionalCreate(55, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_55_Template, 62, 14, "div", 45);
941
954
  i0.ɵɵconditionalCreate(56, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_56_Template, 34, 5, "div", 45);
942
955
  i0.ɵɵconditionalCreate(57, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_57_Template, 14, 0, "div", 45);
943
956
  i0.ɵɵconditionalCreate(58, VectorManagementResourceComponent_ng_template_2_Conditional_1_Conditional_58_Template, 11, 3, "div", 45);
@@ -985,10 +998,16 @@ function VectorManagementResourceComponent_ng_template_2_Template(rf, ctx) { if
985
998
  i0.ɵɵconditional(ctx_r1.IsLoading ? 0 : 1);
986
999
  } }
987
1000
  let VectorManagementResourceComponent = class VectorManagementResourceComponent extends BaseResourceComponent {
1001
+ static { VectorManagementResourceComponent_1 = this; }
988
1002
  cdr = inject(ChangeDetectorRef);
989
1003
  activityService = inject(ActivityService);
990
1004
  navigationService = inject(NavigationService);
991
1005
  destroy$ = new Subject();
1006
+ /**
1007
+ * How long a sync may go without a progress event before the tab stops waiting. Reaching it does
1008
+ * not mean the sync finished (see subscribeToPipelineProgress).
1009
+ */
1010
+ static SYNC_SILENCE_LIMIT_MS = 2 * 60 * 1000;
992
1011
  /** View mode: 'index' = Option A (shared index as hero, entity docs as children),
993
1012
  * 'operations' = Option C (operations monitoring with real-time sync status) */
994
1013
  ViewMode = 'index';
@@ -1033,6 +1052,8 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
1033
1052
  EditDocVectorIndexID = '';
1034
1053
  EditDocStatus = '';
1035
1054
  EditDocTemplate = '';
1055
+ /** Entity Document Type of the document being edited. Fixed at creation, shown read-only. */
1056
+ EditDocType = '';
1036
1057
  IsEditRegenerating = false;
1037
1058
  /** Parse {{ FieldName }} patterns from the edit panel's template */
1038
1059
  get EditDocSelectedFields() {
@@ -1057,6 +1078,7 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
1057
1078
  this.EditDocAIModelID = doc.AIModelID ?? '';
1058
1079
  this.EditDocVectorIndexID = doc.VectorIndexID || '';
1059
1080
  this.EditDocStatus = doc.Status;
1081
+ this.EditDocType = doc.Type || '';
1060
1082
  this.EditDocTemplate = '';
1061
1083
  this.IsEditRegenerating = false;
1062
1084
  this.ShowEditPanel = true;
@@ -1107,8 +1129,10 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
1107
1129
  doc.AIModelID = aiModelID;
1108
1130
  // "Auto (create/find matching index)" resolves to a real index for this DB + model, so the
1109
1131
  // syncer always has one to write into; without both parts there is nothing to match.
1110
- doc.VectorIndexID = this.EditDocVectorIndexID
1111
- ? this.EditDocVectorIndexID
1132
+ // A chosen index counts only when it matches the database and model shown.
1133
+ const chosenIndex = ChosenIndexForSave(this.editSelection, this.AvailableVectorIndexes);
1134
+ doc.VectorIndexID = chosenIndex
1135
+ ? chosenIndex.ID
1112
1136
  : (vectorDatabaseID && aiModelID
1113
1137
  ? await this.resolveOrCreateVectorIndex(vectorDatabaseID, aiModelID, this.EditDocEntityName)
1114
1138
  : null);
@@ -1162,10 +1186,17 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
1162
1186
  async RegenerateTemplate() {
1163
1187
  if (!this.EditDocEntityName || this.IsEditRegenerating)
1164
1188
  return;
1189
+ // Ask for the use case this document's type stands for, so the regenerated template
1190
+ // still matches the type. Refuse rather than fall back to another use case.
1191
+ const useCase = SuggestionUseCaseForDocumentType(this.EditDocType);
1192
+ if (!useCase) {
1193
+ MJNotificationService.Instance.CreateSimpleNotification(`Can't regenerate: documents of type "${this.EditDocType || 'unknown'}" have no AI template use case.`, 'error', 5000);
1194
+ return;
1195
+ }
1165
1196
  this.IsEditRegenerating = true;
1166
1197
  this.cdr.detectChanges();
1167
1198
  try {
1168
- const result = await this.callSuggestionPrompt(this.EditDocEntityName, 'duplicate detection');
1199
+ const result = await this.callSuggestionPrompt(this.EditDocEntityName, useCase);
1169
1200
  if (result) {
1170
1201
  this.EditDocTemplate = result.template;
1171
1202
  MJNotificationService.Instance.CreateSimpleNotification('Template regenerated with AI. Review and save to apply.', 'info', 3000);
@@ -1329,18 +1360,56 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
1329
1360
  AvailableVectorIndexes = [];
1330
1361
  /** Selected vector index ID — if user picks an existing one */
1331
1362
  SelectedVectorIndexID = '';
1332
- /** Indexes filtered by the currently selected vector DB (for create/edit forms) */
1363
+ /**
1364
+ * The indexes the suggestion panel offers: those in the selected database built with the selected
1365
+ * embedding model, so a chosen index can never store a different model than the one shown.
1366
+ */
1333
1367
  get FilteredIndexesForSelectedDB() {
1334
- const dbId = this.SelectedVectorDBID || this.EditDocVectorDBID;
1335
- if (!dbId)
1336
- return this.AvailableVectorIndexes;
1337
- return this.AvailableVectorIndexes.filter(i => i.VectorDatabaseID === dbId);
1368
+ return IndexesForSelection(this.AvailableVectorIndexes, this.SelectedVectorDBID, this.SelectedEmbeddingModelID);
1338
1369
  }
1339
- /** Indexes filtered by the edit panel's selected vector DB */
1370
+ /** The indexes the edit panel offers, matched to its database and embedding model the same way. */
1340
1371
  get EditFilteredIndexes() {
1341
- if (!this.EditDocVectorDBID)
1342
- return this.AvailableVectorIndexes;
1343
- return this.AvailableVectorIndexes.filter(i => i.VectorDatabaseID === this.EditDocVectorDBID);
1372
+ return IndexesForSelection(this.AvailableVectorIndexes, this.EditDocVectorDBID, this.EditDocAIModelID);
1373
+ }
1374
+ /** Suggestion panel: picking an index moves the model and database dropdowns to its values. */
1375
+ OnSuggestVectorIndexChange(indexID) {
1376
+ this.applySuggestSelection(SelectIndex(this.suggestSelection, this.AvailableVectorIndexes, indexID));
1377
+ }
1378
+ /** Suggestion panel: a chosen index from another database goes back to Auto. */
1379
+ OnSuggestVectorDBChange(databaseID) {
1380
+ this.applySuggestSelection(SelectDatabase(this.suggestSelection, this.AvailableVectorIndexes, databaseID));
1381
+ }
1382
+ /** Suggestion panel: a chosen index built with another model goes back to Auto. */
1383
+ OnSuggestEmbeddingModelChange(embeddingModelID) {
1384
+ this.applySuggestSelection(SelectEmbeddingModel(this.suggestSelection, this.AvailableVectorIndexes, embeddingModelID));
1385
+ }
1386
+ /** Edit panel: picking an index moves the model and database dropdowns to its values. */
1387
+ OnEditVectorIndexChange(indexID) {
1388
+ this.applyEditSelection(SelectIndex(this.editSelection, this.AvailableVectorIndexes, indexID));
1389
+ }
1390
+ /** Edit panel: a chosen index from another database goes back to Auto. */
1391
+ OnEditVectorDBChange(databaseID) {
1392
+ this.applyEditSelection(SelectDatabase(this.editSelection, this.AvailableVectorIndexes, databaseID));
1393
+ }
1394
+ /** Edit panel: a chosen index built with another model goes back to Auto. */
1395
+ OnEditEmbeddingModelChange(embeddingModelID) {
1396
+ this.applyEditSelection(SelectEmbeddingModel(this.editSelection, this.AvailableVectorIndexes, embeddingModelID));
1397
+ }
1398
+ get suggestSelection() {
1399
+ return { EmbeddingModelID: this.SelectedEmbeddingModelID, VectorDatabaseID: this.SelectedVectorDBID, VectorIndexID: this.SelectedVectorIndexID };
1400
+ }
1401
+ applySuggestSelection(selection) {
1402
+ this.SelectedEmbeddingModelID = selection.EmbeddingModelID;
1403
+ this.SelectedVectorDBID = selection.VectorDatabaseID;
1404
+ this.SelectedVectorIndexID = selection.VectorIndexID;
1405
+ }
1406
+ get editSelection() {
1407
+ return { EmbeddingModelID: this.EditDocAIModelID, VectorDatabaseID: this.EditDocVectorDBID, VectorIndexID: this.EditDocVectorIndexID };
1408
+ }
1409
+ applyEditSelection(selection) {
1410
+ this.EditDocAIModelID = selection.EmbeddingModelID;
1411
+ this.EditDocVectorDBID = selection.VectorDatabaseID;
1412
+ this.EditDocVectorIndexID = selection.VectorIndexID;
1344
1413
  }
1345
1414
  /** Grouped entity list for the suggestion panel — schemas as groups, entities as items */
1346
1415
  EntityGroups = [];
@@ -1627,11 +1696,19 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
1627
1696
  `;
1628
1697
  let idleTimer = null;
1629
1698
  const activityID = this.activityService.Start('Vector sync', { icon: 'fa-solid fa-cubes', detail: entityName, progress: 0 });
1630
- const finishSync = (success) => {
1699
+ /**
1700
+ * 'success' and 'error' come only from the server's own complete / error events.
1701
+ * 'unconfirmed' is a long silence (a dropped connection, say): the row is refreshed from the
1702
+ * database, but nothing claims the run finished, because the server may still be working.
1703
+ */
1704
+ const finishSync = (outcome) => {
1631
1705
  if (idleTimer)
1632
1706
  clearTimeout(idleTimer);
1633
1707
  rxSub?.unsubscribe();
1634
- this.activityService.Complete(activityID, success ? 'success' : 'error', success ? `${entityName} vectorized` : `Failed for ${entityName}`);
1708
+ const success = outcome !== 'error';
1709
+ this.activityService.Complete(activityID, success ? 'success' : 'error', outcome === 'success' ? `${entityName} vectorized`
1710
+ : outcome === 'error' ? `Failed for ${entityName}`
1711
+ : `${entityName}: no progress received`);
1635
1712
  // Use setTimeout to defer state changes to the next macrotask,
1636
1713
  // avoiding ExpressionChangedAfterItHasBeenCheckedError.
1637
1714
  // (Promise.resolve microtasks run between Angular's check passes
@@ -1639,10 +1716,15 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
1639
1716
  setTimeout(async () => {
1640
1717
  try {
1641
1718
  this.removeSyncingId(entityDocumentId);
1642
- if (success) {
1719
+ if (outcome === 'success') {
1643
1720
  MJNotificationService.Instance.CreateSimpleNotification(`Vectorization complete for ${entityName}`, 'success', 3000);
1644
1721
  await this.refreshSyncRow(entityDocumentId);
1645
1722
  }
1723
+ else if (outcome === 'unconfirmed') {
1724
+ MJNotificationService.Instance.CreateSimpleNotification(`No progress received for ${entityName} in ${VectorManagementResourceComponent_1.SYNC_SILENCE_LIMIT_MS / 60000} minutes, ` +
1725
+ `so the result can't be confirmed. The vector count shown is what is stored now; refresh later to check.`, 'warning', 8000);
1726
+ await this.refreshSyncRow(entityDocumentId);
1727
+ }
1646
1728
  else {
1647
1729
  this.updateRowStatus(entityDocumentId, 'Error');
1648
1730
  MJNotificationService.Instance.CreateSimpleNotification(`Vectorization failed for ${entityName}`, 'error', 5000);
@@ -1658,16 +1740,17 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
1658
1740
  }
1659
1741
  });
1660
1742
  };
1661
- // Reset idle timer on every event. When no events arrive for 5s,
1662
- // assume the pipeline is done (handles missing 'complete' event).
1743
+ // Reset on every event. Silence is not success: the server reports progress in 5% steps,
1744
+ // and with a remote embedding model one step can take far longer than a few seconds, so a
1745
+ // short silence routinely reported "Synced" while most records were still being embedded.
1663
1746
  const resetIdleTimer = () => {
1664
1747
  if (idleTimer)
1665
1748
  clearTimeout(idleTimer);
1666
1749
  idleTimer = setTimeout(() => {
1667
1750
  if (this.IsSyncing(entityDocumentId)) {
1668
- finishSync(true);
1751
+ finishSync('unconfirmed');
1669
1752
  }
1670
- }, 5000);
1753
+ }, VectorManagementResourceComponent_1.SYNC_SILENCE_LIMIT_MS);
1671
1754
  };
1672
1755
  // Start the idle timer immediately in case no events ever arrive
1673
1756
  resetIdleTimer();
@@ -1682,10 +1765,10 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
1682
1765
  this.updateRowProgress(entityDocumentId, pct);
1683
1766
  this.cdr.detectChanges();
1684
1767
  if (stage === 'complete') {
1685
- finishSync(true);
1768
+ finishSync('success');
1686
1769
  }
1687
1770
  else if (stage === 'error') {
1688
- finishSync(false);
1771
+ finishSync('error');
1689
1772
  }
1690
1773
  else {
1691
1774
  // Got a progress event — reset idle timer
@@ -1694,7 +1777,7 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
1694
1777
  },
1695
1778
  error: (err) => {
1696
1779
  console.error(`[VectorManagement] Pipeline subscription error:`, err);
1697
- finishSync(false);
1780
+ finishSync('error');
1698
1781
  }
1699
1782
  });
1700
1783
  }
@@ -1896,6 +1979,15 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
1896
1979
  try {
1897
1980
  const result = await this.callSuggestionPrompt(this.SuggestEntityName, this.SuggestUseCase);
1898
1981
  if (result) {
1982
+ // The field list is whatever the model returned — no cap, no filter. Bound it
1983
+ // here so an over-wide suggestion is visible immediately rather than at save.
1984
+ const capped = CapSelectedFields(result.selectedFields);
1985
+ if (capped.dropped > 0) {
1986
+ MJNotificationService.Instance.CreateSimpleNotification(`The suggestion selected ${capped.fields.length + capped.dropped} fields. ` +
1987
+ `Keeping the first ${MAX_TEMPLATE_FIELDS} and dropping ${capped.dropped} — a list ` +
1988
+ `this long usually means the whole table was pulled in. Check the template.`, 'warning', 6000);
1989
+ }
1990
+ result.selectedFields = capped.fields;
1899
1991
  this.SuggestionResult = result;
1900
1992
  this.EditableTemplate = result.template;
1901
1993
  this.SaveDocumentName = `${this.SuggestEntityName} - ${this.SuggestUseCase}`;
@@ -1920,8 +2012,7 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
1920
2012
  this.cdr.detectChanges();
1921
2013
  try {
1922
2014
  const md = this.ProviderToUse;
1923
- const entityDoc = await md.GetEntityObject('MJ: Entity Documents');
1924
- entityDoc.NewRecord();
2015
+ const entityDoc = await this.findOrCreateEntityDocument();
1925
2016
  entityDoc.Name = this.SaveDocumentName;
1926
2017
  const matchingEntity = md.Entities.find(e => e.Name === this.SuggestEntityName);
1927
2018
  if (matchingEntity) {
@@ -1930,6 +2021,12 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
1930
2021
  entityDoc.Status = 'Active';
1931
2022
  // Populate required FK fields from existing data
1932
2023
  await this.populateEntityDocumentFKs(entityDoc);
2024
+ // The panel shows the model's match thresholds; store them rather than leaving the defaults.
2025
+ const thresholds = SuggestedMatchThresholds(this.SuggestionResult.potentialMatchThreshold, this.SuggestionResult.absoluteMatchThreshold);
2026
+ if (thresholds) {
2027
+ entityDoc.PotentialMatchThreshold = thresholds.Potential;
2028
+ entityDoc.AbsoluteMatchThreshold = thresholds.Absolute;
2029
+ }
1933
2030
  const saved = await entityDoc.Save();
1934
2031
  if (saved) {
1935
2032
  MJNotificationService.Instance.CreateSimpleNotification(`Entity Document "${this.SaveDocumentName}" created successfully`, 'success', 3000);
@@ -2020,8 +2117,10 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
2020
2117
  // hands out its own cached array, which this component must not mutate.
2021
2118
  this.vectorIndexes = [...AIEngineBase.Instance.VectorIndexes];
2022
2119
  // Build per-EntityDocument aggregate stats (vector count + last synced).
2023
- // Each query fetches only the most recent row (MaxRows: 1) and uses
2024
- // TotalRowCount for the actual vector count — avoids loading all rows.
2120
+ // Each query fetches the two most recent rows and uses TotalRowCount for the
2121
+ // vector count, which avoids loading all rows. MaxRows is 2, not 1: a full
2122
+ // `MaxRows: 1` read skips the total count (#4450), so TotalRowCount would be 1.
2123
+ // With 2, a full page triggers the count, and a short page is itself the total.
2025
2124
  // AI Models come from a different domain — fetched in the same batch.
2026
2125
  const rv = RunView.FromMetadataProvider(this.ProviderToUse);
2027
2126
  const erdQueries = this.entityDocuments.map(doc => ({
@@ -2030,7 +2129,7 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
2030
2129
  ResultType: 'simple',
2031
2130
  Fields: ['__mj_UpdatedAt'],
2032
2131
  OrderBy: '__mj_UpdatedAt DESC',
2033
- MaxRows: 1,
2132
+ MaxRows: 2,
2034
2133
  BypassCache: forceRefresh,
2035
2134
  }));
2036
2135
  const allQueries = [
@@ -2069,6 +2168,7 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
2069
2168
  EntityDocumentID: doc.ID,
2070
2169
  EntityName: doc.Entity || '',
2071
2170
  DocumentName: doc.Name,
2171
+ DocumentType: doc.Type || '',
2072
2172
  VectorCount: vectorCount,
2073
2173
  LastSynced: lastSynced,
2074
2174
  Status: status,
@@ -2199,10 +2299,9 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
2199
2299
  VectorDatabaseID: vi.VectorDatabaseID,
2200
2300
  EmbeddingModelID: vi.EmbeddingModelID
2201
2301
  }));
2202
- // Pre-select first index if available
2203
- if (this.AvailableVectorIndexes.length > 0 && !this.SelectedVectorIndexID) {
2204
- this.SelectedVectorIndexID = this.AvailableVectorIndexes[0].ID;
2205
- }
2302
+ // No index is pre-selected: the first index is whatever happens to sort first (here, another
2303
+ // feature's shared index), and a chosen index decides the database and model Save stores.
2304
+ // Auto finds or creates the index for the database and model shown.
2206
2305
  }
2207
2306
  /** Find the best embedding model from loaded AI models */
2208
2307
  findEmbeddingModel() {
@@ -2221,26 +2320,46 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
2221
2320
  missing.push('Embedding Model');
2222
2321
  throw new Error(`Prerequisites not configured: ${missing.join(', ')}. Go to the Configuration tab to set these up.`);
2223
2322
  }
2224
- // TypeID — look up 'Record Duplicate' entity document type
2323
+ // TypeID — from the use case the user actually chose. This used to be hardcoded to
2324
+ // 'Record Duplicate', so picking "search" in the dialog silently produced a
2325
+ // duplicate-detection document: the selection was discarded and the document was the
2326
+ // wrong type. A vector pool is typed — Provider.SearchEntity and the Search Entity
2327
+ // action read Search-typed documents — so the mislabelled document is also invisible
2328
+ // to the feature that asked for it.
2329
+ const wantedTypeName = EntityDocumentTypeForUseCase(this.SuggestUseCase);
2330
+ if (!wantedTypeName) {
2331
+ throw new Error(`No Entity Document Type is defined for the "${this.SuggestUseCase}" use case. ` +
2332
+ `Known use cases: ${Object.keys(ENTITY_DOCUMENT_TYPE_BY_USE_CASE).join(', ')}.`);
2333
+ }
2225
2334
  const rv = RunView.FromMetadataProvider(this.ProviderToUse);
2226
2335
  const typeResult = await rv.RunView({
2227
2336
  EntityName: 'MJ: Entity Document Types',
2228
- ExtraFilter: "Name = 'Record Duplicate'",
2229
2337
  ResultType: 'simple',
2230
- Fields: ['ID']
2338
+ Fields: ['ID', 'Name']
2231
2339
  });
2232
- if (typeResult.Success && typeResult.Results.length > 0) {
2233
- entityDoc.TypeID = typeResult.Results[0].ID;
2340
+ const availableTypes = typeResult.Success ? typeResult.Results : [];
2341
+ // Trimmed, case-insensitive comparison — the same match EntityDocumentCache
2342
+ // .GetDocumentTypeByName makes server-side, so the dialog and the syncer agree.
2343
+ const wanted = wantedTypeName.trim().toLowerCase();
2344
+ const matchedType = availableTypes.find(t => t.Name?.trim().toLowerCase() === wanted);
2345
+ if (matchedType) {
2346
+ entityDoc.TypeID = matchedType.ID;
2234
2347
  }
2235
2348
  else {
2236
- throw new Error('Entity Document Type "Record Duplicate" not found in database');
2349
+ // Never substitute a type that happens to exist: that is the defect above.
2350
+ const names = availableTypes.map(t => t.Name).sort();
2351
+ throw new Error(`Entity Document Type "${wantedTypeName}" not found in database. It is the type the ` +
2352
+ `"${this.SuggestUseCase}" use case needs, and no other type will be used in its place. ` +
2353
+ (names.length > 0
2354
+ ? `Types that do exist: ${names.join(', ')}. Add "${wantedTypeName}" to MJ: Entity Document Types.`
2355
+ : 'No Entity Document Types exist at all.'));
2237
2356
  }
2238
2357
  // An explicitly chosen index fixes the DB + model. "Auto (create/find matching index)" resolves
2239
2358
  // (or creates) the index for the chosen DB + model, so the syncer always has a VectorIndexID:
2240
2359
  // it refuses to run without one, which made the Auto choice a dead end before.
2241
- const chosen = this.SelectedVectorIndexID
2242
- ? this.AvailableVectorIndexes.find(i => UUIDsEqual(i.ID, this.SelectedVectorIndexID))
2243
- : undefined;
2360
+ // Only an index that matches the database and model shown counts as chosen, so the stored
2361
+ // database and model are always the ones the dropdowns displayed.
2362
+ const chosen = ChosenIndexForSave(this.suggestSelection, this.AvailableVectorIndexes);
2244
2363
  if (chosen) {
2245
2364
  entityDoc.VectorDatabaseID = chosen.VectorDatabaseID;
2246
2365
  entityDoc.AIModelID = chosen.EmbeddingModelID;
@@ -2297,12 +2416,33 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
2297
2416
  if (!templateText) {
2298
2417
  throw new Error('No template content to save');
2299
2418
  }
2300
- // Create Template record
2301
- const template = await md.GetEntityObject('MJ: Templates');
2302
- template.NewRecord();
2303
- template.Name = `Template for ${this.SaveDocumentName}`;
2419
+ // LAYER 2: the template is hand-editable after the model returns, so a user can type
2420
+ // a field the picker never offered. Refuse before anything is written — once values
2421
+ // reach the vector index they are retrievable by similarity search, outside the
2422
+ // entity permissions that guard the source column, and not fully reversible.
2423
+ const sensitive = SensitiveFieldsInTemplate(templateText, this.vectorFieldPurpose(this.SuggestUseCase));
2424
+ if (sensitive.length > 0) {
2425
+ throw new Error(`This template references ${sensitive.length === 1 ? 'a field' : 'fields'} that must not be ` +
2426
+ `vectorized: ${sensitive.join(', ')}. Embedding copies the values into the vector index, ` +
2427
+ `where they are retrievable by similarity search rather than by an authorized query. ` +
2428
+ `Remove ${sensitive.length === 1 ? 'it' : 'them'} from the template and save again.`);
2429
+ }
2430
+ // The field list is unbounded and comes straight from a prompt, and the template stays
2431
+ // hand-editable after the model returns — so the authoritative bound is here, on what
2432
+ // actually gets embedded, not on the model's own description of what it picked.
2433
+ const capRefusal = TemplateFieldCapRefusal(templateText);
2434
+ if (capRefusal) {
2435
+ throw new Error(capRefusal);
2436
+ }
2437
+ // Find-or-create, so a retry after a mid-flow failure converges on one set of rows.
2438
+ const templateName = this.templateNameForDocument();
2439
+ const template = await this.findOrCreateTemplate(templateName, entityDoc.TemplateID);
2440
+ template.Name = templateName;
2304
2441
  template.Description = `Auto-generated template for entity document: ${this.SaveDocumentName}`;
2305
- template.UserID = md.CurrentUser.ID;
2442
+ // An adopted template keeps its owner; only a new one is the current user's.
2443
+ if (!template.UserID) {
2444
+ template.UserID = md.CurrentUser.ID;
2445
+ }
2306
2446
  template.IsActive = true;
2307
2447
  const templateSaved = await template.Save();
2308
2448
  if (!templateSaved) {
@@ -2322,8 +2462,7 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
2322
2462
  // Create TemplateContent record with the template text
2323
2463
  // Server-side MJTemplateContentEntityServer hook auto-creates Scalar params
2324
2464
  // for each {{FieldName}} — GetTemplateData() handles them via the flat convention.
2325
- const content = await md.GetEntityObject('MJ: Template Contents');
2326
- content.NewRecord();
2465
+ const content = await this.findOrCreateTemplateContent(template.ID);
2327
2466
  content.TemplateID = template.ID;
2328
2467
  content.TypeID = contentTypeResult.Results[0].ID;
2329
2468
  content.TemplateText = templateText;
@@ -2334,11 +2473,136 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
2334
2473
  throw new Error(`Failed to create template content: ${content.LatestResult?.CompleteMessage || 'unknown error'}`);
2335
2474
  }
2336
2475
  }
2476
+ /** The Template name this dialog deterministically gives the current document. */
2477
+ templateNameForDocument() {
2478
+ return `Template for ${this.SaveDocumentName}`;
2479
+ }
2480
+ /**
2481
+ * The Entity Document for the current dialog, reusing the row an earlier attempt created
2482
+ * rather than adding a second one.
2483
+ *
2484
+ * This flow writes three rows — Template, Template Content, Entity Document — in that
2485
+ * order, and only the last is protected by a unique index (`UQ_EntityDocument_Name` on
2486
+ * `EntityDocument.Name`). So a duplicate was not a rare partial-failure case: that index
2487
+ * guarantees a second attempt with the same name fails at the final step, *after* the
2488
+ * Template and Template Content rows have been written again. Orphans accumulated one
2489
+ * pair per retry.
2490
+ *
2491
+ * Matched on Name, because that is the identity the database itself enforces.
2492
+ *
2493
+ * An existing document is adopted only when this dialog created it — its TemplateID points
2494
+ * at the template named `Template for <document name>` — and only for the same entity, so a
2495
+ * retry never moves another entity's document. A collision with a document
2496
+ * authored anywhere else is refused, because silently overwriting somebody's configured
2497
+ * document is worse than asking for a different name.
2498
+ */
2499
+ async findOrCreateEntityDocument() {
2500
+ const md = this.ProviderToUse;
2501
+ const rv = RunView.FromMetadataProvider(md);
2502
+ const existing = await rv.RunView({
2503
+ EntityName: 'MJ: Entity Documents',
2504
+ ExtraFilter: `Name='${EscapeSQLString(this.SaveDocumentName)}'`,
2505
+ ResultType: 'entity_object',
2506
+ MaxRows: 1,
2507
+ });
2508
+ if (existing.Success && existing.Results.length > 0) {
2509
+ const priorDoc = existing.Results[0];
2510
+ const ownTemplate = priorDoc.TemplateID
2511
+ ? await this.templateHasName(priorDoc.TemplateID, this.templateNameForDocument())
2512
+ : false;
2513
+ if (!ownTemplate) {
2514
+ throw new Error(`An Entity Document named "${this.SaveDocumentName}" already exists and was not ` +
2515
+ `created here, so it will not be overwritten. Choose a different name.`);
2516
+ }
2517
+ // Adopting a document for another entity would move it to this one.
2518
+ const entity = md.Entities.find(e => e.Name === this.SuggestEntityName);
2519
+ if (entity && priorDoc.EntityID && !UUIDsEqual(priorDoc.EntityID, entity.ID)) {
2520
+ throw new Error(`An Entity Document named "${this.SaveDocumentName}" already exists for ` +
2521
+ `${priorDoc.Entity || 'another entity'}, so it will not be reused. Choose a different name.`);
2522
+ }
2523
+ return priorDoc;
2524
+ }
2525
+ const entityDoc = await md.GetEntityObject('MJ: Entity Documents');
2526
+ entityDoc.NewRecord();
2527
+ return entityDoc;
2528
+ }
2529
+ /**
2530
+ * The Template for the current document, reusing an earlier attempt's row.
2531
+ *
2532
+ * An adopted Entity Document already points at its template (findOrCreateEntityDocument
2533
+ * checked its name), so that row is reused by ID. Matching it on Name + UserID instead
2534
+ * misses it when another user created it, writes a second template, re-points the document
2535
+ * and orphans the first Template and Template Content.
2536
+ *
2537
+ * For a new document, matched on Name + UserID: `Template` carries no unique index, and that
2538
+ * pair is exactly what this flow writes, so it identifies our own prior row without claiming
2539
+ * anyone else's.
2540
+ */
2541
+ async findOrCreateTemplate(templateName, adoptedTemplateId) {
2542
+ const md = this.ProviderToUse;
2543
+ const rv = RunView.FromMetadataProvider(md);
2544
+ const existing = await rv.RunView({
2545
+ EntityName: 'MJ: Templates',
2546
+ ExtraFilter: adoptedTemplateId
2547
+ ? `ID='${EscapeSQLString(adoptedTemplateId)}'`
2548
+ : `Name='${EscapeSQLString(templateName)}' AND UserID='${md.CurrentUser.ID}'`,
2549
+ ResultType: 'entity_object',
2550
+ MaxRows: 1,
2551
+ });
2552
+ if (existing.Success && existing.Results.length > 0) {
2553
+ return existing.Results[0];
2554
+ }
2555
+ const template = await md.GetEntityObject('MJ: Templates');
2556
+ template.NewRecord();
2557
+ return template;
2558
+ }
2559
+ /**
2560
+ * The Template Content row for a template, reusing the one it already has.
2561
+ *
2562
+ * `Priority ASC`, first row, is how loadEditDocTemplate and saveEditDocTemplate already
2563
+ * identify "the" content of a template — this follows that convention rather than adding
2564
+ * a second one.
2565
+ */
2566
+ async findOrCreateTemplateContent(templateId) {
2567
+ const md = this.ProviderToUse;
2568
+ const rv = RunView.FromMetadataProvider(md);
2569
+ const existing = await rv.RunView({
2570
+ EntityName: 'MJ: Template Contents',
2571
+ ExtraFilter: `TemplateID='${templateId}'`,
2572
+ ResultType: 'entity_object',
2573
+ OrderBy: 'Priority ASC',
2574
+ MaxRows: 1,
2575
+ });
2576
+ if (existing.Success && existing.Results.length > 0) {
2577
+ return existing.Results[0];
2578
+ }
2579
+ const content = await md.GetEntityObject('MJ: Template Contents');
2580
+ content.NewRecord();
2581
+ return content;
2582
+ }
2583
+ /** True when the template with this ID carries the given name. */
2584
+ async templateHasName(templateId, name) {
2585
+ const rv = RunView.FromMetadataProvider(this.ProviderToUse);
2586
+ const result = await rv.RunView({
2587
+ EntityName: 'MJ: Templates',
2588
+ ExtraFilter: `ID='${templateId}'`,
2589
+ Fields: ['Name'],
2590
+ ResultType: 'simple',
2591
+ MaxRows: 1,
2592
+ });
2593
+ return result.Success && result.Results.length > 0 && result.Results[0].Name === name;
2594
+ }
2337
2595
  /** Build grouped entity list from metadata, grouped by SchemaName */
2338
2596
  loadEntityGroups() {
2339
2597
  const md = this.ProviderToUse;
2340
2598
  const groupMap = new Map();
2341
2599
  for (const entity of md.Entities) {
2600
+ // The picker used to list every entity in metadata, so MJ's own internal entities
2601
+ // were offered as vectorization targets. See vector-document-rules.ts for the rule
2602
+ // and the precedent it follows.
2603
+ if (!IsVectorizableEntity(entity)) {
2604
+ continue;
2605
+ }
2342
2606
  const schema = entity.SchemaName || '__default';
2343
2607
  const existing = groupMap.get(schema);
2344
2608
  if (existing) {
@@ -2451,9 +2715,19 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
2451
2715
  }
2452
2716
  return prompt;
2453
2717
  }
2718
+ /**
2719
+ * What a document for this use case embeds its fields for. Only a duplicate-detection document
2720
+ * may embed a date of birth (see sensitive-fields.ts).
2721
+ */
2722
+ vectorFieldPurpose(useCase) {
2723
+ return EntityDocumentTypeForUseCase(useCase) === 'Record Duplicate' ? 'duplicate-detection' : 'other';
2724
+ }
2454
2725
  /** Build the data payload for the suggestion prompt */
2455
2726
  buildPromptData(entity, useCase) {
2456
- const fields = entity.Fields.map(f => ({
2727
+ // LAYER 1 of the sensitive-field refusal: the model never sees these columns, so it
2728
+ // cannot suggest them. See sensitive-fields.ts for why this cannot live in the prompt.
2729
+ const purpose = this.vectorFieldPurpose(useCase);
2730
+ const fields = WithoutSensitiveFields(entity.Fields, purpose).map(f => ({
2457
2731
  Name: f.Name,
2458
2732
  Type: f.Type,
2459
2733
  IsPrimaryKey: f.IsPrimaryKey,
@@ -2468,8 +2742,9 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
2468
2742
  .slice(0, 20)
2469
2743
  .map(r => {
2470
2744
  const relatedEntity = md.Entities.find(e => e.Name === r.RelatedEntity);
2745
+ // Layer 1 covers related entities too: their fields reach the model here.
2471
2746
  const relFields = relatedEntity
2472
- ? relatedEntity.Fields
2747
+ ? WithoutSensitiveFields(relatedEntity.Fields, purpose)
2473
2748
  .filter(f => !f.IsPrimaryKey && f.Type !== 'datetimeoffset')
2474
2749
  .map(f => f.Name)
2475
2750
  : [];
@@ -2493,7 +2768,7 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
2493
2768
  } if (rf & 2) {
2494
2769
  let _t;
2495
2770
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.EntitySearchInput = _t.first);
2496
- } }, inputs: { HideToolbar: "HideToolbar" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 4, vars: 2, consts: [["vectorBody", ""], ["entitySearchInput", ""], ["Title", "Vector Management", "Icon", "fa-solid fa-cubes", "Subtitle", "Vector index health, embeddings, and entity sync status"], ["actions", ""], [3, "KeyChange", "Options", "ActiveKey"], [3, "Flex"], [4, "ngTemplateOutlet"], [1, "vector-loading"], ["text", "Loading vector management data..."], [1, "vector-dashboard"], [1, "kpi-row"], [3, "data"], [1, "content-area"], [1, "sync-table-panel"], [1, "panel-header"], [1, "panel-title"], [1, "fa-solid", "fa-table-list"], [1, "panel-actions"], ["title", "Use AI to suggest an Entity Document template", 1, "suggest-btn", 3, "click"], [1, "fa-solid", "fa-wand-magic-sparkles"], [1, "suggest-btn-text"], ["title", "Refresh data", 1, "refresh-btn", 3, "click"], [1, "fa-solid", "fa-arrows-rotate"], ["Icon", "fa-solid fa-folder-open", "Title", "No entity documents configured for vectorization."], [1, "table-wrapper"], [1, "sidebar"], [1, "sidebar-card"], [1, "sidebar-title"], [1, "fa-solid", "fa-heart-pulse"], [1, "health-row"], [1, "health-dot"], [1, "health-label"], [1, "health-status", 3, "title"], [1, "health-reason"], [1, "fa-solid", "fa-microchip"], [1, "model-info"], [1, "info-row"], [1, "info-label"], [1, "info-value", 3, "title"], [1, "fa-solid", "fa-hard-drive"], [1, "gauge-container"], [1, "gauge-bar"], [1, "gauge-fill"], [1, "gauge-label"], [1, "storage-detail"], [1, "slide-panel-overlay"], [1, "sync-table"], [1, "text-right"], [1, "text-center"], [1, "entity-name"], [1, "document-name"], [1, "text-right", "vector-count"], [1, "last-synced"], [1, "status-badge"], [1, "text-center", "actions-cell"], ["title", "Sync now", 1, "sync-btn", 3, "click", "disabled"], ["title", "Schedule recurring sync", 1, "schedule-btn", 3, "click"], [1, "fa-regular", "fa-clock"], ["title", "Edit entity document", 1, "edit-btn", 3, "click"], [1, "fa-solid", "fa-pen"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "fa-solid", "fa-play"], [1, "info-value"], [1, "slide-panel-overlay", 3, "click"], [1, "slide-panel", "open", 3, "click"], [1, "suggest-dialog-header"], [1, "suggest-dialog-title"], [1, "suggest-close-btn", 3, "click"], [1, "fa-solid", "fa-times"], [1, "suggest-dialog-body"], [1, "suggest-form"], [1, "suggest-field"], [1, "suggest-label"], [1, "edit-readonly-value"], [1, "edit-template-header"], ["title", "Regenerate template using AI", 1, "edit-regenerate-btn", 3, "click", "disabled"], [1, "template-editor-wrapper"], ["language", "markdown", 3, "change", "value", "readonly", "lineWrapping"], ["type", "text", 1, "suggest-input", 3, "ngModelChange", "ngModel"], [1, "suggest-select", 3, "ngModelChange", "ngModel"], [3, "value"], [1, "suggest-select", 3, "ngModel"], [1, "edit-readonly-value", 2, "font-size", "13px", "color", "var(--mj-text-muted)"], ["value", "Active"], ["value", "Inactive"], [1, "result-actions", 2, "margin-top", "1rem"], ["text", "Saving...", "size", "small"], [1, "result-tags"], [1, "result-tag"], ["value", ""], [1, "suggest-submit-btn", 3, "click"], [1, "fa-solid", "fa-save"], [1, "edit-delete-btn", 3, "click"], [1, "fa-solid", "fa-trash-can"], [1, "suggest-close-action", 3, "click"], [1, "schedule-dialog", 3, "click"], ["type", "text", "placeholder", "0 2 * * *", 1, "suggest-input", 3, "ngModelChange", "ngModel"], [1, "schedule-cron-preview"], [1, "fa-solid", "fa-info-circle"], [1, "suggest-field", "schedule-toggle-row"], ["type", "checkbox", 1, "mj-checkbox", 3, "ngModelChange", "ngModel"], [1, "fa-solid", "fa-check"], [1, "no-index-warning-dialog", 3, "click"], [1, "no-index-warning-icon"], [1, "fa-solid", "fa-triangle-exclamation"], [1, "no-index-warning-title"], [1, "no-index-warning-message"], [1, "no-index-warning-actions"], [1, "fa-solid", "fa-gear"], [1, "slide-panel", 3, "click"], [1, "suggest-result"], [1, "entity-picker"], [1, "entity-picker-trigger", 3, "click"], [1, "fa-solid", "fa-chevron-down", "entity-picker-arrow"], [1, "entity-picker-dropdown"], [1, "use-case-options"], [1, "use-case-btn", 3, "click"], [1, "fa-solid", "fa-clone"], [1, "fa-solid", "fa-magnifying-glass"], [1, "fa-solid", "fa-tags"], [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) {
2771
+ } }, inputs: { HideToolbar: "HideToolbar" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 4, vars: 2, consts: [["vectorBody", ""], ["entitySearchInput", ""], ["Title", "Vector Management", "Icon", "fa-solid fa-cubes", "Subtitle", "Vector index health, embeddings, and entity sync status"], ["actions", ""], [3, "KeyChange", "Options", "ActiveKey"], [3, "Flex"], [4, "ngTemplateOutlet"], [1, "vector-loading"], ["text", "Loading vector management data..."], [1, "vector-dashboard"], [1, "kpi-row"], [3, "data"], [1, "content-area"], [1, "sync-table-panel"], [1, "panel-header"], [1, "panel-title"], [1, "fa-solid", "fa-table-list"], [1, "panel-actions"], ["title", "Use AI to suggest an Entity Document template", 1, "suggest-btn", 3, "click"], [1, "fa-solid", "fa-wand-magic-sparkles"], [1, "suggest-btn-text"], ["title", "Refresh data", 1, "refresh-btn", 3, "click"], [1, "fa-solid", "fa-arrows-rotate"], ["Icon", "fa-solid fa-folder-open", "Title", "No entity documents configured for vectorization."], [1, "table-wrapper"], [1, "sidebar"], [1, "sidebar-card"], [1, "sidebar-title"], [1, "fa-solid", "fa-heart-pulse"], [1, "health-row"], [1, "health-dot"], [1, "health-label"], [1, "health-status", 3, "title"], [1, "health-reason"], [1, "fa-solid", "fa-microchip"], [1, "model-info"], [1, "info-row"], [1, "info-label"], [1, "info-value", 3, "title"], [1, "fa-solid", "fa-hard-drive"], [1, "gauge-container"], [1, "gauge-bar"], [1, "gauge-fill"], [1, "gauge-label"], [1, "storage-detail"], [1, "slide-panel-overlay"], [1, "sync-table"], [1, "text-right"], [1, "text-center"], [1, "entity-name"], [1, "document-name"], [1, "document-type"], [1, "text-right", "vector-count"], [1, "last-synced"], [1, "status-badge"], [1, "text-center", "actions-cell"], ["title", "Sync now", 1, "sync-btn", 3, "click", "disabled"], ["title", "Schedule recurring sync", 1, "schedule-btn", 3, "click"], [1, "fa-regular", "fa-clock"], ["title", "Edit entity document", 1, "edit-btn", 3, "click"], [1, "fa-solid", "fa-pen"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "fa-solid", "fa-play"], [1, "info-value"], [1, "slide-panel-overlay", 3, "click"], [1, "slide-panel", "open", 3, "click"], [1, "suggest-dialog-header"], [1, "suggest-dialog-title"], [1, "suggest-close-btn", 3, "click"], [1, "fa-solid", "fa-times"], [1, "suggest-dialog-body"], [1, "suggest-form"], [1, "suggest-field"], [1, "suggest-label"], [1, "edit-readonly-value"], [1, "edit-template-header"], ["title", "Regenerate template using AI", 1, "edit-regenerate-btn", 3, "click", "disabled"], [1, "template-editor-wrapper"], ["language", "markdown", 3, "change", "value", "readonly", "lineWrapping"], ["type", "text", 1, "suggest-input", 3, "ngModelChange", "ngModel"], [1, "suggest-select", 3, "ngModelChange", "ngModel"], [3, "value"], [1, "suggest-select", 3, "ngModel"], [1, "edit-readonly-value", 2, "font-size", "13px", "color", "var(--mj-text-muted)"], ["value", "Active"], ["value", "Inactive"], [1, "result-actions", 2, "margin-top", "1rem"], ["text", "Saving...", "size", "small"], [1, "result-tags"], [1, "result-tag"], ["value", ""], [1, "suggest-submit-btn", 3, "click"], [1, "fa-solid", "fa-save"], [1, "edit-delete-btn", 3, "click"], [1, "fa-solid", "fa-trash-can"], [1, "suggest-close-action", 3, "click"], [1, "schedule-dialog", 3, "click"], ["type", "text", "placeholder", "0 2 * * *", 1, "suggest-input", 3, "ngModelChange", "ngModel"], [1, "schedule-cron-preview"], [1, "fa-solid", "fa-info-circle"], [1, "suggest-field", "schedule-toggle-row"], ["type", "checkbox", 1, "mj-checkbox", 3, "ngModelChange", "ngModel"], [1, "fa-solid", "fa-check"], [1, "no-index-warning-dialog", 3, "click"], [1, "no-index-warning-icon"], [1, "fa-solid", "fa-triangle-exclamation"], [1, "no-index-warning-title"], [1, "no-index-warning-message"], [1, "no-index-warning-actions"], [1, "fa-solid", "fa-gear"], [1, "slide-panel", 3, "click"], [1, "suggest-result"], [1, "entity-picker"], [1, "entity-picker-trigger", 3, "click"], [1, "fa-solid", "fa-chevron-down", "entity-picker-arrow"], [1, "entity-picker-dropdown"], [1, "use-case-options"], [1, "use-case-btn", 3, "click"], [1, "fa-solid", "fa-clone"], [1, "fa-solid", "fa-magnifying-glass"], [1, "suggest-submit-btn", 3, "click", "disabled"], ["Variant", "error", "Size", "sm"], [1, "fa-solid", "fa-table"], [1, "entity-picker-value"], [1, "fa-solid", "fa-search"], [1, "entity-picker-placeholder"], [1, "entity-picker-dropdown", 3, "mousedown"], [1, "entity-picker-search"], ["type", "text", "placeholder", "Filter entities...", 1, "entity-picker-search-input", 3, "ngModelChange", "input", "keydown", "ngModel"], [1, "entity-picker-list"], [1, "entity-picker-group"], [1, "entity-picker-empty"], [1, "entity-picker-group-header"], [1, "fa-solid", "fa-database"], [1, "entity-picker-item", 3, "entity-picker-item-selected", "entity-picker-item-focused"], [1, "entity-picker-item", 3, "click"], [1, "result-section"], [1, "result-heading"], [1, "result-section", "result-thresholds"], [1, "threshold-item"], [1, "threshold-label"], [1, "threshold-value"], [1, "result-reasoning"], [1, "suggest-field", 2, "margin-top", "0.75rem"], [1, "result-actions"], [1, "save-spinner"], [1, "result-relationship"], [1, "rel-name"], [1, "rel-fields"], [1, "fa-solid", "fa-floppy-disk"], [1, "suggest-submit-btn", "suggest-try-again-btn", 3, "click"], [1, "fa-solid", "fa-rotate"]], template: function VectorManagementResourceComponent_Template(rf, ctx) { if (rf & 1) {
2497
2772
  i0.ɵɵconditionalCreate(0, VectorManagementResourceComponent_Conditional_0_Template, 6, 4, "mj-page-layout");
2498
2773
  i0.ɵɵconditionalCreate(1, VectorManagementResourceComponent_Conditional_1_Template, 1, 1, "ng-container");
2499
2774
  i0.ɵɵtemplate(2, VectorManagementResourceComponent_ng_template_2_Template, 2, 1, "ng-template", null, 0, i0.ɵɵtemplateRefExtractor);
@@ -2501,22 +2776,22 @@ let VectorManagementResourceComponent = class VectorManagementResourceComponent
2501
2776
  i0.ɵɵconditional(!ctx.HideToolbar ? 0 : -1);
2502
2777
  i0.ɵɵadvance();
2503
2778
  i0.ɵɵconditional(ctx.HideToolbar ? 1 : -1);
2504
- } }, dependencies: [i1.NgTemplateOutlet, i2.NgSelectOption, i2.ɵNgSelectMultipleOption, i2.DefaultValueAccessor, i2.CheckboxControlValueAccessor, i2.SelectControlValueAccessor, i2.NgControlStatus, i2.NgModel, i3.CodeEditorComponent, i4.LoadingComponent, i5.KPICardComponent, i6.MJPageHeaderComponent, i6.MJPageLayoutComponent, i6.MJPageBodyComponent, i6.MJViewToggleComponent, i6.MJEmptyStateComponent, i6.MJAlertComponent, i1.DecimalPipe], styles: ["\n\n\n\n\n\n\n.vector-loading[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 400px;\n}\n\n\n.view-mode-toggle[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.25rem;\n padding: 0 24px 0;\n margin-bottom: -12px;\n}\n\n.view-mode-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n padding: 0.4rem 0.85rem;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 0.82rem;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.view-mode-btn[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n}\n\n.view-mode-btn-active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n\n.vector-dashboard[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 24px;\n padding: 24px;\n background: var(--mj-bg-page);\n min-height: 100%;\n}\n\n\n.kpi-row[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 16px;\n}\n\n@media (max-width: 1200px) {\n .kpi-row[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n}\n\n@media (max-width: 600px) {\n .kpi-row[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n}\n\n\n.content-area[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 1fr 300px;\n gap: 24px;\n align-items: start;\n}\n\n@media (max-width: 1024px) {\n .content-area[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n}\n\n\n.sync-table-panel[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n overflow: hidden;\n}\n\n.panel-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.panel-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 15px;\n font-weight: 600;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.panel-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 14px;\n}\n\n.refresh-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.refresh-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n border-color: var(--mj-border-strong);\n}\n\n\n.table-wrapper[_ngcontent-%COMP%] {\n overflow-x: auto;\n}\n\n.sync-table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n}\n\n.sync-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n padding: 10px 16px;\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n text-align: left;\n white-space: nowrap;\n}\n\n.sync-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 12px 16px;\n font-size: 13px;\n color: var(--mj-text-primary);\n border-bottom: 1px solid var(--mj-border-subtle);\n vertical-align: middle;\n}\n\n.sync-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.sync-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:last-child td[_ngcontent-%COMP%] {\n border-bottom: none;\n}\n\n.text-right[_ngcontent-%COMP%] {\n text-align: right;\n}\n\n.text-center[_ngcontent-%COMP%] {\n text-align: center;\n}\n\n.entity-name[_ngcontent-%COMP%] {\n font-weight: 600;\n}\n\n.document-name[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n}\n\n.vector-count[_ngcontent-%COMP%] {\n font-variant-numeric: tabular-nums;\n font-weight: 600;\n}\n\n.last-synced[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n font-size: 12px;\n white-space: nowrap;\n}\n\n\n\n.actions-cell[_ngcontent-%COMP%] {\n display: flex;\n gap: 6px;\n align-items: center;\n justify-content: center;\n}\n\n.schedule-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 30px;\n height: 30px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: transparent;\n color: var(--mj-text-muted);\n font-size: 12px;\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.schedule-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n}\n\n.edit-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 30px;\n height: 30px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: transparent;\n color: var(--mj-text-muted);\n font-size: 12px;\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.edit-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n border-color: var(--mj-border-strong);\n}\n\n\n.schedule-dialog[_ngcontent-%COMP%] {\n width: 440px;\n max-width: 90vw;\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.2);\n overflow: hidden;\n}\n\n.schedule-cron-preview[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 0 0;\n font-size: 0.82rem;\n color: var(--mj-text-muted);\n}\n\n.schedule-toggle-row[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: 12px;\n}\n\n.edit-delete-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n border: 1px solid var(--mj-status-error-border);\n border-radius: 6px;\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n color: var(--mj-status-error-text);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.edit-delete-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-status-error) 20%, var(--mj-bg-surface));\n}\n\n.edit-readonly-value[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n padding: 8px 0;\n}\n\n\n.status-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 10px;\n border-radius: 999px;\n font-size: 11px;\n font-weight: 600;\n white-space: nowrap;\n}\n\n.status-synced[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 12%, var(--mj-bg-surface));\n color: var(--mj-status-success-text, var(--mj-status-success));\n}\n\n.status-syncing[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.status-error[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 12%, var(--mj-bg-surface));\n color: var(--mj-status-error-text, var(--mj-status-error));\n}\n\n.status-pending[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 12%, var(--mj-bg-surface));\n color: var(--mj-status-warning-text, var(--mj-status-warning));\n}\n\n\n.sync-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 5px 12px;\n border: 1px solid var(--mj-brand-primary);\n border-radius: 6px;\n background: transparent;\n color: var(--mj-brand-primary);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.sync-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.sync-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n\n\n\n.sidebar[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.sidebar-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n padding: 16px 20px;\n}\n\n.sidebar-title[_ngcontent-%COMP%] {\n margin: 0 0 14px 0;\n font-size: 13px;\n font-weight: 700;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.sidebar-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 13px;\n}\n\n\n.health-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 6px;\n}\n\n.health-dot[_ngcontent-%COMP%] {\n width: 10px;\n height: 10px;\n border-radius: 50%;\n flex-shrink: 0;\n}\n\n.health-healthy[_ngcontent-%COMP%] {\n background: var(--mj-status-success);\n box-shadow: 0 0 6px color-mix(in srgb, var(--mj-status-success) 50%, transparent);\n}\n\n.health-degraded[_ngcontent-%COMP%] {\n background: var(--mj-status-warning);\n box-shadow: 0 0 6px color-mix(in srgb, var(--mj-status-warning) 50%, transparent);\n}\n\n.health-offline[_ngcontent-%COMP%] {\n background: var(--mj-status-error);\n box-shadow: 0 0 6px color-mix(in srgb, var(--mj-status-error) 50%, transparent);\n}\n\n.health-label[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.health-status[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n padding-left: 18px;\n}\n\n.health-reason[_ngcontent-%COMP%] {\n font-size: 11px;\n line-height: 1.4;\n color: var(--mj-text-muted);\n padding-left: 18px;\n margin-top: 4px;\n}\n\n\n.model-info[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.info-row[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.info-label[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.info-value[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n\n.gauge-container[_ngcontent-%COMP%] {\n margin-bottom: 8px;\n}\n\n.gauge-bar[_ngcontent-%COMP%] {\n height: 8px;\n border-radius: 4px;\n background: var(--mj-bg-surface-sunken);\n overflow: hidden;\n margin-bottom: 6px;\n}\n\n.gauge-fill[_ngcontent-%COMP%] {\n height: 100%;\n border-radius: 4px;\n background: var(--mj-brand-primary);\n transition: width 0.6s cubic-bezier(0.4, 0, 0.2, 1);\n min-width: 2px;\n}\n\n.gauge-label[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n.storage-detail[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n\n.panel-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n\n.suggest-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border: 1px solid var(--mj-brand-primary);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.suggest-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary-hover);\n}\n\n\n.slide-panel-overlay[_ngcontent-%COMP%] {\n position: fixed;\n inset: 0;\n background: var(--mj-bg-overlay);\n z-index: 100000;\n}\n\n.slide-panel[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n right: 0;\n height: 100vh;\n width: 480px;\n max-width: 90vw;\n background: var(--mj-bg-surface);\n box-shadow: -4px 0 24px color-mix(in srgb, var(--mj-text-primary) 12%, transparent);\n transform: translateX(100%);\n transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n overflow-y: auto;\n}\n\n.slide-panel.open[_ngcontent-%COMP%] {\n transform: translateX(0);\n}\n\n.suggest-dialog-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px 24px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.suggest-dialog-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.suggest-dialog-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.suggest-close-btn[_ngcontent-%COMP%] {\n border: none;\n background: none;\n color: var(--mj-text-muted);\n font-size: 16px;\n cursor: pointer;\n padding: 4px;\n}\n\n.suggest-close-btn[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n}\n\n.suggest-dialog-body[_ngcontent-%COMP%] {\n padding: 24px;\n}\n\n\n.suggest-form[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.suggest-field[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.suggest-label[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n.suggest-select[_ngcontent-%COMP%] {\n padding: 8px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n}\n\n.suggest-select[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n\n\n.use-case-options[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n flex-wrap: wrap;\n}\n\n.use-case-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.use-case-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-border-strong);\n color: var(--mj-text-primary);\n}\n\n.use-case-btn-active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n.use-case-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n\n\n.entity-picker[_ngcontent-%COMP%] {\n position: relative;\n}\n\n.entity-picker-trigger[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n padding: 9px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n cursor: pointer;\n text-align: left;\n transition: border-color 0.15s;\n}\n\n.entity-picker-trigger[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-border-strong);\n}\n\n.entity-picker-placeholder[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n flex: 1;\n}\n\n.entity-picker-value[_ngcontent-%COMP%] {\n flex: 1;\n font-weight: 500;\n}\n\n.entity-picker-arrow[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--mj-text-muted);\n transition: transform 0.2s;\n}\n\n.entity-picker-dropdown[_ngcontent-%COMP%] {\n position: absolute;\n top: calc(100% + 4px);\n left: 0;\n right: 0;\n background: var(--mj-bg-surface-elevated, var(--mj-bg-surface));\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n box-shadow: 0 8px 32px color-mix(in srgb, var(--mj-text-primary) 15%, transparent);\n z-index: 100;\n max-height: 350px;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n.entity-picker-search[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 14px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.entity-picker-search[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 13px;\n}\n\n.entity-picker-search-input[_ngcontent-%COMP%] {\n flex: 1;\n border: none;\n background: transparent;\n color: var(--mj-text-primary);\n font-size: 13px;\n outline: none;\n}\n\n.entity-picker-search-input[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-disabled);\n}\n\n.entity-picker-list[_ngcontent-%COMP%] {\n overflow-y: auto;\n max-height: 300px;\n padding: 4px 0;\n}\n\n.entity-picker-group-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 14px 4px;\n font-size: 11px;\n font-weight: 700;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n position: sticky;\n top: 0;\n background: var(--mj-bg-surface-elevated, var(--mj-bg-surface));\n}\n\n.entity-picker-group-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n.entity-picker-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n padding: 7px 14px 7px 28px;\n border: none;\n background: transparent;\n color: var(--mj-text-primary);\n font-size: 13px;\n cursor: pointer;\n text-align: left;\n transition: background 0.1s;\n}\n\n.entity-picker-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.entity-picker-item-selected[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n.entity-picker-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.entity-picker-item-selected[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.entity-picker-item-focused[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-hover);\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: -2px;\n}\n\n.entity-picker-empty[_ngcontent-%COMP%] {\n padding: 20px 14px;\n text-align: center;\n color: var(--mj-text-disabled);\n font-size: 13px;\n}\n\n\n\n.template-editor-wrapper[_ngcontent-%COMP%] {\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n min-height: 120px;\n max-height: 300px;\n}\n\n.template-editor-wrapper[_ngcontent-%COMP%] .cm-editor {\n min-height: 120px;\n max-height: 300px;\n font-size: 13px;\n}\n\n.suggest-submit-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n padding: 10px 20px;\n border: none;\n border-radius: 6px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.2s ease;\n}\n\n.suggest-submit-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n\n.suggest-submit-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n\n.suggest-result[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.result-section[_ngcontent-%COMP%] {\n border-bottom: 1px solid var(--mj-border-subtle);\n padding-bottom: 12px;\n}\n\n.result-section[_ngcontent-%COMP%]:last-child {\n border-bottom: none;\n}\n\n.result-heading[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.result-template[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 6px;\n padding: 12px;\n font-size: 12px;\n color: var(--mj-text-primary);\n white-space: pre-wrap;\n word-break: break-all;\n margin: 0;\n}\n\n.result-tags[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n}\n\n.result-tag[_ngcontent-%COMP%] {\n padding: 3px 10px;\n border-radius: 12px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 12px;\n font-weight: 500;\n}\n\n.result-relationship[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 4px 0;\n}\n\n.rel-name[_ngcontent-%COMP%] {\n font-weight: 600;\n font-size: 13px;\n color: var(--mj-text-primary);\n}\n\n.rel-fields[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.result-thresholds[_ngcontent-%COMP%] {\n display: flex;\n gap: 24px;\n}\n\n.threshold-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.threshold-label[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.threshold-value[_ngcontent-%COMP%] {\n font-size: 18px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.result-reasoning[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 13px;\n color: var(--mj-text-secondary);\n line-height: 1.5;\n}\n\n.result-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n padding-top: 8px;\n}\n\n.suggest-close-action[_ngcontent-%COMP%] {\n padding: 10px 20px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n}\n\n.suggest-close-action[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n\n.suggest-input[_ngcontent-%COMP%] {\n padding: 8px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n width: 100%;\n box-sizing: border-box;\n}\n\n.suggest-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n\n.suggest-try-again-btn[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n border: 1px solid var(--mj-brand-primary);\n}\n\n.suggest-try-again-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n\n.save-spinner[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 8px 0;\n}\n\n\n.edit-template-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n}\n\n.edit-regenerate-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 10px;\n border: 1px solid var(--mj-brand-primary);\n border-radius: 6px;\n background: transparent;\n color: var(--mj-brand-primary);\n font-size: 11px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n white-space: nowrap;\n}\n\n.edit-regenerate-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.edit-regenerate-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n\n.no-index-warning-dialog[_ngcontent-%COMP%] {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 440px;\n max-width: 90vw;\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: 0 20px 60px color-mix(in srgb, var(--mj-text-primary) 20%, transparent);\n padding: 32px;\n text-align: center;\n}\n\n.no-index-warning-icon[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 56px;\n height: 56px;\n margin: 0 auto 16px;\n border-radius: 50%;\n background: color-mix(in srgb, var(--mj-status-warning) 12%, var(--mj-bg-surface));\n}\n\n.no-index-warning-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 24px;\n color: var(--mj-status-warning);\n}\n\n.no-index-warning-title[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: 18px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.no-index-warning-message[_ngcontent-%COMP%] {\n margin: 0 0 24px 0;\n font-size: 14px;\n line-height: 1.5;\n color: var(--mj-text-secondary);\n}\n\n.no-index-warning-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n justify-content: center;\n}\n\n\n\n\n\n@media (max-width: 768px) {\n .panel-header[_ngcontent-%COMP%] {\n flex-direction: column;\n align-items: flex-start;\n gap: 12px;\n }\n\n .panel-actions[_ngcontent-%COMP%] {\n flex-wrap: wrap;\n }\n}\n\n@media (max-width: 600px) {\n .slide-panel[_ngcontent-%COMP%] {\n width: 100vw;\n max-width: 100vw;\n }\n}\n\n@media (max-width: 480px) {\n .vector-dashboard[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .suggest-btn[_ngcontent-%COMP%] .suggest-btn-text[_ngcontent-%COMP%] {\n display: none;\n }\n}"] });
2779
+ } }, dependencies: [i1.NgTemplateOutlet, i2.NgSelectOption, i2.ɵNgSelectMultipleOption, i2.DefaultValueAccessor, i2.CheckboxControlValueAccessor, i2.SelectControlValueAccessor, i2.NgControlStatus, i2.NgModel, i3.CodeEditorComponent, i4.LoadingComponent, i5.KPICardComponent, i6.MJPageHeaderComponent, i6.MJPageLayoutComponent, i6.MJPageBodyComponent, i6.MJViewToggleComponent, i6.MJEmptyStateComponent, i6.MJAlertComponent, i1.DecimalPipe], styles: ["\n\n\n\n\n\n\n.vector-loading[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 400px;\n}\n\n\n.view-mode-toggle[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.25rem;\n padding: 0 24px 0;\n margin-bottom: -12px;\n}\n\n.view-mode-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n padding: 0.4rem 0.85rem;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 0.82rem;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.view-mode-btn[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n}\n\n.view-mode-btn-active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n\n.vector-dashboard[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 24px;\n padding: 24px;\n background: var(--mj-bg-page);\n min-height: 100%;\n}\n\n\n.kpi-row[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 16px;\n}\n\n@media (max-width: 1200px) {\n .kpi-row[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n}\n\n@media (max-width: 600px) {\n .kpi-row[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n}\n\n\n.content-area[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 1fr 300px;\n gap: 24px;\n align-items: start;\n}\n\n@media (max-width: 1024px) {\n .content-area[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n}\n\n\n.sync-table-panel[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n overflow: hidden;\n}\n\n.panel-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.panel-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 15px;\n font-weight: 600;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.panel-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 14px;\n}\n\n.refresh-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.refresh-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n border-color: var(--mj-border-strong);\n}\n\n\n.table-wrapper[_ngcontent-%COMP%] {\n overflow-x: auto;\n}\n\n.sync-table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n}\n\n.sync-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n padding: 10px 16px;\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n text-align: left;\n white-space: nowrap;\n}\n\n.sync-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 12px 16px;\n font-size: 13px;\n color: var(--mj-text-primary);\n border-bottom: 1px solid var(--mj-border-subtle);\n vertical-align: middle;\n}\n\n.sync-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.sync-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:last-child td[_ngcontent-%COMP%] {\n border-bottom: none;\n}\n\n.text-right[_ngcontent-%COMP%] {\n text-align: right;\n}\n\n.text-center[_ngcontent-%COMP%] {\n text-align: center;\n}\n\n.entity-name[_ngcontent-%COMP%] {\n font-weight: 600;\n}\n\n.document-name[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n}\n\n.document-type[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n white-space: nowrap;\n}\n\n.vector-count[_ngcontent-%COMP%] {\n font-variant-numeric: tabular-nums;\n font-weight: 600;\n}\n\n.last-synced[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n font-size: 12px;\n white-space: nowrap;\n}\n\n\n\n.actions-cell[_ngcontent-%COMP%] {\n display: flex;\n gap: 6px;\n align-items: center;\n justify-content: center;\n}\n\n.schedule-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 30px;\n height: 30px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: transparent;\n color: var(--mj-text-muted);\n font-size: 12px;\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.schedule-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n}\n\n.edit-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 30px;\n height: 30px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: transparent;\n color: var(--mj-text-muted);\n font-size: 12px;\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.edit-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n border-color: var(--mj-border-strong);\n}\n\n\n.schedule-dialog[_ngcontent-%COMP%] {\n width: 440px;\n max-width: 90vw;\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.2);\n overflow: hidden;\n}\n\n.schedule-cron-preview[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 0 0;\n font-size: 0.82rem;\n color: var(--mj-text-muted);\n}\n\n.schedule-toggle-row[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: 12px;\n}\n\n.edit-delete-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n border: 1px solid var(--mj-status-error-border);\n border-radius: 6px;\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n color: var(--mj-status-error-text);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.edit-delete-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-status-error) 20%, var(--mj-bg-surface));\n}\n\n.edit-readonly-value[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n padding: 8px 0;\n}\n\n\n.status-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 10px;\n border-radius: 999px;\n font-size: 11px;\n font-weight: 600;\n white-space: nowrap;\n}\n\n.status-synced[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 12%, var(--mj-bg-surface));\n color: var(--mj-status-success-text, var(--mj-status-success));\n}\n\n.status-syncing[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.status-error[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 12%, var(--mj-bg-surface));\n color: var(--mj-status-error-text, var(--mj-status-error));\n}\n\n.status-pending[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 12%, var(--mj-bg-surface));\n color: var(--mj-status-warning-text, var(--mj-status-warning));\n}\n\n\n.sync-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 5px 12px;\n border: 1px solid var(--mj-brand-primary);\n border-radius: 6px;\n background: transparent;\n color: var(--mj-brand-primary);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.sync-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.sync-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n\n\n\n.sidebar[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.sidebar-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n padding: 16px 20px;\n}\n\n.sidebar-title[_ngcontent-%COMP%] {\n margin: 0 0 14px 0;\n font-size: 13px;\n font-weight: 700;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.sidebar-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 13px;\n}\n\n\n.health-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 6px;\n}\n\n.health-dot[_ngcontent-%COMP%] {\n width: 10px;\n height: 10px;\n border-radius: 50%;\n flex-shrink: 0;\n}\n\n.health-healthy[_ngcontent-%COMP%] {\n background: var(--mj-status-success);\n box-shadow: 0 0 6px color-mix(in srgb, var(--mj-status-success) 50%, transparent);\n}\n\n.health-degraded[_ngcontent-%COMP%] {\n background: var(--mj-status-warning);\n box-shadow: 0 0 6px color-mix(in srgb, var(--mj-status-warning) 50%, transparent);\n}\n\n.health-offline[_ngcontent-%COMP%] {\n background: var(--mj-status-error);\n box-shadow: 0 0 6px color-mix(in srgb, var(--mj-status-error) 50%, transparent);\n}\n\n.health-label[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.health-status[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n padding-left: 18px;\n}\n\n.health-reason[_ngcontent-%COMP%] {\n font-size: 11px;\n line-height: 1.4;\n color: var(--mj-text-muted);\n padding-left: 18px;\n margin-top: 4px;\n}\n\n\n.model-info[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.info-row[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.info-label[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.info-value[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n\n.gauge-container[_ngcontent-%COMP%] {\n margin-bottom: 8px;\n}\n\n.gauge-bar[_ngcontent-%COMP%] {\n height: 8px;\n border-radius: 4px;\n background: var(--mj-bg-surface-sunken);\n overflow: hidden;\n margin-bottom: 6px;\n}\n\n.gauge-fill[_ngcontent-%COMP%] {\n height: 100%;\n border-radius: 4px;\n background: var(--mj-brand-primary);\n transition: width 0.6s cubic-bezier(0.4, 0, 0.2, 1);\n min-width: 2px;\n}\n\n.gauge-label[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n.storage-detail[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n\n.panel-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n\n.suggest-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border: 1px solid var(--mj-brand-primary);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.suggest-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary-hover);\n}\n\n\n.slide-panel-overlay[_ngcontent-%COMP%] {\n position: fixed;\n inset: 0;\n background: var(--mj-bg-overlay);\n z-index: 100000;\n}\n\n.slide-panel[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n right: 0;\n height: 100vh;\n width: 480px;\n max-width: 90vw;\n background: var(--mj-bg-surface);\n box-shadow: -4px 0 24px color-mix(in srgb, var(--mj-text-primary) 12%, transparent);\n transform: translateX(100%);\n transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n overflow-y: auto;\n}\n\n.slide-panel.open[_ngcontent-%COMP%] {\n transform: translateX(0);\n}\n\n.suggest-dialog-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px 24px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.suggest-dialog-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.suggest-dialog-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.suggest-close-btn[_ngcontent-%COMP%] {\n border: none;\n background: none;\n color: var(--mj-text-muted);\n font-size: 16px;\n cursor: pointer;\n padding: 4px;\n}\n\n.suggest-close-btn[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n}\n\n.suggest-dialog-body[_ngcontent-%COMP%] {\n padding: 24px;\n}\n\n\n.suggest-form[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.suggest-field[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.suggest-label[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n.suggest-select[_ngcontent-%COMP%] {\n padding: 8px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n}\n\n.suggest-select[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n\n\n.use-case-options[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n flex-wrap: wrap;\n}\n\n.use-case-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.use-case-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-border-strong);\n color: var(--mj-text-primary);\n}\n\n.use-case-btn-active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n.use-case-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n\n\n.entity-picker[_ngcontent-%COMP%] {\n position: relative;\n}\n\n.entity-picker-trigger[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n padding: 9px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n cursor: pointer;\n text-align: left;\n transition: border-color 0.15s;\n}\n\n.entity-picker-trigger[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-border-strong);\n}\n\n.entity-picker-placeholder[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n flex: 1;\n}\n\n.entity-picker-value[_ngcontent-%COMP%] {\n flex: 1;\n font-weight: 500;\n}\n\n.entity-picker-arrow[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--mj-text-muted);\n transition: transform 0.2s;\n}\n\n.entity-picker-dropdown[_ngcontent-%COMP%] {\n position: absolute;\n top: calc(100% + 4px);\n left: 0;\n right: 0;\n background: var(--mj-bg-surface-elevated, var(--mj-bg-surface));\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n box-shadow: 0 8px 32px color-mix(in srgb, var(--mj-text-primary) 15%, transparent);\n z-index: 100;\n max-height: 350px;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n.entity-picker-search[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 14px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.entity-picker-search[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 13px;\n}\n\n.entity-picker-search-input[_ngcontent-%COMP%] {\n flex: 1;\n border: none;\n background: transparent;\n color: var(--mj-text-primary);\n font-size: 13px;\n outline: none;\n}\n\n.entity-picker-search-input[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-disabled);\n}\n\n.entity-picker-list[_ngcontent-%COMP%] {\n overflow-y: auto;\n max-height: 300px;\n padding: 4px 0;\n}\n\n.entity-picker-group-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 14px 4px;\n font-size: 11px;\n font-weight: 700;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n position: sticky;\n top: 0;\n background: var(--mj-bg-surface-elevated, var(--mj-bg-surface));\n}\n\n.entity-picker-group-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n.entity-picker-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n padding: 7px 14px 7px 28px;\n border: none;\n background: transparent;\n color: var(--mj-text-primary);\n font-size: 13px;\n cursor: pointer;\n text-align: left;\n transition: background 0.1s;\n}\n\n.entity-picker-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.entity-picker-item-selected[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n.entity-picker-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.entity-picker-item-selected[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.entity-picker-item-focused[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-hover);\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: -2px;\n}\n\n.entity-picker-empty[_ngcontent-%COMP%] {\n padding: 20px 14px;\n text-align: center;\n color: var(--mj-text-disabled);\n font-size: 13px;\n}\n\n\n\n.template-editor-wrapper[_ngcontent-%COMP%] {\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n min-height: 120px;\n max-height: 300px;\n}\n\n.template-editor-wrapper[_ngcontent-%COMP%] .cm-editor {\n min-height: 120px;\n max-height: 300px;\n font-size: 13px;\n}\n\n.suggest-submit-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n padding: 10px 20px;\n border: none;\n border-radius: 6px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.2s ease;\n}\n\n.suggest-submit-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n\n.suggest-submit-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n\n.suggest-result[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.result-section[_ngcontent-%COMP%] {\n border-bottom: 1px solid var(--mj-border-subtle);\n padding-bottom: 12px;\n}\n\n.result-section[_ngcontent-%COMP%]:last-child {\n border-bottom: none;\n}\n\n.result-heading[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.result-template[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 6px;\n padding: 12px;\n font-size: 12px;\n color: var(--mj-text-primary);\n white-space: pre-wrap;\n word-break: break-all;\n margin: 0;\n}\n\n.result-tags[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n}\n\n.result-tag[_ngcontent-%COMP%] {\n padding: 3px 10px;\n border-radius: 12px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 12px;\n font-weight: 500;\n}\n\n.result-relationship[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 4px 0;\n}\n\n.rel-name[_ngcontent-%COMP%] {\n font-weight: 600;\n font-size: 13px;\n color: var(--mj-text-primary);\n}\n\n.rel-fields[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.result-thresholds[_ngcontent-%COMP%] {\n display: flex;\n gap: 24px;\n}\n\n.threshold-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.threshold-label[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.threshold-value[_ngcontent-%COMP%] {\n font-size: 18px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.result-reasoning[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 13px;\n color: var(--mj-text-secondary);\n line-height: 1.5;\n}\n\n.result-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n padding-top: 8px;\n}\n\n.suggest-close-action[_ngcontent-%COMP%] {\n padding: 10px 20px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n}\n\n.suggest-close-action[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n\n.suggest-input[_ngcontent-%COMP%] {\n padding: 8px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n width: 100%;\n box-sizing: border-box;\n}\n\n.suggest-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n\n.suggest-try-again-btn[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n border: 1px solid var(--mj-brand-primary);\n}\n\n.suggest-try-again-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n\n.save-spinner[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 8px 0;\n}\n\n\n.edit-template-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n}\n\n.edit-regenerate-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 10px;\n border: 1px solid var(--mj-brand-primary);\n border-radius: 6px;\n background: transparent;\n color: var(--mj-brand-primary);\n font-size: 11px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n white-space: nowrap;\n}\n\n.edit-regenerate-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.edit-regenerate-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n\n.no-index-warning-dialog[_ngcontent-%COMP%] {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 440px;\n max-width: 90vw;\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: 0 20px 60px color-mix(in srgb, var(--mj-text-primary) 20%, transparent);\n padding: 32px;\n text-align: center;\n}\n\n.no-index-warning-icon[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 56px;\n height: 56px;\n margin: 0 auto 16px;\n border-radius: 50%;\n background: color-mix(in srgb, var(--mj-status-warning) 12%, var(--mj-bg-surface));\n}\n\n.no-index-warning-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 24px;\n color: var(--mj-status-warning);\n}\n\n.no-index-warning-title[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: 18px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.no-index-warning-message[_ngcontent-%COMP%] {\n margin: 0 0 24px 0;\n font-size: 14px;\n line-height: 1.5;\n color: var(--mj-text-secondary);\n}\n\n.no-index-warning-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n justify-content: center;\n}\n\n\n\n\n\n@media (max-width: 768px) {\n .panel-header[_ngcontent-%COMP%] {\n flex-direction: column;\n align-items: flex-start;\n gap: 12px;\n }\n\n .panel-actions[_ngcontent-%COMP%] {\n flex-wrap: wrap;\n }\n}\n\n@media (max-width: 600px) {\n .slide-panel[_ngcontent-%COMP%] {\n width: 100vw;\n max-width: 100vw;\n }\n}\n\n@media (max-width: 480px) {\n .vector-dashboard[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .suggest-btn[_ngcontent-%COMP%] .suggest-btn-text[_ngcontent-%COMP%] {\n display: none;\n }\n}"] });
2505
2780
  };
2506
- VectorManagementResourceComponent = __decorate([
2781
+ VectorManagementResourceComponent = VectorManagementResourceComponent_1 = __decorate([
2507
2782
  RegisterClass(BaseResourceComponent, 'VectorManagementResource')
2508
2783
  ], VectorManagementResourceComponent);
2509
2784
  export { VectorManagementResourceComponent };
2510
2785
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(VectorManagementResourceComponent, [{
2511
2786
  type: Component,
2512
- args: [{ standalone: false, selector: 'app-vector-management-resource', template: "@if (!HideToolbar) {\n <mj-page-layout>\n <mj-page-header\n Title=\"Vector Management\"\n Icon=\"fa-solid fa-cubes\"\n Subtitle=\"Vector index health, embeddings, and entity sync status\">\n <div actions>\n <mj-view-toggle\n [Options]=\"VectorViewOptions\"\n [ActiveKey]=\"ViewMode\"\n (KeyChange)=\"ViewMode = $any($event)\">\n </mj-view-toggle>\n </div>\n </mj-page-header>\n <mj-page-body [Flex]=\"true\">\n <ng-container *ngTemplateOutlet=\"vectorBody\"></ng-container>\n </mj-page-body>\n </mj-page-layout>\n}\n@if (HideToolbar) {\n <ng-container *ngTemplateOutlet=\"vectorBody\"></ng-container>\n}\n\n<ng-template #vectorBody>\n@if (IsLoading) {\n <div class=\"vector-loading\">\n <mj-loading text=\"Loading vector management data...\"></mj-loading>\n </div>\n} @else {\n <div class=\"vector-dashboard\">\n\n <!-- KPI Cards Row -->\n <div class=\"kpi-row\">\n @for (card of KPICards; track card.title) {\n <app-kpi-card [data]=\"card\"></app-kpi-card>\n }\n </div>\n\n <!-- Main Content Area: Table + Sidebar -->\n <div class=\"content-area\">\n <!-- Entity Sync Table -->\n <div class=\"sync-table-panel\">\n <div class=\"panel-header\">\n <h3 class=\"panel-title\">\n <i class=\"fa-solid fa-table-list\"></i>\n Entity Sync Status\n </h3>\n <div class=\"panel-actions\">\n <button class=\"suggest-btn\" (click)=\"OpenSuggestDialog()\" title=\"Use AI to suggest an Entity Document template\">\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i>\n <span class=\"suggest-btn-text\">Suggest Document</span>\n </button>\n <button class=\"refresh-btn\" (click)=\"LoadData(true)\" title=\"Refresh data\">\n <i class=\"fa-solid fa-arrows-rotate\"></i>\n Refresh\n </button>\n </div>\n </div>\n\n @if (SyncRows.length === 0) {\n <mj-empty-state Icon=\"fa-solid fa-folder-open\"\n Title=\"No entity documents configured for vectorization.\" />\n } @else {\n <div class=\"table-wrapper\">\n <table class=\"sync-table\">\n <thead>\n <tr>\n <th>Entity</th>\n <th>Document</th>\n <th class=\"text-right\">Vectors</th>\n <th>Last Synced</th>\n <th>Status</th>\n <th class=\"text-center\">Actions</th>\n </tr>\n </thead>\n <tbody>\n @for (row of SyncRows; track row.EntityDocumentID) {\n <tr>\n <td class=\"entity-name\">{{ row.EntityName }}</td>\n <td class=\"document-name\">{{ row.DocumentName }}</td>\n <td class=\"text-right vector-count\">{{ row.VectorCount | number }}</td>\n <td class=\"last-synced\">{{ FormatDate(row.LastSynced) }}</td>\n <td>\n <span class=\"status-badge\" [class]=\"GetStatusClass(row.Status)\">\n <i [class]=\"GetStatusIcon(row.Status)\"></i>\n @if (row.Status === 'Syncing' && row.PercentComplete > 0) {\n {{ row.PercentComplete }}%\n } @else {\n {{ row.Status }}\n }\n </span>\n </td>\n <td class=\"text-center actions-cell\">\n <button\n class=\"sync-btn\"\n [disabled]=\"IsSyncing(row.EntityDocumentID)\"\n (click)=\"SyncEntity(row.EntityDocumentID)\"\n title=\"Sync now\">\n @if (IsSyncing(row.EntityDocumentID)) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n {{ row.PercentComplete > 0 ? row.PercentComplete + '%' : 'Sync' }}\n } @else {\n <i class=\"fa-solid fa-play\"></i>\n Sync\n }\n </button>\n <button\n class=\"schedule-btn\"\n (click)=\"OpenScheduleSyncDialog(row.EntityDocumentID)\"\n title=\"Schedule recurring sync\">\n <i class=\"fa-regular fa-clock\"></i>\n </button>\n <button\n class=\"edit-btn\"\n (click)=\"OpenEditPanel(row.EntityDocumentID)\"\n title=\"Edit entity document\">\n <i class=\"fa-solid fa-pen\"></i>\n </button>\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n </div>\n\n <!-- Sidebar Panels -->\n <div class=\"sidebar\">\n <!-- Vector DB Health -->\n <div class=\"sidebar-card\">\n <h4 class=\"sidebar-title\">\n <i class=\"fa-solid fa-heart-pulse\"></i>\n Vector DB Health\n </h4>\n <div class=\"health-row\">\n <span class=\"health-dot\" [class]=\"DBHealthClass\"></span>\n <span class=\"health-label\">{{ VectorDBName }}</span>\n </div>\n <div class=\"health-status\" [title]=\"VectorDBStatusReason\">{{ VectorDBStatus }}</div>\n @if (VectorDBStatusReason) {\n <div class=\"health-reason\">{{ VectorDBStatusReason }}</div>\n }\n </div>\n\n <!-- Embedding Model Info -->\n <div class=\"sidebar-card\">\n <h4 class=\"sidebar-title\">\n <i class=\"fa-solid fa-microchip\"></i>\n Embedding Model\n </h4>\n <div class=\"model-info\">\n <div class=\"info-row\">\n <span class=\"info-label\">Model</span>\n <span class=\"info-value\" [title]=\"'Embeddings are generated by this model; the index above stores the resulting vectors.'\">{{ EmbeddingModel.Name }}</span>\n </div>\n @if (EmbeddingModel.Dimensions != null) {\n <div class=\"info-row\">\n <span class=\"info-label\">Dimensions</span>\n <span class=\"info-value\">{{ EmbeddingModel.Dimensions | number }}</span>\n </div>\n }\n </div>\n </div>\n\n <!-- Storage Usage -->\n <div class=\"sidebar-card\">\n <h4 class=\"sidebar-title\">\n <i class=\"fa-solid fa-hard-drive\"></i>\n Vectorization Coverage\n </h4>\n <div class=\"gauge-container\">\n <div class=\"gauge-bar\">\n <div class=\"gauge-fill\" [style.width.%]=\"StorageUsagePercent\"></div>\n </div>\n <div class=\"gauge-label\">{{ StorageLabel }} of records vectorized</div>\n </div>\n <div class=\"storage-detail\">\n {{ TotalVectors | number }} vectors stored\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Edit Entity Document Slide-in Panel -->\n @if (ShowEditPanel) {\n <div class=\"slide-panel-overlay\" (click)=\"CloseEditPanel()\">\n <div class=\"slide-panel open\" (click)=\"$event.stopPropagation()\">\n <div class=\"suggest-dialog-header\">\n <h3 class=\"suggest-dialog-title\">\n <i class=\"fa-solid fa-pen\"></i>\n Edit Entity Document\n </h3>\n <button class=\"suggest-close-btn\" (click)=\"CloseEditPanel()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n <div class=\"suggest-dialog-body\">\n <div class=\"suggest-form\">\n <div class=\"suggest-field\">\n <label class=\"suggest-label\">Entity</label>\n <span class=\"edit-readonly-value\">{{ EditDocEntityName }}</span>\n </div>\n\n <!-- Template Section -->\n <div class=\"suggest-field\">\n <div class=\"edit-template-header\">\n <label class=\"suggest-label\">Template</label>\n <button class=\"edit-regenerate-btn\"\n [disabled]=\"IsEditRegenerating\"\n (click)=\"RegenerateTemplate()\"\n title=\"Regenerate template using AI\">\n @if (IsEditRegenerating) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Regenerating...\n } @else {\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i> Regenerate with AI\n }\n </button>\n </div>\n <div class=\"template-editor-wrapper\">\n <mj-code-editor\n [value]=\"EditDocTemplate\"\n language=\"markdown\"\n [readonly]=\"false\"\n [lineWrapping]=\"true\"\n (change)=\"OnEditTemplateChange($event)\">\n </mj-code-editor>\n </div>\n </div>\n\n <!-- Selected Fields (parsed from template) -->\n @if (EditDocSelectedFields.length > 0) {\n <div class=\"suggest-field\">\n <label class=\"suggest-label\">Selected Fields</label>\n <div class=\"result-tags\">\n @for (field of EditDocSelectedFields; track field) {\n <span class=\"result-tag\">{{ field }}</span>\n }\n </div>\n </div>\n }\n\n <div class=\"suggest-field\">\n <label class=\"suggest-label\">Document Name</label>\n <input class=\"suggest-input\" type=\"text\" [(ngModel)]=\"EditDocName\" />\n </div>\n <div class=\"suggest-field\">\n <label class=\"suggest-label\">Embedding Model</label>\n <select class=\"suggest-select\" [(ngModel)]=\"EditDocAIModelID\">\n @for (model of AvailableEmbeddingModels; track model.ID) {\n <option [value]=\"model.ID\">{{ model.Name }}</option>\n }\n </select>\n </div>\n <div class=\"suggest-field\">\n <label class=\"suggest-label\">Vector Database</label>\n <select class=\"suggest-select\" [(ngModel)]=\"EditDocVectorDBID\">\n @for (db of vectorDatabases; track db.ID) {\n <option [value]=\"db.ID\">{{ db.Name }}</option>\n }\n </select>\n </div>\n <div class=\"suggest-field\">\n <label class=\"suggest-label\">Vector Index</label>\n @if (EditFilteredIndexes.length > 0) {\n <select class=\"suggest-select\" [(ngModel)]=\"EditDocVectorIndexID\">\n <option value=\"\">Auto (create/find matching index)</option>\n @for (idx of EditFilteredIndexes; track idx.ID) {\n <option [value]=\"idx.ID\">{{ idx.Name }}</option>\n }\n </select>\n } @else {\n <span class=\"edit-readonly-value\" style=\"font-size: 13px; color: var(--mj-text-muted);\">\n No indexes for this database \u2014 one will be created automatically on sync\n </span>\n }\n </div>\n <div class=\"suggest-field\">\n <label class=\"suggest-label\">Status</label>\n <select class=\"suggest-select\" [(ngModel)]=\"EditDocStatus\">\n <option value=\"Active\">Active</option>\n <option value=\"Inactive\">Inactive</option>\n </select>\n </div>\n <div class=\"result-actions\" style=\"margin-top: 1rem\">\n @if (IsEditSaving || IsEditDeleting) {\n <mj-loading text=\"Saving...\" size=\"small\"></mj-loading>\n } @else {\n <button class=\"suggest-submit-btn\" (click)=\"SaveEditedDocument()\">\n <i class=\"fa-solid fa-save\"></i> Save Changes\n </button>\n <button class=\"edit-delete-btn\" (click)=\"DeleteEntityDocument()\">\n <i class=\"fa-solid fa-trash-can\"></i> Delete\n </button>\n <button class=\"suggest-close-action\" (click)=\"CloseEditPanel()\">\n Cancel\n </button>\n }\n </div>\n </div>\n </div>\n </div>\n </div>\n }\n\n <!-- Schedule Sync Dialog -->\n @if (ShowScheduleSyncDialog) {\n <div class=\"slide-panel-overlay\" (click)=\"CloseScheduleSyncDialog()\">\n <div class=\"schedule-dialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"suggest-dialog-header\">\n <h3 class=\"suggest-dialog-title\">\n <i class=\"fa-regular fa-clock\"></i>\n Schedule Vector Sync\n </h3>\n <button class=\"suggest-close-btn\" (click)=\"CloseScheduleSyncDialog()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n <div class=\"suggest-dialog-body\">\n <div class=\"suggest-form\">\n <div class=\"suggest-field\">\n <label class=\"suggest-label\">Entity Document</label>\n <span class=\"edit-readonly-value\">{{ ScheduleSyncDocName }}</span>\n </div>\n <div class=\"suggest-field\">\n <label class=\"suggest-label\">Action</label>\n <span class=\"edit-readonly-value\">__VectorizeEntity</span>\n </div>\n <div class=\"suggest-field\">\n <label class=\"suggest-label\">Cron Expression</label>\n <input class=\"suggest-input\" type=\"text\" [(ngModel)]=\"ScheduleSyncCron\" placeholder=\"0 2 * * *\" />\n <div class=\"schedule-cron-preview\">\n <i class=\"fa-solid fa-info-circle\"></i>\n {{ GetScheduleCronPreview(ScheduleSyncCron) }}\n </div>\n </div>\n <div class=\"suggest-field schedule-toggle-row\">\n <label class=\"suggest-label\">Enabled</label>\n <input type=\"checkbox\" class=\"mj-checkbox\" [(ngModel)]=\"ScheduleSyncEnabled\" />\n </div>\n <div class=\"result-actions\" style=\"margin-top: 1rem\">\n @if (ScheduleSyncSaving) {\n <mj-loading text=\"Saving...\" size=\"small\"></mj-loading>\n } @else {\n <button class=\"suggest-submit-btn\" (click)=\"SaveScheduleSync()\">\n <i class=\"fa-solid fa-check\"></i> Create Schedule\n </button>\n <button class=\"suggest-close-action\" (click)=\"CloseScheduleSyncDialog()\">\n Cancel\n </button>\n }\n </div>\n </div>\n </div>\n </div>\n </div>\n }\n\n <!-- No Vector Index Warning Dialog -->\n @if (ShowNoIndexWarning) {\n <div class=\"slide-panel-overlay\" (click)=\"CloseNoIndexWarning()\">\n <div class=\"no-index-warning-dialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"no-index-warning-icon\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n </div>\n <h3 class=\"no-index-warning-title\">Vector Index Required</h3>\n <p class=\"no-index-warning-message\">\n You need to create at least one vector database and index before creating entity documents.\n Go to the Configuration section to set up a vector database and create an index.\n </p>\n <div class=\"no-index-warning-actions\">\n <button class=\"suggest-submit-btn\" (click)=\"GoToConfiguration()\">\n <i class=\"fa-solid fa-gear\"></i> Go to Configuration\n </button>\n <button class=\"suggest-close-action\" (click)=\"CloseNoIndexWarning()\">\n Close\n </button>\n </div>\n </div>\n </div>\n }\n\n <!-- Suggest Document Slide-in Panel -->\n @if (ShowSuggestDialog) {\n <div class=\"slide-panel-overlay\" (click)=\"CloseSuggestDialog()\">\n <div class=\"slide-panel\" [class.open]=\"ShowSuggestDialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"suggest-dialog-header\">\n <h3 class=\"suggest-dialog-title\">\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i>\n AI Document Suggestion\n </h3>\n <button class=\"suggest-close-btn\" (click)=\"CloseSuggestDialog()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n <div class=\"suggest-dialog-body\">\n @if (!SuggestionResult) {\n <div class=\"suggest-form\">\n <div class=\"suggest-field\">\n <label class=\"suggest-label\">Entity</label>\n <div class=\"entity-picker\">\n <button class=\"entity-picker-trigger\" (click)=\"ToggleEntityPicker()\">\n @if (SuggestEntityName) {\n <i class=\"fa-solid fa-table\"></i>\n <span class=\"entity-picker-value\">{{ SuggestEntityName }}</span>\n } @else {\n <i class=\"fa-solid fa-search\"></i>\n <span class=\"entity-picker-placeholder\">Search and select an entity...</span>\n }\n <i class=\"fa-solid fa-chevron-down entity-picker-arrow\"></i>\n </button>\n @if (ShowEntityPicker) {\n <div class=\"entity-picker-dropdown\" (mousedown)=\"$event.stopPropagation()\">\n <div class=\"entity-picker-search\">\n <i class=\"fa-solid fa-search\"></i>\n <input #entitySearchInput\n type=\"text\"\n class=\"entity-picker-search-input\"\n placeholder=\"Filter entities...\"\n [(ngModel)]=\"EntitySearchText\"\n (input)=\"FilterEntities()\"\n (keydown)=\"OnEntityPickerKeyDown($event)\" />\n </div>\n <div class=\"entity-picker-list\">\n @for (group of FilteredEntityGroups; track group.SchemaName) {\n <div class=\"entity-picker-group\">\n <div class=\"entity-picker-group-header\">\n <i class=\"fa-solid fa-database\"></i>\n {{ group.SchemaName }}\n </div>\n @for (entity of group.Entities; track entity.ID) {\n <button class=\"entity-picker-item\"\n [class.entity-picker-item-selected]=\"entity.Name === SuggestEntityName\"\n [class.entity-picker-item-focused]=\"FlatFilteredEntities[SelectedEntityIndex]?.ID === entity.ID\"\n (click)=\"SelectEntity(entity.Name)\">\n <i class=\"fa-solid fa-table\"></i>\n {{ entity.Name }}\n </button>\n }\n </div>\n }\n @if (FilteredEntityGroups.length === 0) {\n <div class=\"entity-picker-empty\">\n No entities matching \"{{ EntitySearchText }}\"\n </div>\n }\n </div>\n </div>\n }\n </div>\n </div>\n <div class=\"suggest-field\">\n <label class=\"suggest-label\">Use Case</label>\n <div class=\"use-case-options\">\n <button class=\"use-case-btn\"\n [class.use-case-btn-active]=\"SuggestUseCase === 'duplicate detection'\"\n (click)=\"SuggestUseCase = 'duplicate detection'\">\n <i class=\"fa-solid fa-clone\"></i>\n Duplicate Detection\n </button>\n <button class=\"use-case-btn\"\n [class.use-case-btn-active]=\"SuggestUseCase === 'search'\"\n (click)=\"SuggestUseCase = 'search'\">\n <i class=\"fa-solid fa-magnifying-glass\"></i>\n Search\n </button>\n <button class=\"use-case-btn\"\n [class.use-case-btn-active]=\"SuggestUseCase === 'classification'\"\n (click)=\"SuggestUseCase = 'classification'\">\n <i class=\"fa-solid fa-tags\"></i>\n Classification\n </button>\n </div>\n </div>\n <button class=\"suggest-submit-btn\"\n [disabled]=\"IsSuggesting || !SuggestEntityName\"\n (click)=\"RunSuggestion()\">\n @if (IsSuggesting) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Generating with AI...\n } @else {\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i> Generate Template\n }\n </button>\n @if (SuggestionError) {\n <mj-alert Variant=\"error\" Size=\"sm\">{{ SuggestionError }}</mj-alert>\n }\n </div>\n } @else {\n <div class=\"suggest-result\">\n <div class=\"result-section\">\n <h4 class=\"result-heading\">Suggested Template</h4>\n <div class=\"template-editor-wrapper\">\n <mj-code-editor\n [value]=\"EditableTemplate\"\n language=\"markdown\"\n [readonly]=\"false\"\n [lineWrapping]=\"true\"\n (change)=\"OnTemplateChange($event)\">\n </mj-code-editor>\n </div>\n </div>\n <div class=\"result-section\">\n <h4 class=\"result-heading\">Selected Fields</h4>\n <div class=\"result-tags\">\n @for (field of SuggestionResult.selectedFields; track field) {\n <span class=\"result-tag\">{{ field }}</span>\n }\n </div>\n </div>\n @if ((SuggestionResult.selectedRelationships?.length ?? 0) > 0) {\n <div class=\"result-section\">\n <h4 class=\"result-heading\">Related Entities</h4>\n @for (rel of SuggestionResult.selectedRelationships; track rel.name) {\n <div class=\"result-relationship\">\n <span class=\"rel-name\">{{ rel.name }}</span>\n <span class=\"rel-fields\">{{ rel.fields.join(', ') }}</span>\n </div>\n }\n </div>\n }\n <div class=\"result-section result-thresholds\">\n <div class=\"threshold-item\">\n <span class=\"threshold-label\">Potential Match</span>\n <span class=\"threshold-value\">{{ (SuggestionResult.potentialMatchThreshold * 100).toFixed(0) }}%</span>\n </div>\n <div class=\"threshold-item\">\n <span class=\"threshold-label\">Absolute Match</span>\n <span class=\"threshold-value\">{{ (SuggestionResult.absoluteMatchThreshold * 100).toFixed(0) }}%</span>\n </div>\n </div>\n <div class=\"result-section\">\n <h4 class=\"result-heading\">Reasoning</h4>\n <p class=\"result-reasoning\">{{ SuggestionResult.reasoning }}</p>\n </div>\n <div class=\"result-section\">\n <div class=\"suggest-field\">\n <label class=\"suggest-label\">Document Name</label>\n <input class=\"suggest-input\" type=\"text\" [(ngModel)]=\"SaveDocumentName\" />\n </div>\n <div class=\"suggest-field\" style=\"margin-top: 0.75rem\">\n <label class=\"suggest-label\">Embedding Model</label>\n <select class=\"suggest-select\" [(ngModel)]=\"SelectedEmbeddingModelID\">\n @for (model of AvailableEmbeddingModels; track model.ID) {\n <option [value]=\"model.ID\">{{ model.Name }}</option>\n }\n </select>\n </div>\n <div class=\"suggest-field\" style=\"margin-top: 0.75rem\">\n <label class=\"suggest-label\">Vector Database</label>\n <select class=\"suggest-select\" [(ngModel)]=\"SelectedVectorDBID\">\n @for (db of vectorDatabases; track db.ID) {\n <option [value]=\"db.ID\">{{ db.Name }}</option>\n }\n </select>\n </div>\n <div class=\"suggest-field\" style=\"margin-top: 0.75rem\">\n <label class=\"suggest-label\">Vector Index</label>\n @if (FilteredIndexesForSelectedDB.length > 0) {\n <select class=\"suggest-select\" [(ngModel)]=\"SelectedVectorIndexID\">\n <option value=\"\">Auto (create/find matching index)</option>\n @for (idx of FilteredIndexesForSelectedDB; track idx.ID) {\n <option [value]=\"idx.ID\">{{ idx.Name }}</option>\n }\n </select>\n } @else {\n <span class=\"edit-readonly-value\" style=\"font-size: 13px; color: var(--mj-text-muted);\">\n No indexes yet \u2014 create one in Configuration > Vector Database, or one will be created on sync\n </span>\n }\n </div>\n </div>\n <div class=\"result-actions\">\n @if (IsSavingDocument) {\n <div class=\"save-spinner\">\n <mj-loading text=\"Saving...\" size=\"small\"></mj-loading>\n </div>\n } @else {\n <button class=\"suggest-submit-btn\" (click)=\"SaveAsEntityDocument()\">\n <i class=\"fa-solid fa-floppy-disk\"></i> Save as Entity Document\n </button>\n <button class=\"suggest-submit-btn suggest-try-again-btn\" (click)=\"ClearSuggestion()\">\n <i class=\"fa-solid fa-rotate\"></i> Try Again\n </button>\n <button class=\"suggest-close-action\" (click)=\"CloseSuggestDialog()\">\n Close\n </button>\n }\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n }\n}\n</ng-template>\n", styles: ["/* ================================================================\n Vector Management Dashboard\n All colors use MJ design tokens from _tokens.scss\n ================================================================ */\n\n\n/* --- Loading state --- */\n.vector-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 400px;\n}\n\n/* --- View Mode Toggle --- */\n.view-mode-toggle {\n display: flex;\n gap: 0.25rem;\n padding: 0 24px 0;\n margin-bottom: -12px;\n}\n\n.view-mode-btn {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n padding: 0.4rem 0.85rem;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 0.82rem;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.view-mode-btn:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n}\n\n.view-mode-btn-active {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n/* --- Dashboard container --- */\n.vector-dashboard {\n display: flex;\n flex-direction: column;\n gap: 24px;\n padding: 24px;\n background: var(--mj-bg-page);\n min-height: 100%;\n}\n\n/* --- KPI cards row --- */\n.kpi-row {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 16px;\n}\n\n@media (max-width: 1200px) {\n .kpi-row {\n grid-template-columns: repeat(2, 1fr);\n }\n}\n\n@media (max-width: 600px) {\n .kpi-row {\n grid-template-columns: 1fr;\n }\n}\n\n/* --- Main content: table + sidebar --- */\n.content-area {\n display: grid;\n grid-template-columns: 1fr 300px;\n gap: 24px;\n align-items: start;\n}\n\n@media (max-width: 1024px) {\n .content-area {\n grid-template-columns: 1fr;\n }\n}\n\n/* --- Sync table panel --- */\n.sync-table-panel {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n overflow: hidden;\n}\n\n.panel-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.panel-title {\n margin: 0;\n font-size: 15px;\n font-weight: 600;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.panel-title i {\n color: var(--mj-brand-primary);\n font-size: 14px;\n}\n\n.refresh-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.refresh-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n border-color: var(--mj-border-strong);\n}\n\n/* --- Table --- */\n.table-wrapper {\n overflow-x: auto;\n}\n\n.sync-table {\n width: 100%;\n border-collapse: collapse;\n}\n\n.sync-table th {\n padding: 10px 16px;\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n text-align: left;\n white-space: nowrap;\n}\n\n.sync-table td {\n padding: 12px 16px;\n font-size: 13px;\n color: var(--mj-text-primary);\n border-bottom: 1px solid var(--mj-border-subtle);\n vertical-align: middle;\n}\n\n.sync-table tbody tr:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.sync-table tbody tr:last-child td {\n border-bottom: none;\n}\n\n.text-right {\n text-align: right;\n}\n\n.text-center {\n text-align: center;\n}\n\n.entity-name {\n font-weight: 600;\n}\n\n.document-name {\n color: var(--mj-text-secondary);\n}\n\n.vector-count {\n font-variant-numeric: tabular-nums;\n font-weight: 600;\n}\n\n.last-synced {\n color: var(--mj-text-secondary);\n font-size: 12px;\n white-space: nowrap;\n}\n\n/* --- Action buttons in table --- */\n\n.actions-cell {\n display: flex;\n gap: 6px;\n align-items: center;\n justify-content: center;\n}\n\n.schedule-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 30px;\n height: 30px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: transparent;\n color: var(--mj-text-muted);\n font-size: 12px;\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.schedule-btn:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n}\n\n.edit-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 30px;\n height: 30px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: transparent;\n color: var(--mj-text-muted);\n font-size: 12px;\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.edit-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n border-color: var(--mj-border-strong);\n}\n\n/* --- Schedule Dialog --- */\n.schedule-dialog {\n width: 440px;\n max-width: 90vw;\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.2);\n overflow: hidden;\n}\n\n.schedule-cron-preview {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 0 0;\n font-size: 0.82rem;\n color: var(--mj-text-muted);\n}\n\n.schedule-toggle-row {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: 12px;\n}\n\n.edit-delete-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n border: 1px solid var(--mj-status-error-border);\n border-radius: 6px;\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n color: var(--mj-status-error-text);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.edit-delete-btn:hover {\n background: color-mix(in srgb, var(--mj-status-error) 20%, var(--mj-bg-surface));\n}\n\n.edit-readonly-value {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n padding: 8px 0;\n}\n\n/* --- Status badges --- */\n.status-badge {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 10px;\n border-radius: 999px;\n font-size: 11px;\n font-weight: 600;\n white-space: nowrap;\n}\n\n.status-synced {\n background: color-mix(in srgb, var(--mj-status-success) 12%, var(--mj-bg-surface));\n color: var(--mj-status-success-text, var(--mj-status-success));\n}\n\n.status-syncing {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.status-error {\n background: color-mix(in srgb, var(--mj-status-error) 12%, var(--mj-bg-surface));\n color: var(--mj-status-error-text, var(--mj-status-error));\n}\n\n.status-pending {\n background: color-mix(in srgb, var(--mj-status-warning) 12%, var(--mj-bg-surface));\n color: var(--mj-status-warning-text, var(--mj-status-warning));\n}\n\n/* --- Sync button --- */\n.sync-btn {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 5px 12px;\n border: 1px solid var(--mj-brand-primary);\n border-radius: 6px;\n background: transparent;\n color: var(--mj-brand-primary);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.sync-btn:hover:not(:disabled) {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.sync-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n/* ================================================================\n Sidebar\n ================================================================ */\n.sidebar {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.sidebar-card {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n padding: 16px 20px;\n}\n\n.sidebar-title {\n margin: 0 0 14px 0;\n font-size: 13px;\n font-weight: 700;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.sidebar-title i {\n color: var(--mj-brand-primary);\n font-size: 13px;\n}\n\n/* --- Vector DB Health --- */\n.health-row {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 6px;\n}\n\n.health-dot {\n width: 10px;\n height: 10px;\n border-radius: 50%;\n flex-shrink: 0;\n}\n\n.health-healthy {\n background: var(--mj-status-success);\n box-shadow: 0 0 6px color-mix(in srgb, var(--mj-status-success) 50%, transparent);\n}\n\n.health-degraded {\n background: var(--mj-status-warning);\n box-shadow: 0 0 6px color-mix(in srgb, var(--mj-status-warning) 50%, transparent);\n}\n\n.health-offline {\n background: var(--mj-status-error);\n box-shadow: 0 0 6px color-mix(in srgb, var(--mj-status-error) 50%, transparent);\n}\n\n.health-label {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.health-status {\n font-size: 12px;\n color: var(--mj-text-muted);\n padding-left: 18px;\n}\n\n.health-reason {\n font-size: 11px;\n line-height: 1.4;\n color: var(--mj-text-muted);\n padding-left: 18px;\n margin-top: 4px;\n}\n\n/* --- Model Info --- */\n.model-info {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.info-row {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.info-label {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.info-value {\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n/* --- Storage / Coverage Gauge --- */\n.gauge-container {\n margin-bottom: 8px;\n}\n\n.gauge-bar {\n height: 8px;\n border-radius: 4px;\n background: var(--mj-bg-surface-sunken);\n overflow: hidden;\n margin-bottom: 6px;\n}\n\n.gauge-fill {\n height: 100%;\n border-radius: 4px;\n background: var(--mj-brand-primary);\n transition: width 0.6s cubic-bezier(0.4, 0, 0.2, 1);\n min-width: 2px;\n}\n\n.gauge-label {\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n.storage-detail {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n/* --- Panel actions row --- */\n.panel-actions {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n/* --- Suggest Document Button --- */\n.suggest-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border: 1px solid var(--mj-brand-primary);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.suggest-btn:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary-hover);\n}\n\n/* --- Slide-in Panel Overlay --- */\n.slide-panel-overlay {\n position: fixed;\n inset: 0;\n background: var(--mj-bg-overlay);\n z-index: 100000;\n}\n\n.slide-panel {\n position: fixed;\n top: 0;\n right: 0;\n height: 100vh;\n width: 480px;\n max-width: 90vw;\n background: var(--mj-bg-surface);\n box-shadow: -4px 0 24px color-mix(in srgb, var(--mj-text-primary) 12%, transparent);\n transform: translateX(100%);\n transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n overflow-y: auto;\n}\n\n.slide-panel.open {\n transform: translateX(0);\n}\n\n.suggest-dialog-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px 24px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.suggest-dialog-title {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.suggest-dialog-title i {\n color: var(--mj-brand-primary);\n}\n\n.suggest-close-btn {\n border: none;\n background: none;\n color: var(--mj-text-muted);\n font-size: 16px;\n cursor: pointer;\n padding: 4px;\n}\n\n.suggest-close-btn:hover {\n color: var(--mj-text-primary);\n}\n\n.suggest-dialog-body {\n padding: 24px;\n}\n\n/* --- Suggest Form --- */\n.suggest-form {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.suggest-field {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.suggest-label {\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n.suggest-select {\n padding: 8px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n}\n\n.suggest-select:focus {\n outline: none;\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n/* ---- Use Case Button Group ---- */\n\n.use-case-options {\n display: flex;\n gap: 8px;\n flex-wrap: wrap;\n}\n\n.use-case-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.use-case-btn:hover {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-border-strong);\n color: var(--mj-text-primary);\n}\n\n.use-case-btn-active {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n.use-case-btn i {\n font-size: 12px;\n}\n\n/* ---- Entity Picker (grouped by schema) ---- */\n\n.entity-picker {\n position: relative;\n}\n\n.entity-picker-trigger {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n padding: 9px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n cursor: pointer;\n text-align: left;\n transition: border-color 0.15s;\n}\n\n.entity-picker-trigger:hover {\n border-color: var(--mj-border-strong);\n}\n\n.entity-picker-placeholder {\n color: var(--mj-text-muted);\n flex: 1;\n}\n\n.entity-picker-value {\n flex: 1;\n font-weight: 500;\n}\n\n.entity-picker-arrow {\n font-size: 10px;\n color: var(--mj-text-muted);\n transition: transform 0.2s;\n}\n\n.entity-picker-dropdown {\n position: absolute;\n top: calc(100% + 4px);\n left: 0;\n right: 0;\n background: var(--mj-bg-surface-elevated, var(--mj-bg-surface));\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n box-shadow: 0 8px 32px color-mix(in srgb, var(--mj-text-primary) 15%, transparent);\n z-index: 100;\n max-height: 350px;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n.entity-picker-search {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 14px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.entity-picker-search i {\n color: var(--mj-text-muted);\n font-size: 13px;\n}\n\n.entity-picker-search-input {\n flex: 1;\n border: none;\n background: transparent;\n color: var(--mj-text-primary);\n font-size: 13px;\n outline: none;\n}\n\n.entity-picker-search-input::placeholder {\n color: var(--mj-text-disabled);\n}\n\n.entity-picker-list {\n overflow-y: auto;\n max-height: 300px;\n padding: 4px 0;\n}\n\n.entity-picker-group-header {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 14px 4px;\n font-size: 11px;\n font-weight: 700;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n position: sticky;\n top: 0;\n background: var(--mj-bg-surface-elevated, var(--mj-bg-surface));\n}\n\n.entity-picker-group-header i {\n font-size: 10px;\n}\n\n.entity-picker-item {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n padding: 7px 14px 7px 28px;\n border: none;\n background: transparent;\n color: var(--mj-text-primary);\n font-size: 13px;\n cursor: pointer;\n text-align: left;\n transition: background 0.1s;\n}\n\n.entity-picker-item:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.entity-picker-item-selected {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n.entity-picker-item i {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.entity-picker-item-selected i {\n color: var(--mj-brand-primary);\n}\n\n.entity-picker-item-focused {\n background: var(--mj-bg-surface-hover);\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: -2px;\n}\n\n.entity-picker-empty {\n padding: 20px 14px;\n text-align: center;\n color: var(--mj-text-disabled);\n font-size: 13px;\n}\n\n/* ---- Template Editor ---- */\n\n.template-editor-wrapper {\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n min-height: 120px;\n max-height: 300px;\n}\n\n.template-editor-wrapper ::ng-deep .cm-editor {\n min-height: 120px;\n max-height: 300px;\n font-size: 13px;\n}\n\n.suggest-submit-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n padding: 10px 20px;\n border: none;\n border-radius: 6px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.2s ease;\n}\n\n.suggest-submit-btn:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n\n.suggest-submit-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n/* --- Suggestion Result --- */\n.suggest-result {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.result-section {\n border-bottom: 1px solid var(--mj-border-subtle);\n padding-bottom: 12px;\n}\n\n.result-section:last-child {\n border-bottom: none;\n}\n\n.result-heading {\n margin: 0 0 8px 0;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.result-template {\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 6px;\n padding: 12px;\n font-size: 12px;\n color: var(--mj-text-primary);\n white-space: pre-wrap;\n word-break: break-all;\n margin: 0;\n}\n\n.result-tags {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n}\n\n.result-tag {\n padding: 3px 10px;\n border-radius: 12px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 12px;\n font-weight: 500;\n}\n\n.result-relationship {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 4px 0;\n}\n\n.rel-name {\n font-weight: 600;\n font-size: 13px;\n color: var(--mj-text-primary);\n}\n\n.rel-fields {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.result-thresholds {\n display: flex;\n gap: 24px;\n}\n\n.threshold-item {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.threshold-label {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.threshold-value {\n font-size: 18px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.result-reasoning {\n margin: 0;\n font-size: 13px;\n color: var(--mj-text-secondary);\n line-height: 1.5;\n}\n\n.result-actions {\n display: flex;\n gap: 8px;\n padding-top: 8px;\n}\n\n.suggest-close-action {\n padding: 10px 20px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n}\n\n.suggest-close-action:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n/* --- Suggest Input --- */\n.suggest-input {\n padding: 8px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n width: 100%;\n box-sizing: border-box;\n}\n\n.suggest-input:focus {\n outline: none;\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n/* --- Try Again Button (secondary style) --- */\n.suggest-try-again-btn {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n border: 1px solid var(--mj-brand-primary);\n}\n\n.suggest-try-again-btn:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n/* --- Save Spinner --- */\n.save-spinner {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 8px 0;\n}\n\n/* --- Edit Panel Template Header --- */\n.edit-template-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n}\n\n.edit-regenerate-btn {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 10px;\n border: 1px solid var(--mj-brand-primary);\n border-radius: 6px;\n background: transparent;\n color: var(--mj-brand-primary);\n font-size: 11px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n white-space: nowrap;\n}\n\n.edit-regenerate-btn:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.edit-regenerate-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n/* --- No Vector Index Warning Dialog --- */\n.no-index-warning-dialog {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 440px;\n max-width: 90vw;\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: 0 20px 60px color-mix(in srgb, var(--mj-text-primary) 20%, transparent);\n padding: 32px;\n text-align: center;\n}\n\n.no-index-warning-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 56px;\n height: 56px;\n margin: 0 auto 16px;\n border-radius: 50%;\n background: color-mix(in srgb, var(--mj-status-warning) 12%, var(--mj-bg-surface));\n}\n\n.no-index-warning-icon i {\n font-size: 24px;\n color: var(--mj-status-warning);\n}\n\n.no-index-warning-title {\n margin: 0 0 8px 0;\n font-size: 18px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.no-index-warning-message {\n margin: 0 0 24px 0;\n font-size: 14px;\n line-height: 1.5;\n color: var(--mj-text-secondary);\n}\n\n.no-index-warning-actions {\n display: flex;\n gap: 8px;\n justify-content: center;\n}\n\n/* ================================================================\n Responsive \u2014 Vector Management\n ================================================================ */\n\n@media (max-width: 768px) {\n .panel-header {\n flex-direction: column;\n align-items: flex-start;\n gap: 12px;\n }\n\n .panel-actions {\n flex-wrap: wrap;\n }\n}\n\n@media (max-width: 600px) {\n .slide-panel {\n width: 100vw;\n max-width: 100vw;\n }\n}\n\n@media (max-width: 480px) {\n .vector-dashboard {\n padding: 12px;\n }\n\n .suggest-btn .suggest-btn-text {\n display: none;\n }\n}\n"] }]
2787
+ 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\" (ngModelChange)=\"OnEditEmbeddingModelChange($event)\">\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\" (ngModelChange)=\"OnEditVectorDBChange($event)\">\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\" (ngModelChange)=\"OnEditVectorIndexChange($event)\">\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\" (ngModelChange)=\"OnSuggestEmbeddingModelChange($event)\">\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\" (ngModelChange)=\"OnSuggestVectorDBChange($event)\">\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\" (ngModelChange)=\"OnSuggestVectorIndexChange($event)\">\n <option value=\"\">Auto (create/find matching index)</option>\n @for (idx of FilteredIndexesForSelectedDB; track idx.ID) {\n <option [value]=\"idx.ID\">{{ idx.Name }}</option>\n }\n </select>\n } @else {\n <span class=\"edit-readonly-value\" style=\"font-size: 13px; color: var(--mj-text-muted);\">\n No indexes yet \u2014 create one in Configuration > Vector Database, or one will be created on sync\n </span>\n }\n </div>\n </div>\n <div class=\"result-actions\">\n @if (IsSavingDocument) {\n <div class=\"save-spinner\">\n <mj-loading text=\"Saving...\" size=\"small\"></mj-loading>\n </div>\n } @else {\n <button class=\"suggest-submit-btn\" (click)=\"SaveAsEntityDocument()\">\n <i class=\"fa-solid fa-floppy-disk\"></i> Save as Entity Document\n </button>\n <button class=\"suggest-submit-btn suggest-try-again-btn\" (click)=\"ClearSuggestion()\">\n <i class=\"fa-solid fa-rotate\"></i> Try Again\n </button>\n <button class=\"suggest-close-action\" (click)=\"CloseSuggestDialog()\">\n Close\n </button>\n }\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n }\n}\n</ng-template>\n", styles: ["/* ================================================================\n Vector Management Dashboard\n All colors use MJ design tokens from _tokens.scss\n ================================================================ */\n\n\n/* --- Loading state --- */\n.vector-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 400px;\n}\n\n/* --- View Mode Toggle --- */\n.view-mode-toggle {\n display: flex;\n gap: 0.25rem;\n padding: 0 24px 0;\n margin-bottom: -12px;\n}\n\n.view-mode-btn {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n padding: 0.4rem 0.85rem;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 0.82rem;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.view-mode-btn:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n}\n\n.view-mode-btn-active {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n/* --- Dashboard container --- */\n.vector-dashboard {\n display: flex;\n flex-direction: column;\n gap: 24px;\n padding: 24px;\n background: var(--mj-bg-page);\n min-height: 100%;\n}\n\n/* --- KPI cards row --- */\n.kpi-row {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 16px;\n}\n\n@media (max-width: 1200px) {\n .kpi-row {\n grid-template-columns: repeat(2, 1fr);\n }\n}\n\n@media (max-width: 600px) {\n .kpi-row {\n grid-template-columns: 1fr;\n }\n}\n\n/* --- Main content: table + sidebar --- */\n.content-area {\n display: grid;\n grid-template-columns: 1fr 300px;\n gap: 24px;\n align-items: start;\n}\n\n@media (max-width: 1024px) {\n .content-area {\n grid-template-columns: 1fr;\n }\n}\n\n/* --- Sync table panel --- */\n.sync-table-panel {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n overflow: hidden;\n}\n\n.panel-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.panel-title {\n margin: 0;\n font-size: 15px;\n font-weight: 600;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.panel-title i {\n color: var(--mj-brand-primary);\n font-size: 14px;\n}\n\n.refresh-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.refresh-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n border-color: var(--mj-border-strong);\n}\n\n/* --- Table --- */\n.table-wrapper {\n overflow-x: auto;\n}\n\n.sync-table {\n width: 100%;\n border-collapse: collapse;\n}\n\n.sync-table th {\n padding: 10px 16px;\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n text-align: left;\n white-space: nowrap;\n}\n\n.sync-table td {\n padding: 12px 16px;\n font-size: 13px;\n color: var(--mj-text-primary);\n border-bottom: 1px solid var(--mj-border-subtle);\n vertical-align: middle;\n}\n\n.sync-table tbody tr:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.sync-table tbody tr:last-child td {\n border-bottom: none;\n}\n\n.text-right {\n text-align: right;\n}\n\n.text-center {\n text-align: center;\n}\n\n.entity-name {\n font-weight: 600;\n}\n\n.document-name {\n color: var(--mj-text-secondary);\n}\n\n.document-type {\n color: var(--mj-text-secondary);\n white-space: nowrap;\n}\n\n.vector-count {\n font-variant-numeric: tabular-nums;\n font-weight: 600;\n}\n\n.last-synced {\n color: var(--mj-text-secondary);\n font-size: 12px;\n white-space: nowrap;\n}\n\n/* --- Action buttons in table --- */\n\n.actions-cell {\n display: flex;\n gap: 6px;\n align-items: center;\n justify-content: center;\n}\n\n.schedule-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 30px;\n height: 30px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: transparent;\n color: var(--mj-text-muted);\n font-size: 12px;\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.schedule-btn:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n}\n\n.edit-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 30px;\n height: 30px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: transparent;\n color: var(--mj-text-muted);\n font-size: 12px;\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.edit-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n border-color: var(--mj-border-strong);\n}\n\n/* --- Schedule Dialog --- */\n.schedule-dialog {\n width: 440px;\n max-width: 90vw;\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.2);\n overflow: hidden;\n}\n\n.schedule-cron-preview {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 0 0;\n font-size: 0.82rem;\n color: var(--mj-text-muted);\n}\n\n.schedule-toggle-row {\n display: flex;\n flex-direction: row;\n align-items: center;\n gap: 12px;\n}\n\n.edit-delete-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n border: 1px solid var(--mj-status-error-border);\n border-radius: 6px;\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n color: var(--mj-status-error-text);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.edit-delete-btn:hover {\n background: color-mix(in srgb, var(--mj-status-error) 20%, var(--mj-bg-surface));\n}\n\n.edit-readonly-value {\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-primary);\n padding: 8px 0;\n}\n\n/* --- Status badges --- */\n.status-badge {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 10px;\n border-radius: 999px;\n font-size: 11px;\n font-weight: 600;\n white-space: nowrap;\n}\n\n.status-synced {\n background: color-mix(in srgb, var(--mj-status-success) 12%, var(--mj-bg-surface));\n color: var(--mj-status-success-text, var(--mj-status-success));\n}\n\n.status-syncing {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n}\n\n.status-error {\n background: color-mix(in srgb, var(--mj-status-error) 12%, var(--mj-bg-surface));\n color: var(--mj-status-error-text, var(--mj-status-error));\n}\n\n.status-pending {\n background: color-mix(in srgb, var(--mj-status-warning) 12%, var(--mj-bg-surface));\n color: var(--mj-status-warning-text, var(--mj-status-warning));\n}\n\n/* --- Sync button --- */\n.sync-btn {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 5px 12px;\n border: 1px solid var(--mj-brand-primary);\n border-radius: 6px;\n background: transparent;\n color: var(--mj-brand-primary);\n font-size: 12px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.sync-btn:hover:not(:disabled) {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.sync-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n/* ================================================================\n Sidebar\n ================================================================ */\n.sidebar {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.sidebar-card {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n padding: 16px 20px;\n}\n\n.sidebar-title {\n margin: 0 0 14px 0;\n font-size: 13px;\n font-weight: 700;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.sidebar-title i {\n color: var(--mj-brand-primary);\n font-size: 13px;\n}\n\n/* --- Vector DB Health --- */\n.health-row {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 6px;\n}\n\n.health-dot {\n width: 10px;\n height: 10px;\n border-radius: 50%;\n flex-shrink: 0;\n}\n\n.health-healthy {\n background: var(--mj-status-success);\n box-shadow: 0 0 6px color-mix(in srgb, var(--mj-status-success) 50%, transparent);\n}\n\n.health-degraded {\n background: var(--mj-status-warning);\n box-shadow: 0 0 6px color-mix(in srgb, var(--mj-status-warning) 50%, transparent);\n}\n\n.health-offline {\n background: var(--mj-status-error);\n box-shadow: 0 0 6px color-mix(in srgb, var(--mj-status-error) 50%, transparent);\n}\n\n.health-label {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.health-status {\n font-size: 12px;\n color: var(--mj-text-muted);\n padding-left: 18px;\n}\n\n.health-reason {\n font-size: 11px;\n line-height: 1.4;\n color: var(--mj-text-muted);\n padding-left: 18px;\n margin-top: 4px;\n}\n\n/* --- Model Info --- */\n.model-info {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.info-row {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.info-label {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.info-value {\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n/* --- Storage / Coverage Gauge --- */\n.gauge-container {\n margin-bottom: 8px;\n}\n\n.gauge-bar {\n height: 8px;\n border-radius: 4px;\n background: var(--mj-bg-surface-sunken);\n overflow: hidden;\n margin-bottom: 6px;\n}\n\n.gauge-fill {\n height: 100%;\n border-radius: 4px;\n background: var(--mj-brand-primary);\n transition: width 0.6s cubic-bezier(0.4, 0, 0.2, 1);\n min-width: 2px;\n}\n\n.gauge-label {\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n.storage-detail {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n/* --- Panel actions row --- */\n.panel-actions {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n/* --- Suggest Document Button --- */\n.suggest-btn {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border: 1px solid var(--mj-brand-primary);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.suggest-btn:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary-hover);\n}\n\n/* --- Slide-in Panel Overlay --- */\n.slide-panel-overlay {\n position: fixed;\n inset: 0;\n background: var(--mj-bg-overlay);\n z-index: 100000;\n}\n\n.slide-panel {\n position: fixed;\n top: 0;\n right: 0;\n height: 100vh;\n width: 480px;\n max-width: 90vw;\n background: var(--mj-bg-surface);\n box-shadow: -4px 0 24px color-mix(in srgb, var(--mj-text-primary) 12%, transparent);\n transform: translateX(100%);\n transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n overflow-y: auto;\n}\n\n.slide-panel.open {\n transform: translateX(0);\n}\n\n.suggest-dialog-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px 24px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.suggest-dialog-title {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.suggest-dialog-title i {\n color: var(--mj-brand-primary);\n}\n\n.suggest-close-btn {\n border: none;\n background: none;\n color: var(--mj-text-muted);\n font-size: 16px;\n cursor: pointer;\n padding: 4px;\n}\n\n.suggest-close-btn:hover {\n color: var(--mj-text-primary);\n}\n\n.suggest-dialog-body {\n padding: 24px;\n}\n\n/* --- Suggest Form --- */\n.suggest-form {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.suggest-field {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.suggest-label {\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n.suggest-select {\n padding: 8px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n}\n\n.suggest-select:focus {\n outline: none;\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n/* ---- Use Case Button Group ---- */\n\n.use-case-options {\n display: flex;\n gap: 8px;\n flex-wrap: wrap;\n}\n\n.use-case-btn {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.use-case-btn:hover {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-border-strong);\n color: var(--mj-text-primary);\n}\n\n.use-case-btn-active {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n.use-case-btn i {\n font-size: 12px;\n}\n\n/* ---- Entity Picker (grouped by schema) ---- */\n\n.entity-picker {\n position: relative;\n}\n\n.entity-picker-trigger {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n padding: 9px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n cursor: pointer;\n text-align: left;\n transition: border-color 0.15s;\n}\n\n.entity-picker-trigger:hover {\n border-color: var(--mj-border-strong);\n}\n\n.entity-picker-placeholder {\n color: var(--mj-text-muted);\n flex: 1;\n}\n\n.entity-picker-value {\n flex: 1;\n font-weight: 500;\n}\n\n.entity-picker-arrow {\n font-size: 10px;\n color: var(--mj-text-muted);\n transition: transform 0.2s;\n}\n\n.entity-picker-dropdown {\n position: absolute;\n top: calc(100% + 4px);\n left: 0;\n right: 0;\n background: var(--mj-bg-surface-elevated, var(--mj-bg-surface));\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n box-shadow: 0 8px 32px color-mix(in srgb, var(--mj-text-primary) 15%, transparent);\n z-index: 100;\n max-height: 350px;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n.entity-picker-search {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 14px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.entity-picker-search i {\n color: var(--mj-text-muted);\n font-size: 13px;\n}\n\n.entity-picker-search-input {\n flex: 1;\n border: none;\n background: transparent;\n color: var(--mj-text-primary);\n font-size: 13px;\n outline: none;\n}\n\n.entity-picker-search-input::placeholder {\n color: var(--mj-text-disabled);\n}\n\n.entity-picker-list {\n overflow-y: auto;\n max-height: 300px;\n padding: 4px 0;\n}\n\n.entity-picker-group-header {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 14px 4px;\n font-size: 11px;\n font-weight: 700;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n position: sticky;\n top: 0;\n background: var(--mj-bg-surface-elevated, var(--mj-bg-surface));\n}\n\n.entity-picker-group-header i {\n font-size: 10px;\n}\n\n.entity-picker-item {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n padding: 7px 14px 7px 28px;\n border: none;\n background: transparent;\n color: var(--mj-text-primary);\n font-size: 13px;\n cursor: pointer;\n text-align: left;\n transition: background 0.1s;\n}\n\n.entity-picker-item:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.entity-picker-item-selected {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n.entity-picker-item i {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.entity-picker-item-selected i {\n color: var(--mj-brand-primary);\n}\n\n.entity-picker-item-focused {\n background: var(--mj-bg-surface-hover);\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: -2px;\n}\n\n.entity-picker-empty {\n padding: 20px 14px;\n text-align: center;\n color: var(--mj-text-disabled);\n font-size: 13px;\n}\n\n/* ---- Template Editor ---- */\n\n.template-editor-wrapper {\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n overflow: hidden;\n min-height: 120px;\n max-height: 300px;\n}\n\n.template-editor-wrapper ::ng-deep .cm-editor {\n min-height: 120px;\n max-height: 300px;\n font-size: 13px;\n}\n\n.suggest-submit-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n padding: 10px 20px;\n border: none;\n border-radius: 6px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.2s ease;\n}\n\n.suggest-submit-btn:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n\n.suggest-submit-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n/* --- Suggestion Result --- */\n.suggest-result {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.result-section {\n border-bottom: 1px solid var(--mj-border-subtle);\n padding-bottom: 12px;\n}\n\n.result-section:last-child {\n border-bottom: none;\n}\n\n.result-heading {\n margin: 0 0 8px 0;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.result-template {\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 6px;\n padding: 12px;\n font-size: 12px;\n color: var(--mj-text-primary);\n white-space: pre-wrap;\n word-break: break-all;\n margin: 0;\n}\n\n.result-tags {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n}\n\n.result-tag {\n padding: 3px 10px;\n border-radius: 12px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 12px;\n font-weight: 500;\n}\n\n.result-relationship {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 4px 0;\n}\n\n.rel-name {\n font-weight: 600;\n font-size: 13px;\n color: var(--mj-text-primary);\n}\n\n.rel-fields {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.result-thresholds {\n display: flex;\n gap: 24px;\n}\n\n.threshold-item {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.threshold-label {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.threshold-value {\n font-size: 18px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.result-reasoning {\n margin: 0;\n font-size: 13px;\n color: var(--mj-text-secondary);\n line-height: 1.5;\n}\n\n.result-actions {\n display: flex;\n gap: 8px;\n padding-top: 8px;\n}\n\n.suggest-close-action {\n padding: 10px 20px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n}\n\n.suggest-close-action:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n/* --- Suggest Input --- */\n.suggest-input {\n padding: 8px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font-size: 13px;\n width: 100%;\n box-sizing: border-box;\n}\n\n.suggest-input:focus {\n outline: none;\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n/* --- Try Again Button (secondary style) --- */\n.suggest-try-again-btn {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n border: 1px solid var(--mj-brand-primary);\n}\n\n.suggest-try-again-btn:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n/* --- Save Spinner --- */\n.save-spinner {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 8px 0;\n}\n\n/* --- Edit Panel Template Header --- */\n.edit-template-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n}\n\n.edit-regenerate-btn {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 10px;\n border: 1px solid var(--mj-brand-primary);\n border-radius: 6px;\n background: transparent;\n color: var(--mj-brand-primary);\n font-size: 11px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n white-space: nowrap;\n}\n\n.edit-regenerate-btn:hover:not(:disabled) {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.edit-regenerate-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n/* --- No Vector Index Warning Dialog --- */\n.no-index-warning-dialog {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 440px;\n max-width: 90vw;\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: 0 20px 60px color-mix(in srgb, var(--mj-text-primary) 20%, transparent);\n padding: 32px;\n text-align: center;\n}\n\n.no-index-warning-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 56px;\n height: 56px;\n margin: 0 auto 16px;\n border-radius: 50%;\n background: color-mix(in srgb, var(--mj-status-warning) 12%, var(--mj-bg-surface));\n}\n\n.no-index-warning-icon i {\n font-size: 24px;\n color: var(--mj-status-warning);\n}\n\n.no-index-warning-title {\n margin: 0 0 8px 0;\n font-size: 18px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.no-index-warning-message {\n margin: 0 0 24px 0;\n font-size: 14px;\n line-height: 1.5;\n color: var(--mj-text-secondary);\n}\n\n.no-index-warning-actions {\n display: flex;\n gap: 8px;\n justify-content: center;\n}\n\n/* ================================================================\n Responsive \u2014 Vector Management\n ================================================================ */\n\n@media (max-width: 768px) {\n .panel-header {\n flex-direction: column;\n align-items: flex-start;\n gap: 12px;\n }\n\n .panel-actions {\n flex-wrap: wrap;\n }\n}\n\n@media (max-width: 600px) {\n .slide-panel {\n width: 100vw;\n max-width: 100vw;\n }\n}\n\n@media (max-width: 480px) {\n .vector-dashboard {\n padding: 12px;\n }\n\n .suggest-btn .suggest-btn-text {\n display: none;\n }\n}\n"] }]
2513
2788
  }], null, { HideToolbar: [{
2514
2789
  type: Input
2515
2790
  }], EntitySearchInput: [{
2516
2791
  type: ViewChild,
2517
2792
  args: ['entitySearchInput']
2518
2793
  }] }); })();
2519
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(VectorManagementResourceComponent, { className: "VectorManagementResourceComponent", filePath: "src/AI/components/vectors/vector-management-resource.component.ts", lineNumber: 80 }); })();
2794
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(VectorManagementResourceComponent, { className: "VectorManagementResourceComponent", filePath: "src/AI/components/vectors/vector-management-resource.component.ts", lineNumber: 102 }); })();
2520
2795
  export function LoadVectorManagementResource() {
2521
2796
  // Prevents tree-shaking
2522
2797
  }