@memberjunction/ng-dashboards 5.23.0 → 5.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts +677 -5
  2. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts.map +1 -1
  3. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js +6879 -1873
  4. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js.map +1 -1
  5. package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts +46 -1
  6. package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts.map +1 -1
  7. package/dist/AI/components/duplicates/duplicate-detection-resource.component.js +758 -491
  8. package/dist/AI/components/duplicates/duplicate-detection-resource.component.js.map +1 -1
  9. package/dist/AI/components/vectors/vector-management-resource.component.d.ts +19 -0
  10. package/dist/AI/components/vectors/vector-management-resource.component.d.ts.map +1 -1
  11. package/dist/AI/components/vectors/vector-management-resource.component.js +410 -208
  12. package/dist/AI/components/vectors/vector-management-resource.component.js.map +1 -1
  13. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
  14. package/dist/DataExplorer/data-explorer-dashboard.component.js +17 -17
  15. package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
  16. package/dist/Integration/components/activity/activity.component.d.ts.map +1 -1
  17. package/dist/Integration/components/activity/activity.component.js +1 -0
  18. package/dist/Integration/components/activity/activity.component.js.map +1 -1
  19. package/dist/Integration/components/connections/connections.component.d.ts.map +1 -1
  20. package/dist/Integration/components/connections/connections.component.js +1 -0
  21. package/dist/Integration/components/connections/connections.component.js.map +1 -1
  22. package/dist/Integration/components/mapping-workspace/mapping-workspace.component.d.ts.map +1 -1
  23. package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js +1 -0
  24. package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js.map +1 -1
  25. package/dist/Integration/components/overview/overview.component.d.ts.map +1 -1
  26. package/dist/Integration/components/overview/overview.component.js +1 -0
  27. package/dist/Integration/components/overview/overview.component.js.map +1 -1
  28. package/dist/Integration/components/pipelines/pipelines.component.d.ts.map +1 -1
  29. package/dist/Integration/components/pipelines/pipelines.component.js +1 -0
  30. package/dist/Integration/components/pipelines/pipelines.component.js.map +1 -1
  31. package/dist/Integration/components/schedules/schedules.component.d.ts.map +1 -1
  32. package/dist/Integration/components/schedules/schedules.component.js +1 -0
  33. package/dist/Integration/components/schedules/schedules.component.js.map +1 -1
  34. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.d.ts +411 -0
  35. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.d.ts.map +1 -0
  36. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js +4266 -0
  37. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js.map +1 -0
  38. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.d.ts +35 -1
  39. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.d.ts.map +1 -1
  40. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js +186 -13
  41. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js.map +1 -1
  42. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.d.ts +1 -0
  43. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.d.ts.map +1 -1
  44. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js +188 -165
  45. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js.map +1 -1
  46. package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.d.ts +75 -0
  47. package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.d.ts.map +1 -0
  48. package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.js +601 -0
  49. package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.js.map +1 -0
  50. package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.d.ts +93 -12
  51. package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.d.ts.map +1 -1
  52. package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.js +637 -107
  53. package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.js.map +1 -1
  54. package/dist/KnowledgeHub/index.d.ts +2 -0
  55. package/dist/KnowledgeHub/index.d.ts.map +1 -1
  56. package/dist/KnowledgeHub/index.js +2 -0
  57. package/dist/KnowledgeHub/index.js.map +1 -1
  58. package/dist/__tests__/analytics-resource.test.d.ts +2 -0
  59. package/dist/__tests__/analytics-resource.test.d.ts.map +1 -0
  60. package/dist/__tests__/analytics-resource.test.js +181 -0
  61. package/dist/__tests__/analytics-resource.test.js.map +1 -0
  62. package/dist/__tests__/scheduling.test.d.ts +2 -0
  63. package/dist/__tests__/scheduling.test.d.ts.map +1 -0
  64. package/dist/__tests__/scheduling.test.js +205 -0
  65. package/dist/__tests__/scheduling.test.js.map +1 -0
  66. package/dist/ai-dashboards.module.d.ts +18 -14
  67. package/dist/ai-dashboards.module.d.ts.map +1 -1
  68. package/dist/ai-dashboards.module.js +25 -5
  69. package/dist/ai-dashboards.module.js.map +1 -1
  70. package/dist/public-api.d.ts +1 -0
  71. package/dist/public-api.d.ts.map +1 -1
  72. package/dist/public-api.js +1 -0
  73. package/dist/public-api.js.map +1 -1
  74. package/dist/shared/entity-field-display.d.ts +44 -0
  75. package/dist/shared/entity-field-display.d.ts.map +1 -0
  76. package/dist/shared/entity-field-display.js +118 -0
  77. package/dist/shared/entity-field-display.js.map +1 -0
  78. package/package.json +47 -46
@@ -16,11 +16,13 @@ import { Subject } from 'rxjs';
16
16
  import { Metadata, RunView } from '@memberjunction/core';
17
17
  import { KnowledgeHubMetadataEngine } from '@memberjunction/core-entities';
18
18
  import { RegisterClass, UUIDsEqual } from '@memberjunction/global';
19
- import { BaseResourceComponent } from '@memberjunction/ng-shared';
19
+ import { BaseResourceComponent, NavigationService } from '@memberjunction/ng-shared';
20
20
  import { MJNotificationService } from '@memberjunction/ng-notifications';
21
+ import { AIEngineBase } from '@memberjunction/ai-engine-base';
21
22
  import * as i0 from "@angular/core";
22
23
  import * as i1 from "@angular/forms";
23
24
  import * as i2 from "@memberjunction/ng-shared-generic";
25
+ import * as i3 from "../scheduling/scheduling-resource.component";
24
26
  const _forTrack0 = ($index, $item) => $item.ID;
25
27
  const _forTrack1 = ($index, $item) => $item.EntityName;
26
28
  function KnowledgeConfigResourceComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
@@ -30,7 +32,7 @@ function KnowledgeConfigResourceComponent_Conditional_0_Template(rf, ctx) { if (
30
32
  } }
31
33
  function KnowledgeConfigResourceComponent_Conditional_1_For_7_Template(rf, ctx) { if (rf & 1) {
32
34
  const _r1 = i0.ɵɵgetCurrentView();
33
- i0.ɵɵelementStart(0, "button", 10);
35
+ i0.ɵɵelementStart(0, "button", 11);
34
36
  i0.ɵɵlistener("click", function KnowledgeConfigResourceComponent_Conditional_1_For_7_Template_button_click_0_listener() { const section_r2 = i0.ɵɵrestoreView(_r1).$implicit; const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.SelectSection(section_r2.ID)); });
35
37
  i0.ɵɵelement(1, "i");
36
38
  i0.ɵɵelementStart(2, "span");
@@ -47,49 +49,49 @@ function KnowledgeConfigResourceComponent_Conditional_1_For_7_Template(rf, ctx)
47
49
  } }
48
50
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_9_Template(rf, ctx) { if (rf & 1) {
49
51
  const _r4 = i0.ɵɵgetCurrentView();
50
- i0.ɵɵelementStart(0, "div", 8)(1, "h2", 11);
52
+ i0.ɵɵelementStart(0, "div", 8)(1, "h2", 12);
51
53
  i0.ɵɵtext(2, "Pipeline Settings");
52
54
  i0.ɵɵelementEnd();
53
- i0.ɵɵelementStart(3, "p", 12);
55
+ i0.ɵɵelementStart(3, "p", 13);
54
56
  i0.ɵɵtext(4, "Configure how the Knowledge Pipeline processes incoming content.");
55
57
  i0.ɵɵelementEnd();
56
- i0.ɵɵelementStart(5, "div", 13)(6, "label", 14)(7, "div", 15)(8, "span", 16);
58
+ i0.ɵɵelementStart(5, "div", 14)(6, "label", 15)(7, "div", 16)(8, "span", 17);
57
59
  i0.ɵɵtext(9, "Auto-tag on Ingest");
58
60
  i0.ɵɵelementEnd();
59
- i0.ɵɵelementStart(10, "span", 17);
61
+ i0.ɵɵelementStart(10, "span", 18);
60
62
  i0.ɵɵtext(11, "Automatically run autotagging when new content is ingested");
61
63
  i0.ɵɵelementEnd()();
62
- i0.ɵɵelementStart(12, "input", 18);
64
+ i0.ɵɵelementStart(12, "input", 19);
63
65
  i0.ɵɵtwoWayListener("ngModelChange", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_9_Template_input_ngModelChange_12_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r2.PipelineSettings.AutotagOnIngest, $event) || (ctx_r2.PipelineSettings.AutotagOnIngest = $event); return i0.ɵɵresetView($event); });
64
66
  i0.ɵɵlistener("change", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_9_Template_input_change_12_listener() { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.OnSettingChanged()); });
65
67
  i0.ɵɵelementEnd()();
66
- i0.ɵɵelementStart(13, "label", 14)(14, "div", 15)(15, "span", 16);
68
+ i0.ɵɵelementStart(13, "label", 15)(14, "div", 16)(15, "span", 17);
67
69
  i0.ɵɵtext(16, "Vectorize on Ingest");
68
70
  i0.ɵɵelementEnd();
69
- i0.ɵɵelementStart(17, "span", 17);
71
+ i0.ɵɵelementStart(17, "span", 18);
70
72
  i0.ɵɵtext(18, "Automatically create embeddings for new content");
71
73
  i0.ɵɵelementEnd()();
72
- i0.ɵɵelementStart(19, "input", 18);
74
+ i0.ɵɵelementStart(19, "input", 19);
73
75
  i0.ɵɵtwoWayListener("ngModelChange", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_9_Template_input_ngModelChange_19_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r2.PipelineSettings.VectorizeOnIngest, $event) || (ctx_r2.PipelineSettings.VectorizeOnIngest = $event); return i0.ɵɵresetView($event); });
74
76
  i0.ɵɵlistener("change", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_9_Template_input_change_19_listener() { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.OnSettingChanged()); });
75
77
  i0.ɵɵelementEnd()();
76
- i0.ɵɵelementStart(20, "div", 19)(21, "div", 20)(22, "span", 16);
78
+ i0.ɵɵelementStart(20, "div", 20)(21, "div", 21)(22, "span", 17);
77
79
  i0.ɵɵtext(23, "Default Batch Size");
78
80
  i0.ɵɵelementEnd();
79
- i0.ɵɵelementStart(24, "span", 17);
81
+ i0.ɵɵelementStart(24, "span", 18);
80
82
  i0.ɵɵtext(25, "Number of items processed per batch");
81
83
  i0.ɵɵelementEnd()();
82
- i0.ɵɵelementStart(26, "input", 21);
84
+ i0.ɵɵelementStart(26, "input", 22);
83
85
  i0.ɵɵtwoWayListener("ngModelChange", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_9_Template_input_ngModelChange_26_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r2.PipelineSettings.DefaultBatchSize, $event) || (ctx_r2.PipelineSettings.DefaultBatchSize = $event); return i0.ɵɵresetView($event); });
84
86
  i0.ɵɵlistener("input", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_9_Template_input_input_26_listener() { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.OnSettingChanged()); });
85
87
  i0.ɵɵelementEnd()();
86
- i0.ɵɵelementStart(27, "div", 19)(28, "div", 20)(29, "span", 16);
88
+ i0.ɵɵelementStart(27, "div", 20)(28, "div", 21)(29, "span", 17);
87
89
  i0.ɵɵtext(30, "Max Concurrent Jobs");
88
90
  i0.ɵɵelementEnd();
89
- i0.ɵɵelementStart(31, "span", 17);
91
+ i0.ɵɵelementStart(31, "span", 18);
90
92
  i0.ɵɵtext(32, "Maximum number of pipeline jobs running at once");
91
93
  i0.ɵɵelementEnd()();
92
- i0.ɵɵelementStart(33, "input", 22);
94
+ i0.ɵɵelementStart(33, "input", 23);
93
95
  i0.ɵɵtwoWayListener("ngModelChange", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_9_Template_input_ngModelChange_33_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r2.PipelineSettings.MaxConcurrentJobs, $event) || (ctx_r2.PipelineSettings.MaxConcurrentJobs = $event); return i0.ɵɵresetView($event); });
94
96
  i0.ɵɵlistener("input", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_9_Template_input_input_33_listener() { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.OnSettingChanged()); });
95
97
  i0.ɵɵelementEnd()()()();
@@ -105,15 +107,15 @@ function KnowledgeConfigResourceComponent_Conditional_1_Conditional_9_Template(r
105
107
  i0.ɵɵtwoWayProperty("ngModel", ctx_r2.PipelineSettings.MaxConcurrentJobs);
106
108
  } }
107
109
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_16_Template(rf, ctx) { if (rf & 1) {
108
- i0.ɵɵelement(0, "i", 32);
110
+ i0.ɵɵelement(0, "i", 33);
109
111
  } }
110
112
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_17_Template(rf, ctx) { if (rf & 1) {
111
- i0.ɵɵelementStart(0, "span", 33);
113
+ i0.ɵɵelementStart(0, "span", 34);
112
114
  i0.ɵɵtext(1, "1");
113
115
  i0.ɵɵelementEnd();
114
116
  } }
115
117
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_21_Template(rf, ctx) { if (rf & 1) {
116
- i0.ɵɵelementStart(0, "span", 36);
118
+ i0.ɵɵelementStart(0, "span", 37);
117
119
  i0.ɵɵtext(1);
118
120
  i0.ɵɵelementEnd();
119
121
  } if (rf & 2) {
@@ -122,22 +124,22 @@ function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Condition
122
124
  i0.ɵɵtextInterpolate1("", ctx_r2.VectorDBProviders.length, " provider(s) registered");
123
125
  } }
124
126
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_22_Template(rf, ctx) { if (rf & 1) {
125
- i0.ɵɵelementStart(0, "span", 36);
127
+ i0.ɵɵelementStart(0, "span", 37);
126
128
  i0.ɵɵtext(1, "No providers registered. Add a vector database provider (e.g., Pinecone, Weaviate) via the admin console.");
127
129
  i0.ɵɵelementEnd();
128
130
  } }
129
131
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_23_For_2_Template(rf, ctx) { if (rf & 1) {
130
- i0.ɵɵelementStart(0, "div", 40)(1, "div", 41);
131
- i0.ɵɵelement(2, "i", 42);
132
+ i0.ɵɵelementStart(0, "div", 41)(1, "div", 42);
133
+ i0.ɵɵelement(2, "i", 43);
132
134
  i0.ɵɵelementEnd();
133
- i0.ɵɵelementStart(3, "div", 43)(4, "span", 44);
135
+ i0.ɵɵelementStart(3, "div", 44)(4, "span", 45);
134
136
  i0.ɵɵtext(5);
135
137
  i0.ɵɵelementEnd();
136
- i0.ɵɵelementStart(6, "span", 45);
138
+ i0.ɵɵelementStart(6, "span", 46);
137
139
  i0.ɵɵtext(7);
138
140
  i0.ɵɵelementEnd()();
139
- i0.ɵɵelementStart(8, "span", 46);
140
- i0.ɵɵelement(9, "i", 32);
141
+ i0.ɵɵelementStart(8, "span", 47);
142
+ i0.ɵɵelement(9, "i", 33);
141
143
  i0.ɵɵtext(10, " Active ");
142
144
  i0.ɵɵelementEnd()();
143
145
  } if (rf & 2) {
@@ -148,8 +150,8 @@ function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Condition
148
150
  i0.ɵɵtextInterpolate(provider_r5.ClassKey);
149
151
  } }
150
152
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_23_Template(rf, ctx) { if (rf & 1) {
151
- i0.ɵɵelementStart(0, "div", 37);
152
- i0.ɵɵrepeaterCreate(1, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_23_For_2_Template, 11, 2, "div", 40, _forTrack0);
153
+ i0.ɵɵelementStart(0, "div", 38);
154
+ i0.ɵɵrepeaterCreate(1, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_23_For_2_Template, 11, 2, "div", 41, _forTrack0);
153
155
  i0.ɵɵelementEnd();
154
156
  } if (rf & 2) {
155
157
  const ctx_r2 = i0.ɵɵnextContext(3);
@@ -157,15 +159,15 @@ function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Condition
157
159
  i0.ɵɵrepeater(ctx_r2.VectorDBProviders);
158
160
  } }
159
161
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_27_Template(rf, ctx) { if (rf & 1) {
160
- i0.ɵɵelement(0, "i", 32);
162
+ i0.ɵɵelement(0, "i", 33);
161
163
  } }
162
164
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_28_Template(rf, ctx) { if (rf & 1) {
163
- i0.ɵɵelementStart(0, "span", 33);
165
+ i0.ɵɵelementStart(0, "span", 34);
164
166
  i0.ɵɵtext(1, "2");
165
167
  i0.ɵɵelementEnd();
166
168
  } }
167
169
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_32_Template(rf, ctx) { if (rf & 1) {
168
- i0.ɵɵelementStart(0, "span", 36);
170
+ i0.ɵɵelementStart(0, "span", 37);
169
171
  i0.ɵɵtext(1);
170
172
  i0.ɵɵelementEnd();
171
173
  } if (rf & 2) {
@@ -174,12 +176,12 @@ function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Condition
174
176
  i0.ɵɵtextInterpolate1("", ctx_r2.EmbeddingModels.length, " model(s) available");
175
177
  } }
176
178
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_33_Template(rf, ctx) { if (rf & 1) {
177
- i0.ɵɵelementStart(0, "span", 36);
179
+ i0.ɵɵelementStart(0, "span", 37);
178
180
  i0.ɵɵtext(1, "No embedding models found. Configure at least one in the AI app > Models tab.");
179
181
  i0.ɵɵelementEnd();
180
182
  } }
181
183
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_34_For_3_Template(rf, ctx) { if (rf & 1) {
182
- i0.ɵɵelementStart(0, "span", 48);
184
+ i0.ɵɵelementStart(0, "span", 49);
183
185
  i0.ɵɵtext(1);
184
186
  i0.ɵɵelementEnd();
185
187
  } if (rf & 2) {
@@ -188,8 +190,8 @@ function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Condition
188
190
  i0.ɵɵtextInterpolate(model_r6.Name);
189
191
  } }
190
192
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_34_Template(rf, ctx) { if (rf & 1) {
191
- i0.ɵɵelementStart(0, "div", 37)(1, "div", 47);
192
- i0.ɵɵrepeaterCreate(2, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_34_For_3_Template, 2, 1, "span", 48, _forTrack0);
193
+ i0.ɵɵelementStart(0, "div", 38)(1, "div", 48);
194
+ i0.ɵɵrepeaterCreate(2, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_34_For_3_Template, 2, 1, "span", 49, _forTrack0);
193
195
  i0.ɵɵelementEnd()();
194
196
  } if (rf & 2) {
195
197
  const ctx_r2 = i0.ɵɵnextContext(3);
@@ -197,15 +199,15 @@ function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Condition
197
199
  i0.ɵɵrepeater(ctx_r2.EmbeddingModels);
198
200
  } }
199
201
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_38_Template(rf, ctx) { if (rf & 1) {
200
- i0.ɵɵelement(0, "i", 32);
202
+ i0.ɵɵelement(0, "i", 33);
201
203
  } }
202
204
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_39_Template(rf, ctx) { if (rf & 1) {
203
- i0.ɵɵelementStart(0, "span", 33);
205
+ i0.ɵɵelementStart(0, "span", 34);
204
206
  i0.ɵɵtext(1, "3");
205
207
  i0.ɵɵelementEnd();
206
208
  } }
207
209
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_43_Template(rf, ctx) { if (rf & 1) {
208
- i0.ɵɵelementStart(0, "span", 36);
210
+ i0.ɵɵelementStart(0, "span", 37);
209
211
  i0.ɵɵtext(1);
210
212
  i0.ɵɵelementEnd();
211
213
  } if (rf & 2) {
@@ -214,44 +216,44 @@ function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Condition
214
216
  i0.ɵɵtextInterpolate1("", ctx_r2.VectorIndexes.length, " index(es) configured");
215
217
  } }
216
218
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_44_Template(rf, ctx) { if (rf & 1) {
217
- i0.ɵɵelementStart(0, "span", 36);
219
+ i0.ɵɵelementStart(0, "span", 37);
218
220
  i0.ɵɵtext(1, "No indexes yet \u2014 create one below.");
219
221
  i0.ɵɵelementEnd();
220
222
  } }
221
223
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_45_Template(rf, ctx) { if (rf & 1) {
222
- i0.ɵɵelementStart(0, "span", 36);
224
+ i0.ɵɵelementStart(0, "span", 37);
223
225
  i0.ɵɵtext(1, "Complete steps 1 and 2 first.");
224
226
  i0.ɵɵelementEnd();
225
227
  } }
226
228
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_46_Template(rf, ctx) { if (rf & 1) {
227
229
  const _r7 = i0.ɵɵgetCurrentView();
228
- i0.ɵɵelementStart(0, "button", 49);
230
+ i0.ɵɵelementStart(0, "button", 50);
229
231
  i0.ɵɵlistener("click", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_46_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r7); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.OpenCreateIndexForm()); });
230
- i0.ɵɵelement(1, "i", 50);
232
+ i0.ɵɵelement(1, "i", 51);
231
233
  i0.ɵɵtext(2, " Create Index ");
232
234
  i0.ɵɵelementEnd();
233
235
  } }
234
236
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_47_For_2_Template(rf, ctx) { if (rf & 1) {
235
237
  const _r8 = i0.ɵɵgetCurrentView();
236
- i0.ɵɵelementStart(0, "div", 51)(1, "div", 52);
237
- i0.ɵɵelement(2, "i", 53);
238
+ i0.ɵɵelementStart(0, "div", 52)(1, "div", 53);
239
+ i0.ɵɵelement(2, "i", 54);
238
240
  i0.ɵɵelementEnd();
239
- i0.ɵɵelementStart(3, "div", 54)(4, "span", 55);
241
+ i0.ɵɵelementStart(3, "div", 55)(4, "span", 56);
240
242
  i0.ɵɵtext(5);
241
243
  i0.ɵɵelementEnd();
242
- i0.ɵɵelementStart(6, "span", 56);
243
- i0.ɵɵelement(7, "i", 42);
244
+ i0.ɵɵelementStart(6, "span", 57);
245
+ i0.ɵɵelement(7, "i", 43);
244
246
  i0.ɵɵtext(8);
245
- i0.ɵɵelement(9, "i", 57);
247
+ i0.ɵɵelement(9, "i", 58);
246
248
  i0.ɵɵtext(10);
247
249
  i0.ɵɵelementEnd()();
248
- i0.ɵɵelementStart(11, "div", 58)(12, "span", 46);
249
- i0.ɵɵelement(13, "i", 32);
250
+ i0.ɵɵelementStart(11, "div", 59)(12, "span", 47);
251
+ i0.ɵɵelement(13, "i", 33);
250
252
  i0.ɵɵtext(14, " Active ");
251
253
  i0.ɵɵelementEnd();
252
- i0.ɵɵelementStart(15, "button", 59);
254
+ i0.ɵɵelementStart(15, "button", 60);
253
255
  i0.ɵɵlistener("click", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_47_For_2_Template_button_click_15_listener() { const idx_r9 = i0.ɵɵrestoreView(_r8).$implicit; const ctx_r2 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r2.DeleteIndex(idx_r9.ID)); });
254
- i0.ɵɵelement(16, "i", 60);
256
+ i0.ɵɵelement(16, "i", 61);
255
257
  i0.ɵɵelementEnd()()();
256
258
  } if (rf & 2) {
257
259
  const idx_r9 = ctx.$implicit;
@@ -263,8 +265,8 @@ function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Condition
263
265
  i0.ɵɵtextInterpolate1(" ", idx_r9.EmbeddingModel, " ");
264
266
  } }
265
267
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_47_Template(rf, ctx) { if (rf & 1) {
266
- i0.ɵɵelementStart(0, "div", 37);
267
- i0.ɵɵrepeaterCreate(1, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_47_For_2_Template, 17, 3, "div", 51, _forTrack0);
268
+ i0.ɵɵelementStart(0, "div", 38);
269
+ i0.ɵɵrepeaterCreate(1, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_47_For_2_Template, 17, 3, "div", 52, _forTrack0);
268
270
  i0.ɵɵelementEnd();
269
271
  } if (rf & 2) {
270
272
  const ctx_r2 = i0.ɵɵnextContext(3);
@@ -272,7 +274,7 @@ function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Condition
272
274
  i0.ɵɵrepeater(ctx_r2.VectorIndexes);
273
275
  } }
274
276
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_48_For_14_Template(rf, ctx) { if (rf & 1) {
275
- i0.ɵɵelementStart(0, "option", 68);
277
+ i0.ɵɵelementStart(0, "option", 69);
276
278
  i0.ɵɵtext(1);
277
279
  i0.ɵɵelementEnd();
278
280
  } if (rf & 2) {
@@ -282,7 +284,7 @@ function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Condition
282
284
  i0.ɵɵtextInterpolate(db_r11.Name);
283
285
  } }
284
286
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_48_For_20_Template(rf, ctx) { if (rf & 1) {
285
- i0.ɵɵelementStart(0, "option", 68);
287
+ i0.ɵɵelementStart(0, "option", 69);
286
288
  i0.ɵɵtext(1);
287
289
  i0.ɵɵelementEnd();
288
290
  } if (rf & 2) {
@@ -292,44 +294,44 @@ function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Condition
292
294
  i0.ɵɵtextInterpolate(model_r12.Name);
293
295
  } }
294
296
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_48_Conditional_23_Template(rf, ctx) { if (rf & 1) {
295
- i0.ɵɵelement(0, "i", 72);
297
+ i0.ɵɵelement(0, "i", 73);
296
298
  i0.ɵɵtext(1, " Creating... ");
297
299
  } }
298
300
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_48_Conditional_24_Template(rf, ctx) { if (rf & 1) {
299
- i0.ɵɵelement(0, "i", 50);
301
+ i0.ɵɵelement(0, "i", 51);
300
302
  i0.ɵɵtext(1, " Create Index ");
301
303
  } }
302
304
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_48_Template(rf, ctx) { if (rf & 1) {
303
305
  const _r10 = i0.ɵɵgetCurrentView();
304
- i0.ɵɵelementStart(0, "div", 39)(1, "h4", 61);
305
- i0.ɵɵelement(2, "i", 62);
306
+ i0.ɵɵelementStart(0, "div", 40)(1, "h4", 62);
307
+ i0.ɵɵelement(2, "i", 63);
306
308
  i0.ɵɵtext(3, " Create New Vector Index ");
307
309
  i0.ɵɵelementEnd();
308
- i0.ɵɵelementStart(4, "div", 63)(5, "div", 64)(6, "label", 65);
310
+ i0.ɵɵelementStart(4, "div", 64)(5, "div", 65)(6, "label", 66);
309
311
  i0.ɵɵtext(7, "Index Name");
310
312
  i0.ɵɵelementEnd();
311
- i0.ɵɵelementStart(8, "input", 66);
313
+ i0.ɵɵelementStart(8, "input", 67);
312
314
  i0.ɵɵtwoWayListener("ngModelChange", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_48_Template_input_ngModelChange_8_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r2 = i0.ɵɵnextContext(3); i0.ɵɵtwoWayBindingSet(ctx_r2.NewIndexName, $event) || (ctx_r2.NewIndexName = $event); return i0.ɵɵresetView($event); });
313
315
  i0.ɵɵelementEnd()();
314
- i0.ɵɵelementStart(9, "div", 64)(10, "label", 65);
316
+ i0.ɵɵelementStart(9, "div", 65)(10, "label", 66);
315
317
  i0.ɵɵtext(11, "Vector Database");
316
318
  i0.ɵɵelementEnd();
317
- i0.ɵɵelementStart(12, "select", 67);
319
+ i0.ɵɵelementStart(12, "select", 68);
318
320
  i0.ɵɵtwoWayListener("ngModelChange", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_48_Template_select_ngModelChange_12_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r2 = i0.ɵɵnextContext(3); i0.ɵɵtwoWayBindingSet(ctx_r2.NewIndexVectorDBID, $event) || (ctx_r2.NewIndexVectorDBID = $event); return i0.ɵɵresetView($event); });
319
- i0.ɵɵrepeaterCreate(13, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_48_For_14_Template, 2, 2, "option", 68, _forTrack0);
321
+ i0.ɵɵrepeaterCreate(13, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_48_For_14_Template, 2, 2, "option", 69, _forTrack0);
320
322
  i0.ɵɵelementEnd()();
321
- i0.ɵɵelementStart(15, "div", 64)(16, "label", 65);
323
+ i0.ɵɵelementStart(15, "div", 65)(16, "label", 66);
322
324
  i0.ɵɵtext(17, "Embedding Model");
323
325
  i0.ɵɵelementEnd();
324
- i0.ɵɵelementStart(18, "select", 67);
326
+ i0.ɵɵelementStart(18, "select", 68);
325
327
  i0.ɵɵtwoWayListener("ngModelChange", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_48_Template_select_ngModelChange_18_listener($event) { i0.ɵɵrestoreView(_r10); const ctx_r2 = i0.ɵɵnextContext(3); i0.ɵɵtwoWayBindingSet(ctx_r2.NewIndexEmbeddingModelID, $event) || (ctx_r2.NewIndexEmbeddingModelID = $event); return i0.ɵɵresetView($event); });
326
- i0.ɵɵrepeaterCreate(19, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_48_For_20_Template, 2, 2, "option", 68, _forTrack0);
328
+ i0.ɵɵrepeaterCreate(19, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_48_For_20_Template, 2, 2, "option", 69, _forTrack0);
327
329
  i0.ɵɵelementEnd()()();
328
- i0.ɵɵelementStart(21, "div", 69)(22, "button", 70);
330
+ i0.ɵɵelementStart(21, "div", 70)(22, "button", 71);
329
331
  i0.ɵɵlistener("click", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_48_Template_button_click_22_listener() { i0.ɵɵrestoreView(_r10); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.CreateIndex()); });
330
332
  i0.ɵɵconditionalCreate(23, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_48_Conditional_23_Template, 2, 0)(24, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_48_Conditional_24_Template, 2, 0);
331
333
  i0.ɵɵelementEnd();
332
- i0.ɵɵelementStart(25, "button", 71);
334
+ i0.ɵɵelementStart(25, "button", 72);
333
335
  i0.ɵɵlistener("click", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_48_Template_button_click_25_listener() { i0.ɵɵrestoreView(_r10); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.CancelCreateIndex()); });
334
336
  i0.ɵɵtext(26, " Cancel ");
335
337
  i0.ɵɵelementEnd()()();
@@ -353,53 +355,53 @@ function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Condition
353
355
  i0.ɵɵproperty("disabled", ctx_r2.IsCreatingIndex);
354
356
  } }
355
357
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Template(rf, ctx) { if (rf & 1) {
356
- i0.ɵɵelementStart(0, "div", 8)(1, "h2", 11);
358
+ i0.ɵɵelementStart(0, "div", 8)(1, "h2", 12);
357
359
  i0.ɵɵtext(2, "Vector Database");
358
360
  i0.ɵɵelementEnd();
359
- i0.ɵɵelementStart(3, "p", 12);
361
+ i0.ɵɵelementStart(3, "p", 13);
360
362
  i0.ɵɵtext(4, "Manage the shared vector index and database connection.");
361
363
  i0.ɵɵelementEnd();
362
- i0.ɵɵelementStart(5, "div", 23)(6, "div", 24)(7, "span", 25);
364
+ i0.ɵɵelementStart(5, "div", 24)(6, "div", 25)(7, "span", 26);
363
365
  i0.ɵɵtext(8, "Setup Progress");
364
366
  i0.ɵɵelementEnd();
365
- i0.ɵɵelementStart(9, "span", 26);
367
+ i0.ɵɵelementStart(9, "span", 27);
366
368
  i0.ɵɵtext(10);
367
369
  i0.ɵɵelementEnd()();
368
- i0.ɵɵelementStart(11, "div", 27);
369
- i0.ɵɵelement(12, "div", 28);
370
+ i0.ɵɵelementStart(11, "div", 28);
371
+ i0.ɵɵelement(12, "div", 29);
370
372
  i0.ɵɵelementEnd()();
371
- i0.ɵɵelementStart(13, "div", 29)(14, "div", 30)(15, "div", 31);
372
- i0.ɵɵconditionalCreate(16, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_16_Template, 1, 0, "i", 32)(17, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_17_Template, 2, 0, "span", 33);
373
+ i0.ɵɵelementStart(13, "div", 30)(14, "div", 31)(15, "div", 32);
374
+ i0.ɵɵconditionalCreate(16, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_16_Template, 1, 0, "i", 33)(17, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_17_Template, 2, 0, "span", 34);
373
375
  i0.ɵɵelementEnd();
374
- i0.ɵɵelementStart(18, "div", 34)(19, "span", 35);
376
+ i0.ɵɵelementStart(18, "div", 35)(19, "span", 36);
375
377
  i0.ɵɵtext(20, "Vector Database Providers");
376
378
  i0.ɵɵelementEnd();
377
- i0.ɵɵconditionalCreate(21, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_21_Template, 2, 1, "span", 36)(22, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_22_Template, 2, 0, "span", 36);
379
+ i0.ɵɵconditionalCreate(21, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_21_Template, 2, 1, "span", 37)(22, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_22_Template, 2, 0, "span", 37);
378
380
  i0.ɵɵelementEnd()();
379
- i0.ɵɵconditionalCreate(23, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_23_Template, 3, 0, "div", 37);
381
+ i0.ɵɵconditionalCreate(23, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_23_Template, 3, 0, "div", 38);
380
382
  i0.ɵɵelementEnd();
381
- i0.ɵɵelementStart(24, "div", 29)(25, "div", 30)(26, "div", 31);
382
- i0.ɵɵconditionalCreate(27, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_27_Template, 1, 0, "i", 32)(28, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_28_Template, 2, 0, "span", 33);
383
+ i0.ɵɵelementStart(24, "div", 30)(25, "div", 31)(26, "div", 32);
384
+ i0.ɵɵconditionalCreate(27, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_27_Template, 1, 0, "i", 33)(28, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_28_Template, 2, 0, "span", 34);
383
385
  i0.ɵɵelementEnd();
384
- i0.ɵɵelementStart(29, "div", 34)(30, "span", 35);
386
+ i0.ɵɵelementStart(29, "div", 35)(30, "span", 36);
385
387
  i0.ɵɵtext(31, "Embedding Models");
386
388
  i0.ɵɵelementEnd();
387
- i0.ɵɵconditionalCreate(32, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_32_Template, 2, 1, "span", 36)(33, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_33_Template, 2, 0, "span", 36);
389
+ i0.ɵɵconditionalCreate(32, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_32_Template, 2, 1, "span", 37)(33, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_33_Template, 2, 0, "span", 37);
388
390
  i0.ɵɵelementEnd()();
389
- i0.ɵɵconditionalCreate(34, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_34_Template, 4, 0, "div", 37);
391
+ i0.ɵɵconditionalCreate(34, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_34_Template, 4, 0, "div", 38);
390
392
  i0.ɵɵelementEnd();
391
- i0.ɵɵelementStart(35, "div", 29)(36, "div", 30)(37, "div", 31);
392
- i0.ɵɵconditionalCreate(38, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_38_Template, 1, 0, "i", 32)(39, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_39_Template, 2, 0, "span", 33);
393
+ i0.ɵɵelementStart(35, "div", 30)(36, "div", 31)(37, "div", 32);
394
+ i0.ɵɵconditionalCreate(38, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_38_Template, 1, 0, "i", 33)(39, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_39_Template, 2, 0, "span", 34);
393
395
  i0.ɵɵelementEnd();
394
- i0.ɵɵelementStart(40, "div", 34)(41, "span", 35);
396
+ i0.ɵɵelementStart(40, "div", 35)(41, "span", 36);
395
397
  i0.ɵɵtext(42, "Vector Indexes");
396
398
  i0.ɵɵelementEnd();
397
- i0.ɵɵconditionalCreate(43, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_43_Template, 2, 1, "span", 36)(44, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_44_Template, 2, 0, "span", 36)(45, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_45_Template, 2, 0, "span", 36);
399
+ i0.ɵɵconditionalCreate(43, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_43_Template, 2, 1, "span", 37)(44, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_44_Template, 2, 0, "span", 37)(45, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_45_Template, 2, 0, "span", 37);
398
400
  i0.ɵɵelementEnd();
399
- i0.ɵɵconditionalCreate(46, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_46_Template, 3, 0, "button", 38);
401
+ i0.ɵɵconditionalCreate(46, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_46_Template, 3, 0, "button", 39);
400
402
  i0.ɵɵelementEnd();
401
- i0.ɵɵconditionalCreate(47, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_47_Template, 3, 0, "div", 37);
402
- i0.ɵɵconditionalCreate(48, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_48_Template, 27, 6, "div", 39);
403
+ i0.ɵɵconditionalCreate(47, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_47_Template, 3, 0, "div", 38);
404
+ i0.ɵɵconditionalCreate(48, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_48_Template, 27, 6, "div", 40);
403
405
  i0.ɵɵelementEnd()();
404
406
  } if (rf & 2) {
405
407
  const ctx_r2 = i0.ɵɵnextContext(2);
@@ -437,20 +439,20 @@ function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Template(
437
439
  i0.ɵɵconditional(ctx_r2.ShowCreateIndexForm ? 48 : -1);
438
440
  } }
439
441
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_11_Conditional_5_Template(rf, ctx) { if (rf & 1) {
440
- i0.ɵɵelement(0, "mj-loading", 73);
442
+ i0.ɵɵelement(0, "mj-loading", 74);
441
443
  } }
442
444
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_11_Conditional_6_Template(rf, ctx) { if (rf & 1) {
443
- i0.ɵɵelementStart(0, "div", 74);
444
- i0.ɵɵelement(1, "i", 75);
445
- i0.ɵɵelementStart(2, "h3", 76);
445
+ i0.ɵɵelementStart(0, "div", 75);
446
+ i0.ɵɵelement(1, "i", 76);
447
+ i0.ɵɵelementStart(2, "h3", 77);
446
448
  i0.ɵɵtext(3, "No Searchable Entities Found");
447
449
  i0.ɵɵelementEnd();
448
- i0.ɵɵelementStart(4, "p", 77);
450
+ i0.ɵɵelementStart(4, "p", 78);
449
451
  i0.ɵɵtext(5, "No entities with text fields were discovered. Ensure your database schema includes entities with varchar/nvarchar columns.");
450
452
  i0.ɵɵelementEnd()();
451
453
  } }
452
454
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_11_Conditional_7_For_7_For_8_Template(rf, ctx) { if (rf & 1) {
453
- i0.ɵɵelementStart(0, "span", 89);
455
+ i0.ɵɵelementStart(0, "span", 90);
454
456
  i0.ɵɵtext(1);
455
457
  i0.ɵɵelementEnd();
456
458
  } if (rf & 2) {
@@ -459,8 +461,8 @@ function KnowledgeConfigResourceComponent_Conditional_1_Conditional_11_Condition
459
461
  i0.ɵɵtextInterpolate(field_r16);
460
462
  } }
461
463
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_11_Conditional_7_For_7_Conditional_13_Template(rf, ctx) { if (rf & 1) {
462
- i0.ɵɵelementStart(0, "span", 93);
463
- i0.ɵɵelement(1, "i", 94);
464
+ i0.ɵɵelementStart(0, "span", 94);
465
+ i0.ɵɵelement(1, "i", 95);
464
466
  i0.ɵɵtext(2);
465
467
  i0.ɵɵelementEnd();
466
468
  } if (rf & 2) {
@@ -470,21 +472,21 @@ function KnowledgeConfigResourceComponent_Conditional_1_Conditional_11_Condition
470
472
  } }
471
473
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_11_Conditional_7_For_7_Template(rf, ctx) { if (rf & 1) {
472
474
  const _r14 = i0.ɵɵgetCurrentView();
473
- i0.ɵɵelementStart(0, "div", 84)(1, "div", 85)(2, "input", 18);
475
+ i0.ɵɵelementStart(0, "div", 85)(1, "div", 86)(2, "input", 19);
474
476
  i0.ɵɵtwoWayListener("ngModelChange", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_11_Conditional_7_For_7_Template_input_ngModelChange_2_listener($event) { const entity_r15 = i0.ɵɵrestoreView(_r14).$implicit; i0.ɵɵtwoWayBindingSet(entity_r15.Enabled, $event) || (entity_r15.Enabled = $event); return i0.ɵɵresetView($event); });
475
477
  i0.ɵɵlistener("change", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_11_Conditional_7_For_7_Template_input_change_2_listener() { const entity_r15 = i0.ɵɵrestoreView(_r14).$implicit; const ctx_r2 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r2.OnFTSEntityToggled(entity_r15)); });
476
478
  i0.ɵɵelementEnd()();
477
- i0.ɵɵelementStart(3, "div", 86)(4, "span", 87);
479
+ i0.ɵɵelementStart(3, "div", 87)(4, "span", 88);
478
480
  i0.ɵɵtext(5);
479
481
  i0.ɵɵelementEnd();
480
- i0.ɵɵelementStart(6, "div", 88);
481
- i0.ɵɵrepeaterCreate(7, KnowledgeConfigResourceComponent_Conditional_1_Conditional_11_Conditional_7_For_7_For_8_Template, 2, 1, "span", 89, i0.ɵɵrepeaterTrackByIdentity);
482
+ i0.ɵɵelementStart(6, "div", 89);
483
+ i0.ɵɵrepeaterCreate(7, KnowledgeConfigResourceComponent_Conditional_1_Conditional_11_Conditional_7_For_7_For_8_Template, 2, 1, "span", 90, i0.ɵɵrepeaterTrackByIdentity);
482
484
  i0.ɵɵelementEnd()();
483
- i0.ɵɵelementStart(9, "div", 90)(10, "span", 91);
484
- i0.ɵɵelement(11, "i", 92);
485
+ i0.ɵɵelementStart(9, "div", 91)(10, "span", 92);
486
+ i0.ɵɵelement(11, "i", 93);
485
487
  i0.ɵɵtext(12);
486
488
  i0.ɵɵelementEnd();
487
- i0.ɵɵconditionalCreate(13, KnowledgeConfigResourceComponent_Conditional_1_Conditional_11_Conditional_7_For_7_Conditional_13_Template, 3, 1, "span", 93);
489
+ i0.ɵɵconditionalCreate(13, KnowledgeConfigResourceComponent_Conditional_1_Conditional_11_Conditional_7_For_7_Conditional_13_Template, 3, 1, "span", 94);
488
490
  i0.ɵɵelementEnd()();
489
491
  } if (rf & 2) {
490
492
  const entity_r15 = ctx.$implicit;
@@ -502,14 +504,14 @@ function KnowledgeConfigResourceComponent_Conditional_1_Conditional_11_Condition
502
504
  } }
503
505
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_11_Conditional_7_Template(rf, ctx) { if (rf & 1) {
504
506
  const _r13 = i0.ɵɵgetCurrentView();
505
- i0.ɵɵelementStart(0, "div", 78)(1, "div", 79)(2, "span", 80);
507
+ i0.ɵɵelementStart(0, "div", 79)(1, "div", 80)(2, "span", 81);
506
508
  i0.ɵɵtext(3);
507
509
  i0.ɵɵelementEnd();
508
- i0.ɵɵelementStart(4, "input", 81);
510
+ i0.ɵɵelementStart(4, "input", 82);
509
511
  i0.ɵɵtwoWayListener("ngModelChange", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_11_Conditional_7_Template_input_ngModelChange_4_listener($event) { i0.ɵɵrestoreView(_r13); const ctx_r2 = i0.ɵɵnextContext(3); i0.ɵɵtwoWayBindingSet(ctx_r2.FTSFilterText, $event) || (ctx_r2.FTSFilterText = $event); return i0.ɵɵresetView($event); });
510
512
  i0.ɵɵelementEnd()()();
511
- i0.ɵɵelementStart(5, "div", 82);
512
- i0.ɵɵrepeaterCreate(6, KnowledgeConfigResourceComponent_Conditional_1_Conditional_11_Conditional_7_For_7_Template, 14, 6, "div", 83, _forTrack1);
513
+ i0.ɵɵelementStart(5, "div", 83);
514
+ i0.ɵɵrepeaterCreate(6, KnowledgeConfigResourceComponent_Conditional_1_Conditional_11_Conditional_7_For_7_Template, 14, 6, "div", 84, _forTrack1);
513
515
  i0.ɵɵelementEnd();
514
516
  } if (rf & 2) {
515
517
  const ctx_r2 = i0.ɵɵnextContext(3);
@@ -521,13 +523,13 @@ function KnowledgeConfigResourceComponent_Conditional_1_Conditional_11_Condition
521
523
  i0.ɵɵrepeater(ctx_r2.FilteredFTSEntities);
522
524
  } }
523
525
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_11_Template(rf, ctx) { if (rf & 1) {
524
- i0.ɵɵelementStart(0, "div", 8)(1, "h2", 11);
526
+ i0.ɵɵelementStart(0, "div", 8)(1, "h2", 12);
525
527
  i0.ɵɵtext(2, "Full-Text Search Entities");
526
528
  i0.ɵɵelementEnd();
527
- i0.ɵɵelementStart(3, "p", 12);
529
+ i0.ɵɵelementStart(3, "p", 13);
528
530
  i0.ɵɵtext(4, "Configure which entities are included in full-text search. Entities with text fields (Name, Description, etc.) are automatically discovered.");
529
531
  i0.ɵɵelementEnd();
530
- i0.ɵɵconditionalCreate(5, KnowledgeConfigResourceComponent_Conditional_1_Conditional_11_Conditional_5_Template, 1, 0, "mj-loading", 73)(6, KnowledgeConfigResourceComponent_Conditional_1_Conditional_11_Conditional_6_Template, 6, 0, "div", 74)(7, KnowledgeConfigResourceComponent_Conditional_1_Conditional_11_Conditional_7_Template, 8, 3);
532
+ i0.ɵɵconditionalCreate(5, KnowledgeConfigResourceComponent_Conditional_1_Conditional_11_Conditional_5_Template, 1, 0, "mj-loading", 74)(6, KnowledgeConfigResourceComponent_Conditional_1_Conditional_11_Conditional_6_Template, 6, 0, "div", 75)(7, KnowledgeConfigResourceComponent_Conditional_1_Conditional_11_Conditional_7_Template, 8, 3);
531
533
  i0.ɵɵelementEnd();
532
534
  } if (rf & 2) {
533
535
  const ctx_r2 = i0.ɵɵnextContext(2);
@@ -535,7 +537,7 @@ function KnowledgeConfigResourceComponent_Conditional_1_Conditional_11_Template(
535
537
  i0.ɵɵconditional(ctx_r2.IsLoadingFTSEntities ? 5 : ctx_r2.FTSEntities.length === 0 ? 6 : 7);
536
538
  } }
537
539
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_12_Conditional_5_For_17_Template(rf, ctx) { if (rf & 1) {
538
- i0.ɵɵelementStart(0, "span", 48);
540
+ i0.ɵɵelementStart(0, "span", 49);
539
541
  i0.ɵɵtext(1);
540
542
  i0.ɵɵelementEnd();
541
543
  } if (rf & 2) {
@@ -544,26 +546,26 @@ function KnowledgeConfigResourceComponent_Conditional_1_Conditional_12_Condition
544
546
  i0.ɵɵtextInterpolate(model_r17.Name);
545
547
  } }
546
548
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_12_Conditional_5_Template(rf, ctx) { if (rf & 1) {
547
- i0.ɵɵelementStart(0, "div", 13)(1, "div", 19)(2, "div", 20)(3, "span", 16);
549
+ i0.ɵɵelementStart(0, "div", 14)(1, "div", 20)(2, "div", 21)(3, "span", 17);
548
550
  i0.ɵɵtext(4, "Active Model");
549
551
  i0.ɵɵelementEnd();
550
- i0.ɵɵelementStart(5, "span", 17);
552
+ i0.ɵɵelementStart(5, "span", 18);
551
553
  i0.ɵɵtext(6, "Currently selected embedding model");
552
554
  i0.ɵɵelementEnd()();
553
- i0.ɵɵelementStart(7, "span", 95);
555
+ i0.ɵɵelementStart(7, "span", 96);
554
556
  i0.ɵɵtext(8);
555
557
  i0.ɵɵelementEnd()();
556
- i0.ɵɵelementStart(9, "div", 19)(10, "div", 20)(11, "span", 16);
558
+ i0.ɵɵelementStart(9, "div", 20)(10, "div", 21)(11, "span", 17);
557
559
  i0.ɵɵtext(12, "Available Models");
558
560
  i0.ɵɵelementEnd();
559
- i0.ɵɵelementStart(13, "span", 17);
561
+ i0.ɵɵelementStart(13, "span", 18);
560
562
  i0.ɵɵtext(14);
561
563
  i0.ɵɵelementEnd()();
562
- i0.ɵɵelementStart(15, "div", 47);
563
- i0.ɵɵrepeaterCreate(16, KnowledgeConfigResourceComponent_Conditional_1_Conditional_12_Conditional_5_For_17_Template, 2, 1, "span", 48, _forTrack0);
564
+ i0.ɵɵelementStart(15, "div", 48);
565
+ i0.ɵɵrepeaterCreate(16, KnowledgeConfigResourceComponent_Conditional_1_Conditional_12_Conditional_5_For_17_Template, 2, 1, "span", 49, _forTrack0);
564
566
  i0.ɵɵelementEnd()()();
565
- i0.ɵɵelementStart(18, "p", 96);
566
- i0.ɵɵelement(19, "i", 97);
567
+ i0.ɵɵelementStart(18, "p", 97);
568
+ i0.ɵɵelement(19, "i", 98);
567
569
  i0.ɵɵtext(20, " Manage embedding models in the AI Dashboard > Models tab. ");
568
570
  i0.ɵɵelementEnd();
569
571
  } if (rf & 2) {
@@ -576,23 +578,23 @@ function KnowledgeConfigResourceComponent_Conditional_1_Conditional_12_Condition
576
578
  i0.ɵɵrepeater(ctx_r2.EmbeddingModels);
577
579
  } }
578
580
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_12_Conditional_6_Template(rf, ctx) { if (rf & 1) {
579
- i0.ɵɵelementStart(0, "div", 74);
580
- i0.ɵɵelement(1, "i", 98);
581
- i0.ɵɵelementStart(2, "h3", 76);
581
+ i0.ɵɵelementStart(0, "div", 75);
582
+ i0.ɵɵelement(1, "i", 99);
583
+ i0.ɵɵelementStart(2, "h3", 77);
582
584
  i0.ɵɵtext(3, "No Embedding Models Found");
583
585
  i0.ɵɵelementEnd();
584
- i0.ɵɵelementStart(4, "p", 77);
586
+ i0.ɵɵelementStart(4, "p", 78);
585
587
  i0.ɵɵtext(5, " Embedding models are required to convert text into vectors for semantic search and duplicate detection. Configure at least one embedding model (e.g., text-embedding-3-small) in the AI Dashboard > Models tab. ");
586
588
  i0.ɵɵelementEnd()();
587
589
  } }
588
590
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_12_Template(rf, ctx) { if (rf & 1) {
589
- i0.ɵɵelementStart(0, "div", 8)(1, "h2", 11);
591
+ i0.ɵɵelementStart(0, "div", 8)(1, "h2", 12);
590
592
  i0.ɵɵtext(2, "Embedding Models");
591
593
  i0.ɵɵelementEnd();
592
- i0.ɵɵelementStart(3, "p", 12);
594
+ i0.ɵɵelementStart(3, "p", 13);
593
595
  i0.ɵɵtext(4, "AI models used for generating vector embeddings from text.");
594
596
  i0.ɵɵelementEnd();
595
- i0.ɵɵconditionalCreate(5, KnowledgeConfigResourceComponent_Conditional_1_Conditional_12_Conditional_5_Template, 21, 2)(6, KnowledgeConfigResourceComponent_Conditional_1_Conditional_12_Conditional_6_Template, 6, 0, "div", 74);
597
+ i0.ɵɵconditionalCreate(5, KnowledgeConfigResourceComponent_Conditional_1_Conditional_12_Conditional_5_Template, 21, 2)(6, KnowledgeConfigResourceComponent_Conditional_1_Conditional_12_Conditional_6_Template, 6, 0, "div", 75);
596
598
  i0.ɵɵelementEnd();
597
599
  } if (rf & 2) {
598
600
  const ctx_r2 = i0.ɵɵnextContext(2);
@@ -601,49 +603,49 @@ function KnowledgeConfigResourceComponent_Conditional_1_Conditional_12_Template(
601
603
  } }
602
604
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_13_Template(rf, ctx) { if (rf & 1) {
603
605
  const _r18 = i0.ɵɵgetCurrentView();
604
- i0.ɵɵelementStart(0, "div", 8)(1, "h2", 11);
606
+ i0.ɵɵelementStart(0, "div", 8)(1, "h2", 12);
605
607
  i0.ɵɵtext(2, "Scoring Thresholds");
606
608
  i0.ɵɵelementEnd();
607
- i0.ɵɵelementStart(3, "p", 12);
609
+ i0.ɵɵelementStart(3, "p", 13);
608
610
  i0.ɵɵtext(4, "Set the scoring thresholds used by search, duplicate detection, and autotagging.");
609
611
  i0.ɵɵelementEnd();
610
- i0.ɵɵelementStart(5, "div", 13)(6, "div", 19)(7, "div", 20)(8, "span", 16);
612
+ i0.ɵɵelementStart(5, "div", 14)(6, "div", 20)(7, "div", 21)(8, "span", 17);
611
613
  i0.ɵɵtext(9, "Duplicate Absolute Match");
612
614
  i0.ɵɵelementEnd();
613
- i0.ɵɵelementStart(10, "span", 17);
615
+ i0.ɵɵelementStart(10, "span", 18);
614
616
  i0.ɵɵtext(11);
615
617
  i0.ɵɵelementEnd()();
616
- i0.ɵɵelementStart(12, "input", 99);
618
+ i0.ɵɵelementStart(12, "input", 100);
617
619
  i0.ɵɵtwoWayListener("ngModelChange", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_13_Template_input_ngModelChange_12_listener($event) { i0.ɵɵrestoreView(_r18); const ctx_r2 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r2.ThresholdSettings.DuplicateAbsolute, $event) || (ctx_r2.ThresholdSettings.DuplicateAbsolute = $event); return i0.ɵɵresetView($event); });
618
620
  i0.ɵɵlistener("input", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_13_Template_input_input_12_listener() { i0.ɵɵrestoreView(_r18); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.OnSettingChanged()); });
619
621
  i0.ɵɵelementEnd()();
620
- i0.ɵɵelementStart(13, "div", 19)(14, "div", 20)(15, "span", 16);
622
+ i0.ɵɵelementStart(13, "div", 20)(14, "div", 21)(15, "span", 17);
621
623
  i0.ɵɵtext(16, "Duplicate Potential Match");
622
624
  i0.ɵɵelementEnd();
623
- i0.ɵɵelementStart(17, "span", 17);
625
+ i0.ɵɵelementStart(17, "span", 18);
624
626
  i0.ɵɵtext(18);
625
627
  i0.ɵɵelementEnd()();
626
- i0.ɵɵelementStart(19, "input", 100);
628
+ i0.ɵɵelementStart(19, "input", 101);
627
629
  i0.ɵɵtwoWayListener("ngModelChange", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_13_Template_input_ngModelChange_19_listener($event) { i0.ɵɵrestoreView(_r18); const ctx_r2 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r2.ThresholdSettings.DuplicatePotential, $event) || (ctx_r2.ThresholdSettings.DuplicatePotential = $event); return i0.ɵɵresetView($event); });
628
630
  i0.ɵɵlistener("input", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_13_Template_input_input_19_listener() { i0.ɵɵrestoreView(_r18); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.OnSettingChanged()); });
629
631
  i0.ɵɵelementEnd()();
630
- i0.ɵɵelementStart(20, "div", 19)(21, "div", 20)(22, "span", 16);
632
+ i0.ɵɵelementStart(20, "div", 20)(21, "div", 21)(22, "span", 17);
631
633
  i0.ɵɵtext(23, "Search Relevance");
632
634
  i0.ɵɵelementEnd();
633
- i0.ɵɵelementStart(24, "span", 17);
635
+ i0.ɵɵelementStart(24, "span", 18);
634
636
  i0.ɵɵtext(25);
635
637
  i0.ɵɵelementEnd()();
636
- i0.ɵɵelementStart(26, "input", 101);
638
+ i0.ɵɵelementStart(26, "input", 102);
637
639
  i0.ɵɵtwoWayListener("ngModelChange", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_13_Template_input_ngModelChange_26_listener($event) { i0.ɵɵrestoreView(_r18); const ctx_r2 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r2.ThresholdSettings.SearchRelevance, $event) || (ctx_r2.ThresholdSettings.SearchRelevance = $event); return i0.ɵɵresetView($event); });
638
640
  i0.ɵɵlistener("input", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_13_Template_input_input_26_listener() { i0.ɵɵrestoreView(_r18); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.OnSettingChanged()); });
639
641
  i0.ɵɵelementEnd()();
640
- i0.ɵɵelementStart(27, "div", 19)(28, "div", 20)(29, "span", 16);
642
+ i0.ɵɵelementStart(27, "div", 20)(28, "div", 21)(29, "span", 17);
641
643
  i0.ɵɵtext(30, "Autotag Confidence");
642
644
  i0.ɵɵelementEnd();
643
- i0.ɵɵelementStart(31, "span", 17);
645
+ i0.ɵɵelementStart(31, "span", 18);
644
646
  i0.ɵɵtext(32);
645
647
  i0.ɵɵelementEnd()();
646
- i0.ɵɵelementStart(33, "input", 100);
648
+ i0.ɵɵelementStart(33, "input", 101);
647
649
  i0.ɵɵtwoWayListener("ngModelChange", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_13_Template_input_ngModelChange_33_listener($event) { i0.ɵɵrestoreView(_r18); const ctx_r2 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r2.ThresholdSettings.AutotagConfidence, $event) || (ctx_r2.ThresholdSettings.AutotagConfidence = $event); return i0.ɵɵresetView($event); });
648
650
  i0.ɵɵlistener("input", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_13_Template_input_input_33_listener() { i0.ɵɵrestoreView(_r18); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.OnSettingChanged()); });
649
651
  i0.ɵɵelementEnd()()()();
@@ -666,25 +668,37 @@ function KnowledgeConfigResourceComponent_Conditional_1_Conditional_13_Template(
666
668
  i0.ɵɵadvance();
667
669
  i0.ɵɵtwoWayProperty("ngModel", ctx_r2.ThresholdSettings.AutotagConfidence);
668
670
  } }
669
- function KnowledgeConfigResourceComponent_Conditional_1_Conditional_14_Conditional_4_Template(rf, ctx) { if (rf & 1) {
670
- i0.ɵɵelement(0, "i", 72);
671
+ function KnowledgeConfigResourceComponent_Conditional_1_Conditional_14_Template(rf, ctx) { if (rf & 1) {
672
+ i0.ɵɵelementStart(0, "div", 9)(1, "h2", 12);
673
+ i0.ɵɵelement(2, "i", 103);
674
+ i0.ɵɵtext(3, " Scheduling");
675
+ i0.ɵɵelementEnd();
676
+ i0.ɵɵelementStart(4, "p", 13);
677
+ i0.ɵɵtext(5, "Manage automated pipeline schedules for content classification and vector sync. Create schedules here or manage all schedules in the dedicated Scheduling app.");
678
+ i0.ɵɵelementEnd();
679
+ i0.ɵɵelementStart(6, "div", 104);
680
+ i0.ɵɵelement(7, "app-scheduling-resource");
681
+ i0.ɵɵelementEnd()();
682
+ } }
683
+ function KnowledgeConfigResourceComponent_Conditional_1_Conditional_15_Conditional_4_Template(rf, ctx) { if (rf & 1) {
684
+ i0.ɵɵelement(0, "i", 73);
671
685
  i0.ɵɵtext(1, " Saving... ");
672
686
  } }
673
- function KnowledgeConfigResourceComponent_Conditional_1_Conditional_14_Conditional_5_Template(rf, ctx) { if (rf & 1) {
674
- i0.ɵɵelement(0, "i", 105);
687
+ function KnowledgeConfigResourceComponent_Conditional_1_Conditional_15_Conditional_5_Template(rf, ctx) { if (rf & 1) {
688
+ i0.ɵɵelement(0, "i", 108);
675
689
  i0.ɵɵtext(1, " Save Changes ");
676
690
  } }
677
- function KnowledgeConfigResourceComponent_Conditional_1_Conditional_14_Template(rf, ctx) { if (rf & 1) {
691
+ function KnowledgeConfigResourceComponent_Conditional_1_Conditional_15_Template(rf, ctx) { if (rf & 1) {
678
692
  const _r19 = i0.ɵɵgetCurrentView();
679
- i0.ɵɵelementStart(0, "div", 9)(1, "span", 102);
693
+ i0.ɵɵelementStart(0, "div", 10)(1, "span", 105);
680
694
  i0.ɵɵtext(2, "You have unsaved changes");
681
695
  i0.ɵɵelementEnd();
682
- i0.ɵɵelementStart(3, "button", 103);
683
- i0.ɵɵlistener("click", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_14_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r19); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.SaveConfiguration()); });
684
- i0.ɵɵconditionalCreate(4, KnowledgeConfigResourceComponent_Conditional_1_Conditional_14_Conditional_4_Template, 2, 0)(5, KnowledgeConfigResourceComponent_Conditional_1_Conditional_14_Conditional_5_Template, 2, 0);
696
+ i0.ɵɵelementStart(3, "button", 106);
697
+ i0.ɵɵlistener("click", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_15_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r19); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.SaveConfiguration()); });
698
+ i0.ɵɵconditionalCreate(4, KnowledgeConfigResourceComponent_Conditional_1_Conditional_15_Conditional_4_Template, 2, 0)(5, KnowledgeConfigResourceComponent_Conditional_1_Conditional_15_Conditional_5_Template, 2, 0);
685
699
  i0.ɵɵelementEnd();
686
- i0.ɵɵelementStart(6, "button", 104);
687
- i0.ɵɵlistener("click", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_14_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r19); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.ResetConfiguration()); });
700
+ i0.ɵɵelementStart(6, "button", 107);
701
+ i0.ɵɵlistener("click", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_15_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r19); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.ResetConfiguration()); });
688
702
  i0.ɵɵtext(7, " Reset ");
689
703
  i0.ɵɵelementEnd()();
690
704
  } if (rf & 2) {
@@ -710,7 +724,8 @@ function KnowledgeConfigResourceComponent_Conditional_1_Template(rf, ctx) { if (
710
724
  i0.ɵɵconditionalCreate(11, KnowledgeConfigResourceComponent_Conditional_1_Conditional_11_Template, 8, 1, "div", 8);
711
725
  i0.ɵɵconditionalCreate(12, KnowledgeConfigResourceComponent_Conditional_1_Conditional_12_Template, 7, 1, "div", 8);
712
726
  i0.ɵɵconditionalCreate(13, KnowledgeConfigResourceComponent_Conditional_1_Conditional_13_Template, 34, 8, "div", 8);
713
- i0.ɵɵconditionalCreate(14, KnowledgeConfigResourceComponent_Conditional_1_Conditional_14_Template, 8, 3, "div", 9);
727
+ i0.ɵɵconditionalCreate(14, KnowledgeConfigResourceComponent_Conditional_1_Conditional_14_Template, 8, 0, "div", 9);
728
+ i0.ɵɵconditionalCreate(15, KnowledgeConfigResourceComponent_Conditional_1_Conditional_15_Template, 8, 3, "div", 10);
714
729
  i0.ɵɵelementEnd()();
715
730
  } if (rf & 2) {
716
731
  const ctx_r2 = i0.ɵɵnextContext();
@@ -727,10 +742,13 @@ function KnowledgeConfigResourceComponent_Conditional_1_Template(rf, ctx) { if (
727
742
  i0.ɵɵadvance();
728
743
  i0.ɵɵconditional(ctx_r2.ActiveSection === "thresholds" ? 13 : -1);
729
744
  i0.ɵɵadvance();
730
- i0.ɵɵconditional(ctx_r2.HasUnsavedChanges ? 14 : -1);
745
+ i0.ɵɵconditional(ctx_r2.ActiveSection === "scheduling" ? 14 : -1);
746
+ i0.ɵɵadvance();
747
+ i0.ɵɵconditional(ctx_r2.HasUnsavedChanges ? 15 : -1);
731
748
  } }
732
749
  let KnowledgeConfigResourceComponent = class KnowledgeConfigResourceComponent extends BaseResourceComponent {
733
750
  cdr = inject(ChangeDetectorRef);
751
+ navigationService = inject(NavigationService);
734
752
  destroy$ = new Subject();
735
753
  async GetResourceDisplayName(_data) {
736
754
  return 'Configuration';
@@ -745,6 +763,7 @@ let KnowledgeConfigResourceComponent = class KnowledgeConfigResourceComponent ex
745
763
  { ID: 'fulltext', Label: 'Full-Text Indexes', Icon: 'fa-solid fa-text-width', Description: 'Configure SQL full-text search indexes' },
746
764
  { ID: 'embedding', Label: 'Embedding Models', Icon: 'fa-solid fa-microchip', Description: 'Select and configure embedding models' },
747
765
  { ID: 'thresholds', Label: 'Thresholds', Icon: 'fa-solid fa-sliders', Description: 'Set scoring thresholds for search and deduplication' },
766
+ { ID: 'scheduling', Label: 'Scheduling', Icon: 'fa-solid fa-clock', Description: 'Manage automated pipeline schedules' },
748
767
  ];
749
768
  ActiveSection = 'pipeline';
750
769
  IsLoading = true;
@@ -811,6 +830,10 @@ let KnowledgeConfigResourceComponent = class KnowledgeConfigResourceComponent ex
811
830
  NewIndexEmbeddingModelID = '';
812
831
  ngAfterViewInit() {
813
832
  this.loadConfiguration();
833
+ this.navigationService.SetAgentContext(this, {
834
+ ActiveSection: this.ActiveSection,
835
+ });
836
+ this.NotifyLoadComplete();
814
837
  }
815
838
  ngOnDestroy() {
816
839
  this.destroy$.next();
@@ -949,7 +972,7 @@ let KnowledgeConfigResourceComponent = class KnowledgeConfigResourceComponent ex
949
972
  // Use KnowledgeHubMetadataEngine for cached vector DBs, indexes, and entity docs
950
973
  const engine = KnowledgeHubMetadataEngine.Instance;
951
974
  await engine.Config(false);
952
- this.loadVectorDBProvidersFromEngine(engine.VectorDatabases);
975
+ this.loadVectorDBProvidersFromEngine(AIEngineBase.Instance.VectorDatabases);
953
976
  this.loadVectorIndexesFromEngine(engine.VectorIndexes);
954
977
  this.loadEntityDocumentsAndThresholds(engine.GetActiveEntityDocuments());
955
978
  // AI Models come from a different domain — fetch via RunView
@@ -1064,11 +1087,11 @@ let KnowledgeConfigResourceComponent = class KnowledgeConfigResourceComponent ex
1064
1087
  }));
1065
1088
  }
1066
1089
  static ɵfac = /*@__PURE__*/ (() => { let ɵKnowledgeConfigResourceComponent_BaseFactory; return function KnowledgeConfigResourceComponent_Factory(__ngFactoryType__) { return (ɵKnowledgeConfigResourceComponent_BaseFactory || (ɵKnowledgeConfigResourceComponent_BaseFactory = i0.ɵɵgetInheritedFactory(KnowledgeConfigResourceComponent)))(__ngFactoryType__ || KnowledgeConfigResourceComponent); }; })();
1067
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: KnowledgeConfigResourceComponent, selectors: [["app-knowledge-config-resource"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 2, vars: 1, consts: [[1, "config-loading"], [1, "config-layout"], ["text", "Loading configuration...", "size", "medium"], [1, "config-nav"], [1, "config-nav-header"], [1, "fa-solid", "fa-cogs"], [1, "config-nav-item", 3, "config-nav-item-active"], [1, "config-content"], [1, "config-section"], [1, "config-save-bar"], [1, "config-nav-item", 3, "click"], [1, "config-section-title"], [1, "config-section-desc"], [1, "config-group"], [1, "config-toggle-row"], [1, "config-toggle-info"], [1, "config-label"], [1, "config-hint"], ["type", "checkbox", 1, "config-checkbox", 3, "ngModelChange", "change", "ngModel"], [1, "config-field-row"], [1, "config-field-info"], ["type", "number", "min", "10", "max", "1000", 1, "config-input", "config-input-number", 3, "ngModelChange", "input", "ngModel"], ["type", "number", "min", "1", "max", "10", 1, "config-input", "config-input-number", 3, "ngModelChange", "input", "ngModel"], [1, "setup-progress"], [1, "setup-progress-header"], [1, "setup-progress-label"], [1, "setup-progress-count"], [1, "setup-progress-bar"], [1, "setup-progress-fill"], [1, "setup-step"], [1, "setup-step-header"], [1, "setup-step-indicator"], [1, "fa-solid", "fa-circle-check"], [1, "setup-step-number"], [1, "setup-step-info"], [1, "setup-step-title"], [1, "setup-step-status"], [1, "setup-step-detail"], [1, "setup-step-action"], [1, "create-index-form"], [1, "provider-card"], [1, "provider-icon"], [1, "fa-solid", "fa-database"], [1, "provider-info"], [1, "provider-name"], [1, "provider-class"], [1, "config-status-badge", "config-status-active"], [1, "config-tag-list"], [1, "config-tag"], [1, "setup-step-action", 3, "click"], [1, "fa-solid", "fa-plus"], [1, "index-card"], [1, "index-icon"], [1, "fa-solid", "fa-cubes"], [1, "index-info"], [1, "index-name"], [1, "index-meta"], [1, "fa-solid", "fa-microchip"], [1, "index-actions"], ["title", "Delete index", 1, "index-delete-btn", 3, "click"], [1, "fa-solid", "fa-trash-can"], [1, "create-index-title"], [1, "fa-solid", "fa-plus-circle"], [1, "create-index-fields"], [1, "create-index-field"], [1, "create-index-label"], ["type", "text", "placeholder", "e.g., mj-knowledge-index", 1, "config-input", 3, "ngModelChange", "ngModel"], [1, "config-select", 3, "ngModelChange", "ngModel"], [3, "value"], [1, "create-index-actions"], [1, "create-index-submit", 3, "click", "disabled"], [1, "create-index-cancel", 3, "click", "disabled"], [1, "fa-solid", "fa-spinner", "fa-spin"], ["text", "Discovering searchable entities...", "size", "medium"], [1, "config-empty-state"], [1, "fa-solid", "fa-text-width", "config-empty-icon"], [1, "config-empty-title"], [1, "config-empty-text"], [1, "fts-entity-controls"], [1, "fts-summary"], [1, "fts-summary-count"], ["type", "text", "placeholder", "Filter entities...", 1, "config-input", "fts-filter-input", 3, "ngModelChange", "ngModel"], [1, "fts-entity-list"], [1, "fts-entity-card", 3, "fts-entity-enabled"], [1, "fts-entity-card"], [1, "fts-entity-toggle"], [1, "fts-entity-info"], [1, "fts-entity-name"], [1, "fts-entity-fields"], [1, "fts-field-tag"], [1, "fts-entity-meta"], ["title", "Title field", 1, "fts-entity-title-field"], [1, "fa-solid", "fa-heading"], ["title", "Snippet field", 1, "fts-entity-snippet-field"], [1, "fa-solid", "fa-align-left"], [1, "config-value-display"], [1, "config-section-note"], [1, "fa-solid", "fa-info-circle"], [1, "fa-solid", "fa-microchip", "config-empty-icon"], ["type", "range", "min", "0.5", "max", "1", "step", "0.01", 1, "config-slider", 3, "ngModelChange", "input", "ngModel"], ["type", "range", "min", "0.3", "max", "1", "step", "0.01", 1, "config-slider", 3, "ngModelChange", "input", "ngModel"], ["type", "range", "min", "0", "max", "1", "step", "0.01", 1, "config-slider", 3, "ngModelChange", "input", "ngModel"], [1, "config-save-text"], [1, "config-save-btn", 3, "click", "disabled"], [1, "config-reset-btn", 3, "click", "disabled"], [1, "fa-solid", "fa-save"]], template: function KnowledgeConfigResourceComponent_Template(rf, ctx) { if (rf & 1) {
1068
- i0.ɵɵconditionalCreate(0, KnowledgeConfigResourceComponent_Conditional_0_Template, 2, 0, "div", 0)(1, KnowledgeConfigResourceComponent_Conditional_1_Template, 15, 6, "div", 1);
1090
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: KnowledgeConfigResourceComponent, selectors: [["app-knowledge-config-resource"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 2, vars: 1, consts: [[1, "config-loading"], [1, "config-layout"], ["text", "Loading configuration...", "size", "medium"], [1, "config-nav"], [1, "config-nav-header"], [1, "fa-solid", "fa-cogs"], [1, "config-nav-item", 3, "config-nav-item-active"], [1, "config-content"], [1, "config-section"], [1, "config-section-content"], [1, "config-save-bar"], [1, "config-nav-item", 3, "click"], [1, "config-section-title"], [1, "config-section-desc"], [1, "config-group"], [1, "config-toggle-row"], [1, "config-toggle-info"], [1, "config-label"], [1, "config-hint"], ["type", "checkbox", 1, "config-checkbox", 3, "ngModelChange", "change", "ngModel"], [1, "config-field-row"], [1, "config-field-info"], ["type", "number", "min", "10", "max", "1000", 1, "config-input", "config-input-number", 3, "ngModelChange", "input", "ngModel"], ["type", "number", "min", "1", "max", "10", 1, "config-input", "config-input-number", 3, "ngModelChange", "input", "ngModel"], [1, "setup-progress"], [1, "setup-progress-header"], [1, "setup-progress-label"], [1, "setup-progress-count"], [1, "setup-progress-bar"], [1, "setup-progress-fill"], [1, "setup-step"], [1, "setup-step-header"], [1, "setup-step-indicator"], [1, "fa-solid", "fa-circle-check"], [1, "setup-step-number"], [1, "setup-step-info"], [1, "setup-step-title"], [1, "setup-step-status"], [1, "setup-step-detail"], [1, "setup-step-action"], [1, "create-index-form"], [1, "provider-card"], [1, "provider-icon"], [1, "fa-solid", "fa-database"], [1, "provider-info"], [1, "provider-name"], [1, "provider-class"], [1, "config-status-badge", "config-status-active"], [1, "config-tag-list"], [1, "config-tag"], [1, "setup-step-action", 3, "click"], [1, "fa-solid", "fa-plus"], [1, "index-card"], [1, "index-icon"], [1, "fa-solid", "fa-cubes"], [1, "index-info"], [1, "index-name"], [1, "index-meta"], [1, "fa-solid", "fa-microchip"], [1, "index-actions"], ["title", "Delete index", 1, "index-delete-btn", 3, "click"], [1, "fa-solid", "fa-trash-can"], [1, "create-index-title"], [1, "fa-solid", "fa-plus-circle"], [1, "create-index-fields"], [1, "create-index-field"], [1, "create-index-label"], ["type", "text", "placeholder", "e.g., mj-knowledge-index", 1, "config-input", 3, "ngModelChange", "ngModel"], [1, "config-select", 3, "ngModelChange", "ngModel"], [3, "value"], [1, "create-index-actions"], [1, "create-index-submit", 3, "click", "disabled"], [1, "create-index-cancel", 3, "click", "disabled"], [1, "fa-solid", "fa-spinner", "fa-spin"], ["text", "Discovering searchable entities...", "size", "medium"], [1, "config-empty-state"], [1, "fa-solid", "fa-text-width", "config-empty-icon"], [1, "config-empty-title"], [1, "config-empty-text"], [1, "fts-entity-controls"], [1, "fts-summary"], [1, "fts-summary-count"], ["type", "text", "placeholder", "Filter entities...", 1, "config-input", "fts-filter-input", 3, "ngModelChange", "ngModel"], [1, "fts-entity-list"], [1, "fts-entity-card", 3, "fts-entity-enabled"], [1, "fts-entity-card"], [1, "fts-entity-toggle"], [1, "fts-entity-info"], [1, "fts-entity-name"], [1, "fts-entity-fields"], [1, "fts-field-tag"], [1, "fts-entity-meta"], ["title", "Title field", 1, "fts-entity-title-field"], [1, "fa-solid", "fa-heading"], ["title", "Snippet field", 1, "fts-entity-snippet-field"], [1, "fa-solid", "fa-align-left"], [1, "config-value-display"], [1, "config-section-note"], [1, "fa-solid", "fa-info-circle"], [1, "fa-solid", "fa-microchip", "config-empty-icon"], ["type", "range", "min", "0.5", "max", "1", "step", "0.01", 1, "config-slider", 3, "ngModelChange", "input", "ngModel"], ["type", "range", "min", "0.3", "max", "1", "step", "0.01", 1, "config-slider", 3, "ngModelChange", "input", "ngModel"], ["type", "range", "min", "0", "max", "1", "step", "0.01", 1, "config-slider", 3, "ngModelChange", "input", "ngModel"], [1, "fa-solid", "fa-clock"], [2, "margin-top", "16px"], [1, "config-save-text"], [1, "config-save-btn", 3, "click", "disabled"], [1, "config-reset-btn", 3, "click", "disabled"], [1, "fa-solid", "fa-save"]], template: function KnowledgeConfigResourceComponent_Template(rf, ctx) { if (rf & 1) {
1091
+ i0.ɵɵconditionalCreate(0, KnowledgeConfigResourceComponent_Conditional_0_Template, 2, 0, "div", 0)(1, KnowledgeConfigResourceComponent_Conditional_1_Template, 16, 7, "div", 1);
1069
1092
  } if (rf & 2) {
1070
1093
  i0.ɵɵconditional(ctx.IsLoading ? 0 : 1);
1071
- } }, dependencies: [i1.NgSelectOption, i1.ɵNgSelectMultipleOption, i1.DefaultValueAccessor, i1.NumberValueAccessor, i1.RangeValueAccessor, i1.CheckboxControlValueAccessor, i1.SelectControlValueAccessor, i1.NgControlStatus, i1.MinValidator, i1.MaxValidator, i1.NgModel, i2.LoadingComponent], styles: ["\n\n\n.config-loading[_ngcontent-%COMP%] {\n display: flex;\n justify-content: center;\n align-items: center;\n height: 400px;\n}\n\n.config-layout[_ngcontent-%COMP%] {\n display: flex;\n height: 100%;\n min-height: 500px;\n}\n\n\n\n.config-nav[_ngcontent-%COMP%] {\n width: 240px;\n border-right: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n flex-shrink: 0;\n display: flex;\n flex-direction: column;\n padding: 0.5rem 0;\n}\n\n.config-nav-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.75rem 1rem;\n font-weight: 600;\n font-size: 0.9rem;\n color: var(--mj-text-primary);\n border-bottom: 1px solid var(--mj-border-subtle);\n margin-bottom: 0.5rem;\n}\n\n.config-nav-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.6rem;\n padding: 0.55rem 1rem;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 0.85rem;\n cursor: pointer;\n text-align: left;\n transition: all 0.15s ease;\n width: 100%;\n}\n\n.config-nav-item[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n}\n\n.config-nav-item-active[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-left: 3px solid var(--mj-brand-primary);\n}\n\n\n\n.config-content[_ngcontent-%COMP%] {\n flex: 1;\n padding: 1.5rem 2rem;\n overflow-y: auto;\n position: relative;\n}\n\n.config-section[_ngcontent-%COMP%] {\n max-width: 700px;\n}\n\n.config-section-title[_ngcontent-%COMP%] {\n font-size: 1.3rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 0.5rem;\n}\n\n.config-section-desc[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n font-size: 0.9rem;\n margin-bottom: 1.5rem;\n line-height: 1.5;\n}\n\n\n\n.config-group[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n}\n\n.config-toggle-row[_ngcontent-%COMP%], \n.config-field-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0.75rem 1rem;\n border-radius: 8px;\n transition: background 0.1s ease;\n gap: 1rem;\n}\n\n.config-toggle-row[_ngcontent-%COMP%]:hover, \n.config-field-row[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.config-toggle-info[_ngcontent-%COMP%], \n.config-field-info[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.15rem;\n flex: 1;\n}\n\n.config-label[_ngcontent-%COMP%] {\n font-weight: 500;\n font-size: 0.9rem;\n color: var(--mj-text-primary);\n}\n\n.config-hint[_ngcontent-%COMP%] {\n font-size: 0.78rem;\n color: var(--mj-text-muted);\n}\n\n.config-checkbox[_ngcontent-%COMP%] {\n width: 1.1rem;\n height: 1.1rem;\n cursor: pointer;\n accent-color: var(--mj-brand-primary);\n}\n\n.config-input[_ngcontent-%COMP%] {\n padding: 0.4rem 0.6rem;\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: 0.85rem;\n font-family: inherit;\n}\n\n.config-input-number[_ngcontent-%COMP%] {\n width: 80px;\n text-align: center;\n}\n\n.config-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.config-slider[_ngcontent-%COMP%] {\n width: 200px;\n accent-color: var(--mj-brand-primary);\n cursor: pointer;\n}\n\n.config-value-display[_ngcontent-%COMP%] {\n font-size: 0.85rem;\n color: var(--mj-text-secondary);\n padding: 0.3rem 0.6rem;\n background: var(--mj-bg-surface-sunken);\n border-radius: 4px;\n font-family: monospace;\n}\n\n\n\n.config-placeholder[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 3rem 1.5rem;\n text-align: center;\n gap: 1rem;\n color: var(--mj-text-muted);\n}\n\n.config-placeholder-icon[_ngcontent-%COMP%] {\n font-size: 2.5rem;\n}\n\n\n\n\n.setup-progress[_ngcontent-%COMP%] {\n margin-bottom: 1.5rem;\n padding: 1rem 1.25rem;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 10px;\n}\n\n.setup-progress-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 0.5rem;\n}\n\n.setup-progress-label[_ngcontent-%COMP%] {\n font-size: 0.82rem;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.setup-progress-count[_ngcontent-%COMP%] {\n font-size: 0.78rem;\n color: var(--mj-text-muted);\n}\n\n.setup-progress-bar[_ngcontent-%COMP%] {\n height: 6px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 3px;\n overflow: hidden;\n}\n\n.setup-progress-fill[_ngcontent-%COMP%] {\n height: 100%;\n background: var(--mj-brand-primary);\n border-radius: 3px;\n transition: width 0.4s ease;\n}\n\n\n\n\n.setup-step[_ngcontent-%COMP%] {\n padding: 1rem 1.25rem;\n border: 1px solid var(--mj-border-subtle);\n border-radius: 10px;\n margin-bottom: 0.75rem;\n transition: border-color 0.2s;\n}\n\n.setup-step-complete[_ngcontent-%COMP%] {\n border-color: var(--mj-status-success-border);\n background: color-mix(in srgb, var(--mj-status-success) 3%, var(--mj-bg-surface));\n}\n\n.setup-step-pending[_ngcontent-%COMP%] {\n border-color: var(--mj-border-default);\n background: var(--mj-bg-surface);\n}\n\n.setup-step-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 0.85rem;\n}\n\n.setup-step-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n flex-shrink: 0;\n margin-top: 1px;\n}\n\n.setup-step-complete[_ngcontent-%COMP%] .setup-step-indicator[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1.25rem;\n color: var(--mj-status-success);\n}\n\n.setup-step-number[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n border-radius: 50%;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n font-size: 0.75rem;\n font-weight: 700;\n}\n\n.setup-step-info[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n flex: 1;\n}\n\n.setup-step-title[_ngcontent-%COMP%] {\n font-size: 0.9rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.setup-step-status[_ngcontent-%COMP%] {\n font-size: 0.8rem;\n color: var(--mj-text-muted);\n line-height: 1.4;\n}\n\n.setup-step-complete[_ngcontent-%COMP%] .setup-step-status[_ngcontent-%COMP%] {\n color: var(--mj-status-success-text);\n}\n\n\n\n\n.config-group-title[_ngcontent-%COMP%] {\n margin: 0 0 0.75rem 0;\n font-size: 0.85rem;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.04em;\n}\n\n\n\n\n.config-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: 0.75rem;\n font-weight: 600;\n}\n\n.config-status-active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 12%, var(--mj-bg-surface));\n color: var(--mj-status-success-text);\n}\n\n\n\n\n.setup-step-detail[_ngcontent-%COMP%] {\n margin-top: 0.75rem;\n padding-left: 2.85rem;\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.setup-step-action[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 6px 14px;\n border: 1px solid var(--mj-brand-primary);\n border-radius: 6px;\n background: transparent;\n color: var(--mj-brand-primary);\n font-size: 0.78rem;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s;\n flex-shrink: 0;\n}\n\n.setup-step-action[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n\n\n\n.provider-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1rem;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 8px;\n}\n\n.provider-icon[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n border-radius: 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 1rem;\n flex-shrink: 0;\n}\n\n.provider-info[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n flex: 1;\n min-width: 0;\n}\n\n.provider-name[_ngcontent-%COMP%] {\n font-size: 0.9rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.provider-class[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n color: var(--mj-text-muted);\n font-family: monospace;\n}\n\n\n\n\n.index-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1rem;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 8px;\n transition: border-color 0.15s;\n}\n\n.index-card[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-border-default);\n}\n\n.index-icon[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n border-radius: 8px;\n background: color-mix(in srgb, var(--mj-status-info) 10%, var(--mj-bg-surface));\n color: var(--mj-status-info);\n font-size: 1rem;\n flex-shrink: 0;\n}\n\n.index-info[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n flex: 1;\n min-width: 0;\n}\n\n.index-name[_ngcontent-%COMP%] {\n font-size: 0.9rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.index-meta[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n color: var(--mj-text-muted);\n display: flex;\n align-items: center;\n gap: 3px;\n}\n\n.index-meta[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.65rem;\n}\n\n.index-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n flex-shrink: 0;\n}\n\n.index-delete-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: transparent;\n color: var(--mj-text-muted);\n font-size: 0.75rem;\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.index-delete-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n border-color: var(--mj-status-error-border);\n color: var(--mj-status-error);\n}\n\n\n\n\n.create-index-form[_ngcontent-%COMP%] {\n margin-top: 0.75rem;\n padding: 1.25rem;\n background: var(--mj-bg-surface-card);\n border: 2px solid var(--mj-brand-primary);\n border-radius: 10px;\n margin-left: 2.85rem;\n}\n\n.create-index-title[_ngcontent-%COMP%] {\n margin: 0 0 1rem 0;\n font-size: 0.9rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.create-index-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.create-index-fields[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.85rem;\n}\n\n.create-index-field[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.create-index-label[_ngcontent-%COMP%] {\n font-size: 0.78rem;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n.config-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: 0.85rem;\n}\n\n.config-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.create-index-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n margin-top: 1rem;\n}\n\n.create-index-submit[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 18px;\n border: none;\n border-radius: 6px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 0.82rem;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.15s;\n}\n\n.create-index-submit[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n.create-index-submit[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.create-index-cancel[_ngcontent-%COMP%] {\n padding: 8px 18px;\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 font-weight: 500;\n cursor: pointer;\n}\n\n.create-index-cancel[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n\n\n.config-empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 3rem 2rem;\n text-align: center;\n gap: 0.75rem;\n border: 2px dashed var(--mj-border-default);\n border-radius: 12px;\n background: var(--mj-bg-surface-sunken);\n}\n\n.config-empty-icon[_ngcontent-%COMP%] {\n font-size: 2.5rem;\n color: var(--mj-text-disabled);\n}\n\n.config-empty-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 1rem;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.config-empty-text[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 0.85rem;\n color: var(--mj-text-muted);\n max-width: 480px;\n line-height: 1.5;\n}\n\n\n\n.config-tag-list[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n}\n\n.config-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: 0.78rem;\n font-weight: 500;\n}\n\n\n\n.config-section-note[_ngcontent-%COMP%] {\n margin-top: 1rem;\n font-size: 0.8rem;\n color: var(--mj-text-muted);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.config-section-note[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-info);\n}\n\n\n\n.config-save-bar[_ngcontent-%COMP%] {\n position: sticky;\n bottom: 0;\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1rem;\n margin-top: 2rem;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n}\n\n.config-save-text[_ngcontent-%COMP%] {\n flex: 1;\n color: var(--mj-text-secondary);\n font-size: 0.85rem;\n}\n\n.config-save-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n padding: 0.5rem 1rem;\n border-radius: 6px;\n border: none;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 0.85rem;\n font-weight: 500;\n cursor: pointer;\n}\n\n.config-save-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n.config-save-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.config-reset-btn[_ngcontent-%COMP%] {\n padding: 0.5rem 0.75rem;\n border-radius: 6px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 0.85rem;\n cursor: pointer;\n}\n\n.config-reset-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover);\n}\n\n\n\n@media (max-width: 768px) {\n .config-layout[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n\n .config-nav[_ngcontent-%COMP%] {\n width: 100%;\n flex-direction: row;\n overflow-x: auto;\n border-right: none;\n border-bottom: 1px solid var(--mj-border-default);\n padding: 0;\n }\n\n .config-nav-header[_ngcontent-%COMP%] {\n display: none;\n }\n\n .config-nav-item[_ngcontent-%COMP%] {\n white-space: nowrap;\n padding: 0.6rem 1rem;\n }\n\n .config-nav-item-active[_ngcontent-%COMP%] {\n border-left: none;\n border-bottom: 3px solid var(--mj-brand-primary);\n }\n\n .config-content[_ngcontent-%COMP%] {\n padding: 1rem;\n }\n}\n\n\n\n.fts-entity-controls[_ngcontent-%COMP%] {\n margin-bottom: 16px;\n}\n\n.fts-summary[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n}\n\n.fts-summary-count[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n\n.fts-filter-input[_ngcontent-%COMP%] {\n max-width: 240px;\n}\n\n.fts-entity-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.fts-entity-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 14px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n transition: border-color 0.15s, background 0.15s;\n}\n\n.fts-entity-card[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-border-strong);\n}\n\n.fts-entity-card.fts-entity-enabled[_ngcontent-%COMP%] {\n border-color: color-mix(in srgb, var(--mj-brand-primary) 30%, var(--mj-border-default));\n background: color-mix(in srgb, var(--mj-brand-primary) 3%, var(--mj-bg-surface));\n}\n\n.fts-entity-toggle[_ngcontent-%COMP%] {\n flex-shrink: 0;\n}\n\n.fts-entity-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.fts-entity-name[_ngcontent-%COMP%] {\n display: block;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin-bottom: 4px;\n}\n\n.fts-entity-fields[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n}\n\n.fts-field-tag[_ngcontent-%COMP%] {\n display: inline-block;\n padding: 1px 6px;\n font-size: 11px;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-sunken);\n border-radius: 4px;\n}\n\n.fts-entity-meta[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n gap: 2px;\n flex-shrink: 0;\n}\n\n.fts-entity-title-field[_ngcontent-%COMP%], \n.fts-entity-snippet-field[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n white-space: nowrap;\n}\n\n.fts-entity-title-field[_ngcontent-%COMP%] i[_ngcontent-%COMP%], \n.fts-entity-snippet-field[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-right: 4px;\n font-size: 10px;\n}"] });
1094
+ } }, dependencies: [i1.NgSelectOption, i1.ɵNgSelectMultipleOption, i1.DefaultValueAccessor, i1.NumberValueAccessor, i1.RangeValueAccessor, i1.CheckboxControlValueAccessor, i1.SelectControlValueAccessor, i1.NgControlStatus, i1.MinValidator, i1.MaxValidator, i1.NgModel, i2.LoadingComponent, i3.SchedulingResourceComponent], styles: ["\n\n\n.config-loading[_ngcontent-%COMP%] {\n display: flex;\n justify-content: center;\n align-items: center;\n height: 400px;\n}\n\n.config-layout[_ngcontent-%COMP%] {\n display: flex;\n height: 100%;\n min-height: 500px;\n}\n\n\n\n.config-nav[_ngcontent-%COMP%] {\n width: 240px;\n border-right: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n flex-shrink: 0;\n display: flex;\n flex-direction: column;\n padding: 0.5rem 0;\n}\n\n.config-nav-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.75rem 1rem;\n font-weight: 600;\n font-size: 0.9rem;\n color: var(--mj-text-primary);\n border-bottom: 1px solid var(--mj-border-subtle);\n margin-bottom: 0.5rem;\n}\n\n.config-nav-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.6rem;\n padding: 0.55rem 1rem;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 0.85rem;\n cursor: pointer;\n text-align: left;\n transition: all 0.15s ease;\n width: 100%;\n}\n\n.config-nav-item[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n}\n\n.config-nav-item-active[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-left: 3px solid var(--mj-brand-primary);\n}\n\n\n\n.config-content[_ngcontent-%COMP%] {\n flex: 1;\n padding: 1.5rem 2rem;\n overflow-y: auto;\n position: relative;\n}\n\n.config-section[_ngcontent-%COMP%] {\n max-width: 700px;\n}\n\n.config-section-title[_ngcontent-%COMP%] {\n font-size: 1.3rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 0.5rem;\n}\n\n.config-section-desc[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n font-size: 0.9rem;\n margin-bottom: 1.5rem;\n line-height: 1.5;\n}\n\n\n\n.config-group[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n}\n\n.config-toggle-row[_ngcontent-%COMP%], \n.config-field-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0.75rem 1rem;\n border-radius: 8px;\n transition: background 0.1s ease;\n gap: 1rem;\n}\n\n.config-toggle-row[_ngcontent-%COMP%]:hover, \n.config-field-row[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.config-toggle-info[_ngcontent-%COMP%], \n.config-field-info[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.15rem;\n flex: 1;\n}\n\n.config-label[_ngcontent-%COMP%] {\n font-weight: 500;\n font-size: 0.9rem;\n color: var(--mj-text-primary);\n}\n\n.config-hint[_ngcontent-%COMP%] {\n font-size: 0.78rem;\n color: var(--mj-text-muted);\n}\n\n.config-checkbox[_ngcontent-%COMP%] {\n width: 1.1rem;\n height: 1.1rem;\n cursor: pointer;\n accent-color: var(--mj-brand-primary);\n}\n\n.config-input[_ngcontent-%COMP%] {\n padding: 0.4rem 0.6rem;\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: 0.85rem;\n font-family: inherit;\n}\n\n.config-input-number[_ngcontent-%COMP%] {\n width: 80px;\n text-align: center;\n}\n\n.config-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.config-slider[_ngcontent-%COMP%] {\n width: 200px;\n accent-color: var(--mj-brand-primary);\n cursor: pointer;\n}\n\n.config-value-display[_ngcontent-%COMP%] {\n font-size: 0.85rem;\n color: var(--mj-text-secondary);\n padding: 0.3rem 0.6rem;\n background: var(--mj-bg-surface-sunken);\n border-radius: 4px;\n font-family: monospace;\n}\n\n\n\n.config-placeholder[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 3rem 1.5rem;\n text-align: center;\n gap: 1rem;\n color: var(--mj-text-muted);\n}\n\n.config-placeholder-icon[_ngcontent-%COMP%] {\n font-size: 2.5rem;\n}\n\n\n\n\n.setup-progress[_ngcontent-%COMP%] {\n margin-bottom: 1.5rem;\n padding: 1rem 1.25rem;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 10px;\n}\n\n.setup-progress-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 0.5rem;\n}\n\n.setup-progress-label[_ngcontent-%COMP%] {\n font-size: 0.82rem;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.setup-progress-count[_ngcontent-%COMP%] {\n font-size: 0.78rem;\n color: var(--mj-text-muted);\n}\n\n.setup-progress-bar[_ngcontent-%COMP%] {\n height: 6px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 3px;\n overflow: hidden;\n}\n\n.setup-progress-fill[_ngcontent-%COMP%] {\n height: 100%;\n background: var(--mj-brand-primary);\n border-radius: 3px;\n transition: width 0.4s ease;\n}\n\n\n\n\n.setup-step[_ngcontent-%COMP%] {\n padding: 1rem 1.25rem;\n border: 1px solid var(--mj-border-subtle);\n border-radius: 10px;\n margin-bottom: 0.75rem;\n transition: border-color 0.2s;\n}\n\n.setup-step-complete[_ngcontent-%COMP%] {\n border-color: var(--mj-status-success-border);\n background: color-mix(in srgb, var(--mj-status-success) 3%, var(--mj-bg-surface));\n}\n\n.setup-step-pending[_ngcontent-%COMP%] {\n border-color: var(--mj-border-default);\n background: var(--mj-bg-surface);\n}\n\n.setup-step-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 0.85rem;\n}\n\n.setup-step-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n flex-shrink: 0;\n margin-top: 1px;\n}\n\n.setup-step-complete[_ngcontent-%COMP%] .setup-step-indicator[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1.25rem;\n color: var(--mj-status-success);\n}\n\n.setup-step-number[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n border-radius: 50%;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n font-size: 0.75rem;\n font-weight: 700;\n}\n\n.setup-step-info[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n flex: 1;\n}\n\n.setup-step-title[_ngcontent-%COMP%] {\n font-size: 0.9rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.setup-step-status[_ngcontent-%COMP%] {\n font-size: 0.8rem;\n color: var(--mj-text-muted);\n line-height: 1.4;\n}\n\n.setup-step-complete[_ngcontent-%COMP%] .setup-step-status[_ngcontent-%COMP%] {\n color: var(--mj-status-success-text);\n}\n\n\n\n\n.config-group-title[_ngcontent-%COMP%] {\n margin: 0 0 0.75rem 0;\n font-size: 0.85rem;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.04em;\n}\n\n\n\n\n.config-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: 0.75rem;\n font-weight: 600;\n}\n\n.config-status-active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 12%, var(--mj-bg-surface));\n color: var(--mj-status-success-text);\n}\n\n\n\n\n.setup-step-detail[_ngcontent-%COMP%] {\n margin-top: 0.75rem;\n padding-left: 2.85rem;\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.setup-step-action[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 6px 14px;\n border: 1px solid var(--mj-brand-primary);\n border-radius: 6px;\n background: transparent;\n color: var(--mj-brand-primary);\n font-size: 0.78rem;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s;\n flex-shrink: 0;\n}\n\n.setup-step-action[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n\n\n\n.provider-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1rem;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 8px;\n}\n\n.provider-icon[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n border-radius: 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 1rem;\n flex-shrink: 0;\n}\n\n.provider-info[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n flex: 1;\n min-width: 0;\n}\n\n.provider-name[_ngcontent-%COMP%] {\n font-size: 0.9rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.provider-class[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n color: var(--mj-text-muted);\n font-family: monospace;\n}\n\n\n\n\n.index-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1rem;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 8px;\n transition: border-color 0.15s;\n}\n\n.index-card[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-border-default);\n}\n\n.index-icon[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n border-radius: 8px;\n background: color-mix(in srgb, var(--mj-status-info) 10%, var(--mj-bg-surface));\n color: var(--mj-status-info);\n font-size: 1rem;\n flex-shrink: 0;\n}\n\n.index-info[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n flex: 1;\n min-width: 0;\n}\n\n.index-name[_ngcontent-%COMP%] {\n font-size: 0.9rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.index-meta[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n color: var(--mj-text-muted);\n display: flex;\n align-items: center;\n gap: 3px;\n}\n\n.index-meta[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.65rem;\n}\n\n.index-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n flex-shrink: 0;\n}\n\n.index-delete-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: transparent;\n color: var(--mj-text-muted);\n font-size: 0.75rem;\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.index-delete-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n border-color: var(--mj-status-error-border);\n color: var(--mj-status-error);\n}\n\n\n\n\n.create-index-form[_ngcontent-%COMP%] {\n margin-top: 0.75rem;\n padding: 1.25rem;\n background: var(--mj-bg-surface-card);\n border: 2px solid var(--mj-brand-primary);\n border-radius: 10px;\n margin-left: 2.85rem;\n}\n\n.create-index-title[_ngcontent-%COMP%] {\n margin: 0 0 1rem 0;\n font-size: 0.9rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.create-index-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.create-index-fields[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.85rem;\n}\n\n.create-index-field[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.create-index-label[_ngcontent-%COMP%] {\n font-size: 0.78rem;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n.config-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: 0.85rem;\n}\n\n.config-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.create-index-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n margin-top: 1rem;\n}\n\n.create-index-submit[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 18px;\n border: none;\n border-radius: 6px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 0.82rem;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.15s;\n}\n\n.create-index-submit[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n.create-index-submit[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.create-index-cancel[_ngcontent-%COMP%] {\n padding: 8px 18px;\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 font-weight: 500;\n cursor: pointer;\n}\n\n.create-index-cancel[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n\n\n.config-empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 3rem 2rem;\n text-align: center;\n gap: 0.75rem;\n border: 2px dashed var(--mj-border-default);\n border-radius: 12px;\n background: var(--mj-bg-surface-sunken);\n}\n\n.config-empty-icon[_ngcontent-%COMP%] {\n font-size: 2.5rem;\n color: var(--mj-text-disabled);\n}\n\n.config-empty-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 1rem;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.config-empty-text[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 0.85rem;\n color: var(--mj-text-muted);\n max-width: 480px;\n line-height: 1.5;\n}\n\n\n\n.config-tag-list[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n}\n\n.config-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: 0.78rem;\n font-weight: 500;\n}\n\n\n\n.config-section-note[_ngcontent-%COMP%] {\n margin-top: 1rem;\n font-size: 0.8rem;\n color: var(--mj-text-muted);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.config-section-note[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-info);\n}\n\n\n\n.config-save-bar[_ngcontent-%COMP%] {\n position: sticky;\n bottom: 0;\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1rem;\n margin-top: 2rem;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n}\n\n.config-save-text[_ngcontent-%COMP%] {\n flex: 1;\n color: var(--mj-text-secondary);\n font-size: 0.85rem;\n}\n\n.config-save-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n padding: 0.5rem 1rem;\n border-radius: 6px;\n border: none;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 0.85rem;\n font-weight: 500;\n cursor: pointer;\n}\n\n.config-save-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n.config-save-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.config-reset-btn[_ngcontent-%COMP%] {\n padding: 0.5rem 0.75rem;\n border-radius: 6px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 0.85rem;\n cursor: pointer;\n}\n\n.config-reset-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover);\n}\n\n\n\n@media (max-width: 768px) {\n .config-layout[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n\n .config-nav[_ngcontent-%COMP%] {\n width: 100%;\n flex-direction: row;\n overflow-x: auto;\n border-right: none;\n border-bottom: 1px solid var(--mj-border-default);\n padding: 0;\n }\n\n .config-nav-header[_ngcontent-%COMP%] {\n display: none;\n }\n\n .config-nav-item[_ngcontent-%COMP%] {\n white-space: nowrap;\n padding: 0.6rem 1rem;\n }\n\n .config-nav-item-active[_ngcontent-%COMP%] {\n border-left: none;\n border-bottom: 3px solid var(--mj-brand-primary);\n }\n\n .config-content[_ngcontent-%COMP%] {\n padding: 1rem;\n }\n}\n\n\n\n.fts-entity-controls[_ngcontent-%COMP%] {\n margin-bottom: 16px;\n}\n\n.fts-summary[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n}\n\n.fts-summary-count[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n\n.fts-filter-input[_ngcontent-%COMP%] {\n max-width: 240px;\n}\n\n.fts-entity-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.fts-entity-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 14px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n transition: border-color 0.15s, background 0.15s;\n}\n\n.fts-entity-card[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-border-strong);\n}\n\n.fts-entity-card.fts-entity-enabled[_ngcontent-%COMP%] {\n border-color: color-mix(in srgb, var(--mj-brand-primary) 30%, var(--mj-border-default));\n background: color-mix(in srgb, var(--mj-brand-primary) 3%, var(--mj-bg-surface));\n}\n\n.fts-entity-toggle[_ngcontent-%COMP%] {\n flex-shrink: 0;\n}\n\n.fts-entity-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.fts-entity-name[_ngcontent-%COMP%] {\n display: block;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin-bottom: 4px;\n}\n\n.fts-entity-fields[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n}\n\n.fts-field-tag[_ngcontent-%COMP%] {\n display: inline-block;\n padding: 1px 6px;\n font-size: 11px;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-sunken);\n border-radius: 4px;\n}\n\n.fts-entity-meta[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n gap: 2px;\n flex-shrink: 0;\n}\n\n.fts-entity-title-field[_ngcontent-%COMP%], \n.fts-entity-snippet-field[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n white-space: nowrap;\n}\n\n.fts-entity-title-field[_ngcontent-%COMP%] i[_ngcontent-%COMP%], \n.fts-entity-snippet-field[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-right: 4px;\n font-size: 10px;\n}"] });
1072
1095
  };
1073
1096
  KnowledgeConfigResourceComponent = __decorate([
1074
1097
  RegisterClass(BaseResourceComponent, 'KnowledgeConfigResource')
@@ -1076,9 +1099,9 @@ KnowledgeConfigResourceComponent = __decorate([
1076
1099
  export { KnowledgeConfigResourceComponent };
1077
1100
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(KnowledgeConfigResourceComponent, [{
1078
1101
  type: Component,
1079
- args: [{ standalone: false, selector: 'app-knowledge-config-resource', template: "@if (IsLoading) {\n <div class=\"config-loading\">\n <mj-loading text=\"Loading configuration...\" size=\"medium\"></mj-loading>\n </div>\n} @else {\n <div class=\"config-layout\">\n <!-- Left Navigation -->\n <nav class=\"config-nav\">\n <div class=\"config-nav-header\">\n <i class=\"fa-solid fa-cogs\"></i>\n <span>Configuration</span>\n </div>\n @for (section of Sections; track section.ID) {\n <button\n class=\"config-nav-item\"\n [class.config-nav-item-active]=\"ActiveSection === section.ID\"\n (click)=\"SelectSection(section.ID)\"\n >\n <i [class]=\"section.Icon\"></i>\n <span>{{ section.Label }}</span>\n </button>\n }\n </nav>\n\n <!-- Content Area -->\n <div class=\"config-content\">\n <!-- Pipeline Settings -->\n @if (ActiveSection === 'pipeline') {\n <div class=\"config-section\">\n <h2 class=\"config-section-title\">Pipeline Settings</h2>\n <p class=\"config-section-desc\">Configure how the Knowledge Pipeline processes incoming content.</p>\n\n <div class=\"config-group\">\n <label class=\"config-toggle-row\">\n <div class=\"config-toggle-info\">\n <span class=\"config-label\">Auto-tag on Ingest</span>\n <span class=\"config-hint\">Automatically run autotagging when new content is ingested</span>\n </div>\n <input type=\"checkbox\" [(ngModel)]=\"PipelineSettings.AutotagOnIngest\" (change)=\"OnSettingChanged()\" class=\"config-checkbox\" />\n </label>\n\n <label class=\"config-toggle-row\">\n <div class=\"config-toggle-info\">\n <span class=\"config-label\">Vectorize on Ingest</span>\n <span class=\"config-hint\">Automatically create embeddings for new content</span>\n </div>\n <input type=\"checkbox\" [(ngModel)]=\"PipelineSettings.VectorizeOnIngest\" (change)=\"OnSettingChanged()\" class=\"config-checkbox\" />\n </label>\n\n <div class=\"config-field-row\">\n <div class=\"config-field-info\">\n <span class=\"config-label\">Default Batch Size</span>\n <span class=\"config-hint\">Number of items processed per batch</span>\n </div>\n <input type=\"number\" [(ngModel)]=\"PipelineSettings.DefaultBatchSize\" (input)=\"OnSettingChanged()\" class=\"config-input config-input-number\" min=\"10\" max=\"1000\" />\n </div>\n\n <div class=\"config-field-row\">\n <div class=\"config-field-info\">\n <span class=\"config-label\">Max Concurrent Jobs</span>\n <span class=\"config-hint\">Maximum number of pipeline jobs running at once</span>\n </div>\n <input type=\"number\" [(ngModel)]=\"PipelineSettings.MaxConcurrentJobs\" (input)=\"OnSettingChanged()\" class=\"config-input config-input-number\" min=\"1\" max=\"10\" />\n </div>\n </div>\n </div>\n }\n\n <!-- Vector Database Settings -->\n @if (ActiveSection === 'vectordb') {\n <div class=\"config-section\">\n <h2 class=\"config-section-title\">Vector Database</h2>\n <p class=\"config-section-desc\">Manage the shared vector index and database connection.</p>\n\n <!-- Setup Progress -->\n <div class=\"setup-progress\">\n <div class=\"setup-progress-header\">\n <span class=\"setup-progress-label\">Setup Progress</span>\n <span class=\"setup-progress-count\">{{ SetupStepsCompleted }} of 3 complete</span>\n </div>\n <div class=\"setup-progress-bar\">\n <div class=\"setup-progress-fill\" [style.width.%]=\"(SetupStepsCompleted / 3) * 100\"></div>\n </div>\n </div>\n\n <!-- Step 1: Providers -->\n <div class=\"setup-step\" [class.setup-step-complete]=\"HasVectorDBProvider\" [class.setup-step-pending]=\"!HasVectorDBProvider\">\n <div class=\"setup-step-header\">\n <div class=\"setup-step-indicator\">\n @if (HasVectorDBProvider) {\n <i class=\"fa-solid fa-circle-check\"></i>\n } @else {\n <span class=\"setup-step-number\">1</span>\n }\n </div>\n <div class=\"setup-step-info\">\n <span class=\"setup-step-title\">Vector Database Providers</span>\n @if (HasVectorDBProvider) {\n <span class=\"setup-step-status\">{{ VectorDBProviders.length }} provider(s) registered</span>\n } @else {\n <span class=\"setup-step-status\">No providers registered. Add a vector database provider (e.g., Pinecone, Weaviate) via the admin console.</span>\n }\n </div>\n </div>\n @if (HasVectorDBProvider) {\n <div class=\"setup-step-detail\">\n @for (provider of VectorDBProviders; track provider.ID) {\n <div class=\"provider-card\">\n <div class=\"provider-icon\">\n <i class=\"fa-solid fa-database\"></i>\n </div>\n <div class=\"provider-info\">\n <span class=\"provider-name\">{{ provider.Name }}</span>\n <span class=\"provider-class\">{{ provider.ClassKey }}</span>\n </div>\n <span class=\"config-status-badge config-status-active\">\n <i class=\"fa-solid fa-circle-check\"></i> Active\n </span>\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Step 2: Embedding Model -->\n <div class=\"setup-step\" [class.setup-step-complete]=\"HasEmbeddingModel\" [class.setup-step-pending]=\"!HasEmbeddingModel\">\n <div class=\"setup-step-header\">\n <div class=\"setup-step-indicator\">\n @if (HasEmbeddingModel) {\n <i class=\"fa-solid fa-circle-check\"></i>\n } @else {\n <span class=\"setup-step-number\">2</span>\n }\n </div>\n <div class=\"setup-step-info\">\n <span class=\"setup-step-title\">Embedding Models</span>\n @if (HasEmbeddingModel) {\n <span class=\"setup-step-status\">{{ EmbeddingModels.length }} model(s) available</span>\n } @else {\n <span class=\"setup-step-status\">No embedding models found. Configure at least one in the AI app > Models tab.</span>\n }\n </div>\n </div>\n @if (HasEmbeddingModel) {\n <div class=\"setup-step-detail\">\n <div class=\"config-tag-list\">\n @for (model of EmbeddingModels; track model.ID) {\n <span class=\"config-tag\">{{ model.Name }}</span>\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Step 3: Vector Indexes -->\n <div class=\"setup-step\" [class.setup-step-complete]=\"HasVectorIndex\" [class.setup-step-pending]=\"!HasVectorIndex\">\n <div class=\"setup-step-header\">\n <div class=\"setup-step-indicator\">\n @if (HasVectorIndex) {\n <i class=\"fa-solid fa-circle-check\"></i>\n } @else {\n <span class=\"setup-step-number\">3</span>\n }\n </div>\n <div class=\"setup-step-info\">\n <span class=\"setup-step-title\">Vector Indexes</span>\n @if (HasVectorIndex) {\n <span class=\"setup-step-status\">{{ VectorIndexes.length }} index(es) configured</span>\n } @else if (HasVectorDBProvider && HasEmbeddingModel) {\n <span class=\"setup-step-status\">No indexes yet \u2014 create one below.</span>\n } @else {\n <span class=\"setup-step-status\">Complete steps 1 and 2 first.</span>\n }\n </div>\n @if (HasVectorDBProvider && HasEmbeddingModel && !ShowCreateIndexForm) {\n <button class=\"setup-step-action\" (click)=\"OpenCreateIndexForm()\">\n <i class=\"fa-solid fa-plus\"></i> Create Index\n </button>\n }\n </div>\n\n <!-- Existing Indexes -->\n @if (HasVectorIndex) {\n <div class=\"setup-step-detail\">\n @for (idx of VectorIndexes; track idx.ID) {\n <div class=\"index-card\">\n <div class=\"index-icon\">\n <i class=\"fa-solid fa-cubes\"></i>\n </div>\n <div class=\"index-info\">\n <span class=\"index-name\">{{ idx.Name }}</span>\n <span class=\"index-meta\">\n <i class=\"fa-solid fa-database\"></i> {{ idx.VectorDatabase }}\n &nbsp;\u00B7&nbsp;\n <i class=\"fa-solid fa-microchip\"></i> {{ idx.EmbeddingModel }}\n </span>\n </div>\n <div class=\"index-actions\">\n <span class=\"config-status-badge config-status-active\">\n <i class=\"fa-solid fa-circle-check\"></i> Active\n </span>\n <button class=\"index-delete-btn\" (click)=\"DeleteIndex(idx.ID)\" title=\"Delete index\">\n <i class=\"fa-solid fa-trash-can\"></i>\n </button>\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Create Index Form -->\n @if (ShowCreateIndexForm) {\n <div class=\"create-index-form\">\n <h4 class=\"create-index-title\">\n <i class=\"fa-solid fa-plus-circle\"></i> Create New Vector Index\n </h4>\n <div class=\"create-index-fields\">\n <div class=\"create-index-field\">\n <label class=\"create-index-label\">Index Name</label>\n <input type=\"text\"\n class=\"config-input\"\n [(ngModel)]=\"NewIndexName\"\n placeholder=\"e.g., mj-knowledge-index\" />\n </div>\n <div class=\"create-index-field\">\n <label class=\"create-index-label\">Vector Database</label>\n <select class=\"config-select\" [(ngModel)]=\"NewIndexVectorDBID\">\n @for (db of VectorDBProviders; track db.ID) {\n <option [value]=\"db.ID\">{{ db.Name }}</option>\n }\n </select>\n </div>\n <div class=\"create-index-field\">\n <label class=\"create-index-label\">Embedding Model</label>\n <select class=\"config-select\" [(ngModel)]=\"NewIndexEmbeddingModelID\">\n @for (model of EmbeddingModels; track model.ID) {\n <option [value]=\"model.ID\">{{ model.Name }}</option>\n }\n </select>\n </div>\n </div>\n <div class=\"create-index-actions\">\n <button class=\"create-index-submit\" (click)=\"CreateIndex()\" [disabled]=\"IsCreatingIndex\">\n @if (IsCreatingIndex) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Creating...\n } @else {\n <i class=\"fa-solid fa-plus\"></i> Create Index\n }\n </button>\n <button class=\"create-index-cancel\" (click)=\"CancelCreateIndex()\" [disabled]=\"IsCreatingIndex\">\n Cancel\n </button>\n </div>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Full-Text Indexes -->\n @if (ActiveSection === 'fulltext') {\n <div class=\"config-section\">\n <h2 class=\"config-section-title\">Full-Text Search Entities</h2>\n <p class=\"config-section-desc\">Configure which entities are included in full-text search. Entities with text fields (Name, Description, etc.) are automatically discovered.</p>\n\n @if (IsLoadingFTSEntities) {\n <mj-loading text=\"Discovering searchable entities...\" size=\"medium\"></mj-loading>\n } @else if (FTSEntities.length === 0) {\n <div class=\"config-empty-state\">\n <i class=\"fa-solid fa-text-width config-empty-icon\"></i>\n <h3 class=\"config-empty-title\">No Searchable Entities Found</h3>\n <p class=\"config-empty-text\">No entities with text fields were discovered. Ensure your database schema includes entities with varchar/nvarchar columns.</p>\n </div>\n } @else {\n <div class=\"fts-entity-controls\">\n <div class=\"fts-summary\">\n <span class=\"fts-summary-count\">{{ EnabledFTSCount }} of {{ FTSEntities.length }} entities enabled for search</span>\n <input type=\"text\" class=\"config-input fts-filter-input\" placeholder=\"Filter entities...\" [(ngModel)]=\"FTSFilterText\" />\n </div>\n </div>\n\n <div class=\"fts-entity-list\">\n @for (entity of FilteredFTSEntities; track entity.EntityName) {\n <div class=\"fts-entity-card\" [class.fts-entity-enabled]=\"entity.Enabled\">\n <div class=\"fts-entity-toggle\">\n <input type=\"checkbox\" [(ngModel)]=\"entity.Enabled\" (change)=\"OnFTSEntityToggled(entity)\" class=\"config-checkbox\" />\n </div>\n <div class=\"fts-entity-info\">\n <span class=\"fts-entity-name\">{{ entity.EntityName }}</span>\n <div class=\"fts-entity-fields\">\n @for (field of entity.IndexedFields; track field) {\n <span class=\"fts-field-tag\">{{ field }}</span>\n }\n </div>\n </div>\n <div class=\"fts-entity-meta\">\n <span class=\"fts-entity-title-field\" title=\"Title field\">\n <i class=\"fa-solid fa-heading\"></i> {{ entity.TitleField }}\n </span>\n @if (entity.SnippetField !== entity.TitleField) {\n <span class=\"fts-entity-snippet-field\" title=\"Snippet field\">\n <i class=\"fa-solid fa-align-left\"></i> {{ entity.SnippetField }}\n </span>\n }\n </div>\n </div>\n }\n </div>\n }\n </div>\n }\n\n <!-- Embedding Models -->\n @if (ActiveSection === 'embedding') {\n <div class=\"config-section\">\n <h2 class=\"config-section-title\">Embedding Models</h2>\n <p class=\"config-section-desc\">AI models used for generating vector embeddings from text.</p>\n\n @if (HasEmbeddingModel) {\n <div class=\"config-group\">\n <div class=\"config-field-row\">\n <div class=\"config-field-info\">\n <span class=\"config-label\">Active Model</span>\n <span class=\"config-hint\">Currently selected embedding model</span>\n </div>\n <span class=\"config-value-display\">{{ EmbeddingModelName }}</span>\n </div>\n <div class=\"config-field-row\">\n <div class=\"config-field-info\">\n <span class=\"config-label\">Available Models</span>\n <span class=\"config-hint\">{{ EmbeddingModels.length }} embedding model(s) configured</span>\n </div>\n <div class=\"config-tag-list\">\n @for (model of EmbeddingModels; track model.ID) {\n <span class=\"config-tag\">{{ model.Name }}</span>\n }\n </div>\n </div>\n </div>\n <p class=\"config-section-note\">\n <i class=\"fa-solid fa-info-circle\"></i>\n Manage embedding models in the AI Dashboard > Models tab.\n </p>\n } @else {\n <div class=\"config-empty-state\">\n <i class=\"fa-solid fa-microchip config-empty-icon\"></i>\n <h3 class=\"config-empty-title\">No Embedding Models Found</h3>\n <p class=\"config-empty-text\">\n Embedding models are required to convert text into vectors for semantic search and duplicate detection.\n Configure at least one embedding model (e.g., text-embedding-3-small) in the AI Dashboard > Models tab.\n </p>\n </div>\n }\n </div>\n }\n\n <!-- Thresholds -->\n @if (ActiveSection === 'thresholds') {\n <div class=\"config-section\">\n <h2 class=\"config-section-title\">Scoring Thresholds</h2>\n <p class=\"config-section-desc\">Set the scoring thresholds used by search, duplicate detection, and autotagging.</p>\n\n <div class=\"config-group\">\n <div class=\"config-field-row\">\n <div class=\"config-field-info\">\n <span class=\"config-label\">Duplicate Absolute Match</span>\n <span class=\"config-hint\">Score above which duplicates are auto-confirmed ({{ FormatThreshold(ThresholdSettings.DuplicateAbsolute) }})</span>\n </div>\n <input type=\"range\" [(ngModel)]=\"ThresholdSettings.DuplicateAbsolute\" (input)=\"OnSettingChanged()\" class=\"config-slider\" min=\"0.5\" max=\"1\" step=\"0.01\" />\n </div>\n\n <div class=\"config-field-row\">\n <div class=\"config-field-info\">\n <span class=\"config-label\">Duplicate Potential Match</span>\n <span class=\"config-hint\">Score above which duplicates are flagged for review ({{ FormatThreshold(ThresholdSettings.DuplicatePotential) }})</span>\n </div>\n <input type=\"range\" [(ngModel)]=\"ThresholdSettings.DuplicatePotential\" (input)=\"OnSettingChanged()\" class=\"config-slider\" min=\"0.3\" max=\"1\" step=\"0.01\" />\n </div>\n\n <div class=\"config-field-row\">\n <div class=\"config-field-info\">\n <span class=\"config-label\">Search Relevance</span>\n <span class=\"config-hint\">Minimum score for search results ({{ FormatThreshold(ThresholdSettings.SearchRelevance) }})</span>\n </div>\n <input type=\"range\" [(ngModel)]=\"ThresholdSettings.SearchRelevance\" (input)=\"OnSettingChanged()\" class=\"config-slider\" min=\"0\" max=\"1\" step=\"0.01\" />\n </div>\n\n <div class=\"config-field-row\">\n <div class=\"config-field-info\">\n <span class=\"config-label\">Autotag Confidence</span>\n <span class=\"config-hint\">Minimum confidence for accepting auto-generated tags ({{ FormatThreshold(ThresholdSettings.AutotagConfidence) }})</span>\n </div>\n <input type=\"range\" [(ngModel)]=\"ThresholdSettings.AutotagConfidence\" (input)=\"OnSettingChanged()\" class=\"config-slider\" min=\"0.3\" max=\"1\" step=\"0.01\" />\n </div>\n </div>\n </div>\n }\n\n <!-- Save Bar -->\n @if (HasUnsavedChanges) {\n <div class=\"config-save-bar\">\n <span class=\"config-save-text\">You have unsaved changes</span>\n <button class=\"config-save-btn\" (click)=\"SaveConfiguration()\" [disabled]=\"IsSaving\">\n @if (IsSaving) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Saving...\n } @else {\n <i class=\"fa-solid fa-save\"></i> Save Changes\n }\n </button>\n <button class=\"config-reset-btn\" (click)=\"ResetConfiguration()\" [disabled]=\"IsSaving\">\n Reset\n </button>\n </div>\n }\n </div>\n </div>\n}\n", styles: ["/* Knowledge Configuration - Settings Page with Left Nav */\n\n.config-loading {\n display: flex;\n justify-content: center;\n align-items: center;\n height: 400px;\n}\n\n.config-layout {\n display: flex;\n height: 100%;\n min-height: 500px;\n}\n\n/* Left Navigation */\n.config-nav {\n width: 240px;\n border-right: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n flex-shrink: 0;\n display: flex;\n flex-direction: column;\n padding: 0.5rem 0;\n}\n\n.config-nav-header {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.75rem 1rem;\n font-weight: 600;\n font-size: 0.9rem;\n color: var(--mj-text-primary);\n border-bottom: 1px solid var(--mj-border-subtle);\n margin-bottom: 0.5rem;\n}\n\n.config-nav-item {\n display: flex;\n align-items: center;\n gap: 0.6rem;\n padding: 0.55rem 1rem;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 0.85rem;\n cursor: pointer;\n text-align: left;\n transition: all 0.15s ease;\n width: 100%;\n}\n\n.config-nav-item:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n}\n\n.config-nav-item-active {\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-left: 3px solid var(--mj-brand-primary);\n}\n\n/* Content Area */\n.config-content {\n flex: 1;\n padding: 1.5rem 2rem;\n overflow-y: auto;\n position: relative;\n}\n\n.config-section {\n max-width: 700px;\n}\n\n.config-section-title {\n font-size: 1.3rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 0.5rem;\n}\n\n.config-section-desc {\n color: var(--mj-text-secondary);\n font-size: 0.9rem;\n margin-bottom: 1.5rem;\n line-height: 1.5;\n}\n\n/* Config Groups */\n.config-group {\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n}\n\n.config-toggle-row,\n.config-field-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0.75rem 1rem;\n border-radius: 8px;\n transition: background 0.1s ease;\n gap: 1rem;\n}\n\n.config-toggle-row:hover,\n.config-field-row:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.config-toggle-info,\n.config-field-info {\n display: flex;\n flex-direction: column;\n gap: 0.15rem;\n flex: 1;\n}\n\n.config-label {\n font-weight: 500;\n font-size: 0.9rem;\n color: var(--mj-text-primary);\n}\n\n.config-hint {\n font-size: 0.78rem;\n color: var(--mj-text-muted);\n}\n\n.config-checkbox {\n width: 1.1rem;\n height: 1.1rem;\n cursor: pointer;\n accent-color: var(--mj-brand-primary);\n}\n\n.config-input {\n padding: 0.4rem 0.6rem;\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: 0.85rem;\n font-family: inherit;\n}\n\n.config-input-number {\n width: 80px;\n text-align: center;\n}\n\n.config-input:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.config-slider {\n width: 200px;\n accent-color: var(--mj-brand-primary);\n cursor: pointer;\n}\n\n.config-value-display {\n font-size: 0.85rem;\n color: var(--mj-text-secondary);\n padding: 0.3rem 0.6rem;\n background: var(--mj-bg-surface-sunken);\n border-radius: 4px;\n font-family: monospace;\n}\n\n/* Placeholder */\n.config-placeholder {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 3rem 1.5rem;\n text-align: center;\n gap: 1rem;\n color: var(--mj-text-muted);\n}\n\n.config-placeholder-icon {\n font-size: 2.5rem;\n}\n\n/* ---- Setup Progress Bar ---- */\n\n.setup-progress {\n margin-bottom: 1.5rem;\n padding: 1rem 1.25rem;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 10px;\n}\n\n.setup-progress-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 0.5rem;\n}\n\n.setup-progress-label {\n font-size: 0.82rem;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.setup-progress-count {\n font-size: 0.78rem;\n color: var(--mj-text-muted);\n}\n\n.setup-progress-bar {\n height: 6px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 3px;\n overflow: hidden;\n}\n\n.setup-progress-fill {\n height: 100%;\n background: var(--mj-brand-primary);\n border-radius: 3px;\n transition: width 0.4s ease;\n}\n\n/* ---- Setup Steps ---- */\n\n.setup-step {\n padding: 1rem 1.25rem;\n border: 1px solid var(--mj-border-subtle);\n border-radius: 10px;\n margin-bottom: 0.75rem;\n transition: border-color 0.2s;\n}\n\n.setup-step-complete {\n border-color: var(--mj-status-success-border);\n background: color-mix(in srgb, var(--mj-status-success) 3%, var(--mj-bg-surface));\n}\n\n.setup-step-pending {\n border-color: var(--mj-border-default);\n background: var(--mj-bg-surface);\n}\n\n.setup-step-header {\n display: flex;\n align-items: flex-start;\n gap: 0.85rem;\n}\n\n.setup-step-indicator {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n flex-shrink: 0;\n margin-top: 1px;\n}\n\n.setup-step-complete .setup-step-indicator i {\n font-size: 1.25rem;\n color: var(--mj-status-success);\n}\n\n.setup-step-number {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n border-radius: 50%;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n font-size: 0.75rem;\n font-weight: 700;\n}\n\n.setup-step-info {\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n flex: 1;\n}\n\n.setup-step-title {\n font-size: 0.9rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.setup-step-status {\n font-size: 0.8rem;\n color: var(--mj-text-muted);\n line-height: 1.4;\n}\n\n.setup-step-complete .setup-step-status {\n color: var(--mj-status-success-text);\n}\n\n/* ---- Config Group Title ---- */\n\n.config-group-title {\n margin: 0 0 0.75rem 0;\n font-size: 0.85rem;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.04em;\n}\n\n/* ---- Status Badge ---- */\n\n.config-status-badge {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 10px;\n border-radius: 999px;\n font-size: 0.75rem;\n font-weight: 600;\n}\n\n.config-status-active {\n background: color-mix(in srgb, var(--mj-status-success) 12%, var(--mj-bg-surface));\n color: var(--mj-status-success-text);\n}\n\n/* ---- Step Detail Area ---- */\n\n.setup-step-detail {\n margin-top: 0.75rem;\n padding-left: 2.85rem;\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.setup-step-action {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 6px 14px;\n border: 1px solid var(--mj-brand-primary);\n border-radius: 6px;\n background: transparent;\n color: var(--mj-brand-primary);\n font-size: 0.78rem;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s;\n flex-shrink: 0;\n}\n\n.setup-step-action:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n/* ---- Provider Cards ---- */\n\n.provider-card {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1rem;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 8px;\n}\n\n.provider-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n border-radius: 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 1rem;\n flex-shrink: 0;\n}\n\n.provider-info {\n display: flex;\n flex-direction: column;\n flex: 1;\n min-width: 0;\n}\n\n.provider-name {\n font-size: 0.9rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.provider-class {\n font-size: 0.75rem;\n color: var(--mj-text-muted);\n font-family: monospace;\n}\n\n/* ---- Index Cards ---- */\n\n.index-card {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1rem;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 8px;\n transition: border-color 0.15s;\n}\n\n.index-card:hover {\n border-color: var(--mj-border-default);\n}\n\n.index-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n border-radius: 8px;\n background: color-mix(in srgb, var(--mj-status-info) 10%, var(--mj-bg-surface));\n color: var(--mj-status-info);\n font-size: 1rem;\n flex-shrink: 0;\n}\n\n.index-info {\n display: flex;\n flex-direction: column;\n flex: 1;\n min-width: 0;\n}\n\n.index-name {\n font-size: 0.9rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.index-meta {\n font-size: 0.75rem;\n color: var(--mj-text-muted);\n display: flex;\n align-items: center;\n gap: 3px;\n}\n\n.index-meta i {\n font-size: 0.65rem;\n}\n\n.index-actions {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n flex-shrink: 0;\n}\n\n.index-delete-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: transparent;\n color: var(--mj-text-muted);\n font-size: 0.75rem;\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.index-delete-btn:hover {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n border-color: var(--mj-status-error-border);\n color: var(--mj-status-error);\n}\n\n/* ---- Create Index Form ---- */\n\n.create-index-form {\n margin-top: 0.75rem;\n padding: 1.25rem;\n background: var(--mj-bg-surface-card);\n border: 2px solid var(--mj-brand-primary);\n border-radius: 10px;\n margin-left: 2.85rem;\n}\n\n.create-index-title {\n margin: 0 0 1rem 0;\n font-size: 0.9rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.create-index-title i {\n color: var(--mj-brand-primary);\n}\n\n.create-index-fields {\n display: flex;\n flex-direction: column;\n gap: 0.85rem;\n}\n\n.create-index-field {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.create-index-label {\n font-size: 0.78rem;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n.config-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: 0.85rem;\n}\n\n.config-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.create-index-actions {\n display: flex;\n gap: 8px;\n margin-top: 1rem;\n}\n\n.create-index-submit {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 18px;\n border: none;\n border-radius: 6px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 0.82rem;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.15s;\n}\n\n.create-index-submit:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n.create-index-submit:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.create-index-cancel {\n padding: 8px 18px;\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 font-weight: 500;\n cursor: pointer;\n}\n\n.create-index-cancel:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n/* Empty State for unconfigured sections */\n.config-empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 3rem 2rem;\n text-align: center;\n gap: 0.75rem;\n border: 2px dashed var(--mj-border-default);\n border-radius: 12px;\n background: var(--mj-bg-surface-sunken);\n}\n\n.config-empty-icon {\n font-size: 2.5rem;\n color: var(--mj-text-disabled);\n}\n\n.config-empty-title {\n margin: 0;\n font-size: 1rem;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.config-empty-text {\n margin: 0;\n font-size: 0.85rem;\n color: var(--mj-text-muted);\n max-width: 480px;\n line-height: 1.5;\n}\n\n/* Tag list for showing multiple models */\n.config-tag-list {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n}\n\n.config-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: 0.78rem;\n font-weight: 500;\n}\n\n/* Section note */\n.config-section-note {\n margin-top: 1rem;\n font-size: 0.8rem;\n color: var(--mj-text-muted);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.config-section-note i {\n color: var(--mj-status-info);\n}\n\n/* Save Bar */\n.config-save-bar {\n position: sticky;\n bottom: 0;\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1rem;\n margin-top: 2rem;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n}\n\n.config-save-text {\n flex: 1;\n color: var(--mj-text-secondary);\n font-size: 0.85rem;\n}\n\n.config-save-btn {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n padding: 0.5rem 1rem;\n border-radius: 6px;\n border: none;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 0.85rem;\n font-weight: 500;\n cursor: pointer;\n}\n\n.config-save-btn:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n.config-save-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.config-reset-btn {\n padding: 0.5rem 0.75rem;\n border-radius: 6px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 0.85rem;\n cursor: pointer;\n}\n\n.config-reset-btn:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover);\n}\n\n/* Mobile responsive */\n@media (max-width: 768px) {\n .config-layout {\n flex-direction: column;\n }\n\n .config-nav {\n width: 100%;\n flex-direction: row;\n overflow-x: auto;\n border-right: none;\n border-bottom: 1px solid var(--mj-border-default);\n padding: 0;\n }\n\n .config-nav-header {\n display: none;\n }\n\n .config-nav-item {\n white-space: nowrap;\n padding: 0.6rem 1rem;\n }\n\n .config-nav-item-active {\n border-left: none;\n border-bottom: 3px solid var(--mj-brand-primary);\n }\n\n .config-content {\n padding: 1rem;\n }\n}\n\n/* Full-Text Search Entity Management */\n.fts-entity-controls {\n margin-bottom: 16px;\n}\n\n.fts-summary {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n}\n\n.fts-summary-count {\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n\n.fts-filter-input {\n max-width: 240px;\n}\n\n.fts-entity-list {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.fts-entity-card {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 14px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n transition: border-color 0.15s, background 0.15s;\n}\n\n.fts-entity-card:hover {\n border-color: var(--mj-border-strong);\n}\n\n.fts-entity-card.fts-entity-enabled {\n border-color: color-mix(in srgb, var(--mj-brand-primary) 30%, var(--mj-border-default));\n background: color-mix(in srgb, var(--mj-brand-primary) 3%, var(--mj-bg-surface));\n}\n\n.fts-entity-toggle {\n flex-shrink: 0;\n}\n\n.fts-entity-info {\n flex: 1;\n min-width: 0;\n}\n\n.fts-entity-name {\n display: block;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin-bottom: 4px;\n}\n\n.fts-entity-fields {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n}\n\n.fts-field-tag {\n display: inline-block;\n padding: 1px 6px;\n font-size: 11px;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-sunken);\n border-radius: 4px;\n}\n\n.fts-entity-meta {\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n gap: 2px;\n flex-shrink: 0;\n}\n\n.fts-entity-title-field,\n.fts-entity-snippet-field {\n font-size: 11px;\n color: var(--mj-text-muted);\n white-space: nowrap;\n}\n\n.fts-entity-title-field i,\n.fts-entity-snippet-field i {\n margin-right: 4px;\n font-size: 10px;\n}\n"] }]
1102
+ args: [{ standalone: false, selector: 'app-knowledge-config-resource', template: "@if (IsLoading) {\n <div class=\"config-loading\">\n <mj-loading text=\"Loading configuration...\" size=\"medium\"></mj-loading>\n </div>\n} @else {\n <div class=\"config-layout\">\n <!-- Left Navigation -->\n <nav class=\"config-nav\">\n <div class=\"config-nav-header\">\n <i class=\"fa-solid fa-cogs\"></i>\n <span>Configuration</span>\n </div>\n @for (section of Sections; track section.ID) {\n <button\n class=\"config-nav-item\"\n [class.config-nav-item-active]=\"ActiveSection === section.ID\"\n (click)=\"SelectSection(section.ID)\"\n >\n <i [class]=\"section.Icon\"></i>\n <span>{{ section.Label }}</span>\n </button>\n }\n </nav>\n\n <!-- Content Area -->\n <div class=\"config-content\">\n <!-- Pipeline Settings -->\n @if (ActiveSection === 'pipeline') {\n <div class=\"config-section\">\n <h2 class=\"config-section-title\">Pipeline Settings</h2>\n <p class=\"config-section-desc\">Configure how the Knowledge Pipeline processes incoming content.</p>\n\n <div class=\"config-group\">\n <label class=\"config-toggle-row\">\n <div class=\"config-toggle-info\">\n <span class=\"config-label\">Auto-tag on Ingest</span>\n <span class=\"config-hint\">Automatically run autotagging when new content is ingested</span>\n </div>\n <input type=\"checkbox\" [(ngModel)]=\"PipelineSettings.AutotagOnIngest\" (change)=\"OnSettingChanged()\" class=\"config-checkbox\" />\n </label>\n\n <label class=\"config-toggle-row\">\n <div class=\"config-toggle-info\">\n <span class=\"config-label\">Vectorize on Ingest</span>\n <span class=\"config-hint\">Automatically create embeddings for new content</span>\n </div>\n <input type=\"checkbox\" [(ngModel)]=\"PipelineSettings.VectorizeOnIngest\" (change)=\"OnSettingChanged()\" class=\"config-checkbox\" />\n </label>\n\n <div class=\"config-field-row\">\n <div class=\"config-field-info\">\n <span class=\"config-label\">Default Batch Size</span>\n <span class=\"config-hint\">Number of items processed per batch</span>\n </div>\n <input type=\"number\" [(ngModel)]=\"PipelineSettings.DefaultBatchSize\" (input)=\"OnSettingChanged()\" class=\"config-input config-input-number\" min=\"10\" max=\"1000\" />\n </div>\n\n <div class=\"config-field-row\">\n <div class=\"config-field-info\">\n <span class=\"config-label\">Max Concurrent Jobs</span>\n <span class=\"config-hint\">Maximum number of pipeline jobs running at once</span>\n </div>\n <input type=\"number\" [(ngModel)]=\"PipelineSettings.MaxConcurrentJobs\" (input)=\"OnSettingChanged()\" class=\"config-input config-input-number\" min=\"1\" max=\"10\" />\n </div>\n </div>\n </div>\n }\n\n <!-- Vector Database Settings -->\n @if (ActiveSection === 'vectordb') {\n <div class=\"config-section\">\n <h2 class=\"config-section-title\">Vector Database</h2>\n <p class=\"config-section-desc\">Manage the shared vector index and database connection.</p>\n\n <!-- Setup Progress -->\n <div class=\"setup-progress\">\n <div class=\"setup-progress-header\">\n <span class=\"setup-progress-label\">Setup Progress</span>\n <span class=\"setup-progress-count\">{{ SetupStepsCompleted }} of 3 complete</span>\n </div>\n <div class=\"setup-progress-bar\">\n <div class=\"setup-progress-fill\" [style.width.%]=\"(SetupStepsCompleted / 3) * 100\"></div>\n </div>\n </div>\n\n <!-- Step 1: Providers -->\n <div class=\"setup-step\" [class.setup-step-complete]=\"HasVectorDBProvider\" [class.setup-step-pending]=\"!HasVectorDBProvider\">\n <div class=\"setup-step-header\">\n <div class=\"setup-step-indicator\">\n @if (HasVectorDBProvider) {\n <i class=\"fa-solid fa-circle-check\"></i>\n } @else {\n <span class=\"setup-step-number\">1</span>\n }\n </div>\n <div class=\"setup-step-info\">\n <span class=\"setup-step-title\">Vector Database Providers</span>\n @if (HasVectorDBProvider) {\n <span class=\"setup-step-status\">{{ VectorDBProviders.length }} provider(s) registered</span>\n } @else {\n <span class=\"setup-step-status\">No providers registered. Add a vector database provider (e.g., Pinecone, Weaviate) via the admin console.</span>\n }\n </div>\n </div>\n @if (HasVectorDBProvider) {\n <div class=\"setup-step-detail\">\n @for (provider of VectorDBProviders; track provider.ID) {\n <div class=\"provider-card\">\n <div class=\"provider-icon\">\n <i class=\"fa-solid fa-database\"></i>\n </div>\n <div class=\"provider-info\">\n <span class=\"provider-name\">{{ provider.Name }}</span>\n <span class=\"provider-class\">{{ provider.ClassKey }}</span>\n </div>\n <span class=\"config-status-badge config-status-active\">\n <i class=\"fa-solid fa-circle-check\"></i> Active\n </span>\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Step 2: Embedding Model -->\n <div class=\"setup-step\" [class.setup-step-complete]=\"HasEmbeddingModel\" [class.setup-step-pending]=\"!HasEmbeddingModel\">\n <div class=\"setup-step-header\">\n <div class=\"setup-step-indicator\">\n @if (HasEmbeddingModel) {\n <i class=\"fa-solid fa-circle-check\"></i>\n } @else {\n <span class=\"setup-step-number\">2</span>\n }\n </div>\n <div class=\"setup-step-info\">\n <span class=\"setup-step-title\">Embedding Models</span>\n @if (HasEmbeddingModel) {\n <span class=\"setup-step-status\">{{ EmbeddingModels.length }} model(s) available</span>\n } @else {\n <span class=\"setup-step-status\">No embedding models found. Configure at least one in the AI app > Models tab.</span>\n }\n </div>\n </div>\n @if (HasEmbeddingModel) {\n <div class=\"setup-step-detail\">\n <div class=\"config-tag-list\">\n @for (model of EmbeddingModels; track model.ID) {\n <span class=\"config-tag\">{{ model.Name }}</span>\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Step 3: Vector Indexes -->\n <div class=\"setup-step\" [class.setup-step-complete]=\"HasVectorIndex\" [class.setup-step-pending]=\"!HasVectorIndex\">\n <div class=\"setup-step-header\">\n <div class=\"setup-step-indicator\">\n @if (HasVectorIndex) {\n <i class=\"fa-solid fa-circle-check\"></i>\n } @else {\n <span class=\"setup-step-number\">3</span>\n }\n </div>\n <div class=\"setup-step-info\">\n <span class=\"setup-step-title\">Vector Indexes</span>\n @if (HasVectorIndex) {\n <span class=\"setup-step-status\">{{ VectorIndexes.length }} index(es) configured</span>\n } @else if (HasVectorDBProvider && HasEmbeddingModel) {\n <span class=\"setup-step-status\">No indexes yet \u2014 create one below.</span>\n } @else {\n <span class=\"setup-step-status\">Complete steps 1 and 2 first.</span>\n }\n </div>\n @if (HasVectorDBProvider && HasEmbeddingModel && !ShowCreateIndexForm) {\n <button class=\"setup-step-action\" (click)=\"OpenCreateIndexForm()\">\n <i class=\"fa-solid fa-plus\"></i> Create Index\n </button>\n }\n </div>\n\n <!-- Existing Indexes -->\n @if (HasVectorIndex) {\n <div class=\"setup-step-detail\">\n @for (idx of VectorIndexes; track idx.ID) {\n <div class=\"index-card\">\n <div class=\"index-icon\">\n <i class=\"fa-solid fa-cubes\"></i>\n </div>\n <div class=\"index-info\">\n <span class=\"index-name\">{{ idx.Name }}</span>\n <span class=\"index-meta\">\n <i class=\"fa-solid fa-database\"></i> {{ idx.VectorDatabase }}\n &nbsp;\u00B7&nbsp;\n <i class=\"fa-solid fa-microchip\"></i> {{ idx.EmbeddingModel }}\n </span>\n </div>\n <div class=\"index-actions\">\n <span class=\"config-status-badge config-status-active\">\n <i class=\"fa-solid fa-circle-check\"></i> Active\n </span>\n <button class=\"index-delete-btn\" (click)=\"DeleteIndex(idx.ID)\" title=\"Delete index\">\n <i class=\"fa-solid fa-trash-can\"></i>\n </button>\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Create Index Form -->\n @if (ShowCreateIndexForm) {\n <div class=\"create-index-form\">\n <h4 class=\"create-index-title\">\n <i class=\"fa-solid fa-plus-circle\"></i> Create New Vector Index\n </h4>\n <div class=\"create-index-fields\">\n <div class=\"create-index-field\">\n <label class=\"create-index-label\">Index Name</label>\n <input type=\"text\"\n class=\"config-input\"\n [(ngModel)]=\"NewIndexName\"\n placeholder=\"e.g., mj-knowledge-index\" />\n </div>\n <div class=\"create-index-field\">\n <label class=\"create-index-label\">Vector Database</label>\n <select class=\"config-select\" [(ngModel)]=\"NewIndexVectorDBID\">\n @for (db of VectorDBProviders; track db.ID) {\n <option [value]=\"db.ID\">{{ db.Name }}</option>\n }\n </select>\n </div>\n <div class=\"create-index-field\">\n <label class=\"create-index-label\">Embedding Model</label>\n <select class=\"config-select\" [(ngModel)]=\"NewIndexEmbeddingModelID\">\n @for (model of EmbeddingModels; track model.ID) {\n <option [value]=\"model.ID\">{{ model.Name }}</option>\n }\n </select>\n </div>\n </div>\n <div class=\"create-index-actions\">\n <button class=\"create-index-submit\" (click)=\"CreateIndex()\" [disabled]=\"IsCreatingIndex\">\n @if (IsCreatingIndex) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Creating...\n } @else {\n <i class=\"fa-solid fa-plus\"></i> Create Index\n }\n </button>\n <button class=\"create-index-cancel\" (click)=\"CancelCreateIndex()\" [disabled]=\"IsCreatingIndex\">\n Cancel\n </button>\n </div>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Full-Text Indexes -->\n @if (ActiveSection === 'fulltext') {\n <div class=\"config-section\">\n <h2 class=\"config-section-title\">Full-Text Search Entities</h2>\n <p class=\"config-section-desc\">Configure which entities are included in full-text search. Entities with text fields (Name, Description, etc.) are automatically discovered.</p>\n\n @if (IsLoadingFTSEntities) {\n <mj-loading text=\"Discovering searchable entities...\" size=\"medium\"></mj-loading>\n } @else if (FTSEntities.length === 0) {\n <div class=\"config-empty-state\">\n <i class=\"fa-solid fa-text-width config-empty-icon\"></i>\n <h3 class=\"config-empty-title\">No Searchable Entities Found</h3>\n <p class=\"config-empty-text\">No entities with text fields were discovered. Ensure your database schema includes entities with varchar/nvarchar columns.</p>\n </div>\n } @else {\n <div class=\"fts-entity-controls\">\n <div class=\"fts-summary\">\n <span class=\"fts-summary-count\">{{ EnabledFTSCount }} of {{ FTSEntities.length }} entities enabled for search</span>\n <input type=\"text\" class=\"config-input fts-filter-input\" placeholder=\"Filter entities...\" [(ngModel)]=\"FTSFilterText\" />\n </div>\n </div>\n\n <div class=\"fts-entity-list\">\n @for (entity of FilteredFTSEntities; track entity.EntityName) {\n <div class=\"fts-entity-card\" [class.fts-entity-enabled]=\"entity.Enabled\">\n <div class=\"fts-entity-toggle\">\n <input type=\"checkbox\" [(ngModel)]=\"entity.Enabled\" (change)=\"OnFTSEntityToggled(entity)\" class=\"config-checkbox\" />\n </div>\n <div class=\"fts-entity-info\">\n <span class=\"fts-entity-name\">{{ entity.EntityName }}</span>\n <div class=\"fts-entity-fields\">\n @for (field of entity.IndexedFields; track field) {\n <span class=\"fts-field-tag\">{{ field }}</span>\n }\n </div>\n </div>\n <div class=\"fts-entity-meta\">\n <span class=\"fts-entity-title-field\" title=\"Title field\">\n <i class=\"fa-solid fa-heading\"></i> {{ entity.TitleField }}\n </span>\n @if (entity.SnippetField !== entity.TitleField) {\n <span class=\"fts-entity-snippet-field\" title=\"Snippet field\">\n <i class=\"fa-solid fa-align-left\"></i> {{ entity.SnippetField }}\n </span>\n }\n </div>\n </div>\n }\n </div>\n }\n </div>\n }\n\n <!-- Embedding Models -->\n @if (ActiveSection === 'embedding') {\n <div class=\"config-section\">\n <h2 class=\"config-section-title\">Embedding Models</h2>\n <p class=\"config-section-desc\">AI models used for generating vector embeddings from text.</p>\n\n @if (HasEmbeddingModel) {\n <div class=\"config-group\">\n <div class=\"config-field-row\">\n <div class=\"config-field-info\">\n <span class=\"config-label\">Active Model</span>\n <span class=\"config-hint\">Currently selected embedding model</span>\n </div>\n <span class=\"config-value-display\">{{ EmbeddingModelName }}</span>\n </div>\n <div class=\"config-field-row\">\n <div class=\"config-field-info\">\n <span class=\"config-label\">Available Models</span>\n <span class=\"config-hint\">{{ EmbeddingModels.length }} embedding model(s) configured</span>\n </div>\n <div class=\"config-tag-list\">\n @for (model of EmbeddingModels; track model.ID) {\n <span class=\"config-tag\">{{ model.Name }}</span>\n }\n </div>\n </div>\n </div>\n <p class=\"config-section-note\">\n <i class=\"fa-solid fa-info-circle\"></i>\n Manage embedding models in the AI Dashboard > Models tab.\n </p>\n } @else {\n <div class=\"config-empty-state\">\n <i class=\"fa-solid fa-microchip config-empty-icon\"></i>\n <h3 class=\"config-empty-title\">No Embedding Models Found</h3>\n <p class=\"config-empty-text\">\n Embedding models are required to convert text into vectors for semantic search and duplicate detection.\n Configure at least one embedding model (e.g., text-embedding-3-small) in the AI Dashboard > Models tab.\n </p>\n </div>\n }\n </div>\n }\n\n <!-- Thresholds -->\n @if (ActiveSection === 'thresholds') {\n <div class=\"config-section\">\n <h2 class=\"config-section-title\">Scoring Thresholds</h2>\n <p class=\"config-section-desc\">Set the scoring thresholds used by search, duplicate detection, and autotagging.</p>\n\n <div class=\"config-group\">\n <div class=\"config-field-row\">\n <div class=\"config-field-info\">\n <span class=\"config-label\">Duplicate Absolute Match</span>\n <span class=\"config-hint\">Score above which duplicates are auto-confirmed ({{ FormatThreshold(ThresholdSettings.DuplicateAbsolute) }})</span>\n </div>\n <input type=\"range\" [(ngModel)]=\"ThresholdSettings.DuplicateAbsolute\" (input)=\"OnSettingChanged()\" class=\"config-slider\" min=\"0.5\" max=\"1\" step=\"0.01\" />\n </div>\n\n <div class=\"config-field-row\">\n <div class=\"config-field-info\">\n <span class=\"config-label\">Duplicate Potential Match</span>\n <span class=\"config-hint\">Score above which duplicates are flagged for review ({{ FormatThreshold(ThresholdSettings.DuplicatePotential) }})</span>\n </div>\n <input type=\"range\" [(ngModel)]=\"ThresholdSettings.DuplicatePotential\" (input)=\"OnSettingChanged()\" class=\"config-slider\" min=\"0.3\" max=\"1\" step=\"0.01\" />\n </div>\n\n <div class=\"config-field-row\">\n <div class=\"config-field-info\">\n <span class=\"config-label\">Search Relevance</span>\n <span class=\"config-hint\">Minimum score for search results ({{ FormatThreshold(ThresholdSettings.SearchRelevance) }})</span>\n </div>\n <input type=\"range\" [(ngModel)]=\"ThresholdSettings.SearchRelevance\" (input)=\"OnSettingChanged()\" class=\"config-slider\" min=\"0\" max=\"1\" step=\"0.01\" />\n </div>\n\n <div class=\"config-field-row\">\n <div class=\"config-field-info\">\n <span class=\"config-label\">Autotag Confidence</span>\n <span class=\"config-hint\">Minimum confidence for accepting auto-generated tags ({{ FormatThreshold(ThresholdSettings.AutotagConfidence) }})</span>\n </div>\n <input type=\"range\" [(ngModel)]=\"ThresholdSettings.AutotagConfidence\" (input)=\"OnSettingChanged()\" class=\"config-slider\" min=\"0.3\" max=\"1\" step=\"0.01\" />\n </div>\n </div>\n </div>\n }\n\n <!-- Scheduling Section -->\n @if (ActiveSection === 'scheduling') {\n <div class=\"config-section-content\">\n <h2 class=\"config-section-title\"><i class=\"fa-solid fa-clock\"></i> Scheduling</h2>\n <p class=\"config-section-desc\">Manage automated pipeline schedules for content classification and vector sync. Create schedules here or manage all schedules in the dedicated Scheduling app.</p>\n <div style=\"margin-top: 16px;\">\n <app-scheduling-resource></app-scheduling-resource>\n </div>\n </div>\n }\n\n <!-- Save Bar -->\n @if (HasUnsavedChanges) {\n <div class=\"config-save-bar\">\n <span class=\"config-save-text\">You have unsaved changes</span>\n <button class=\"config-save-btn\" (click)=\"SaveConfiguration()\" [disabled]=\"IsSaving\">\n @if (IsSaving) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Saving...\n } @else {\n <i class=\"fa-solid fa-save\"></i> Save Changes\n }\n </button>\n <button class=\"config-reset-btn\" (click)=\"ResetConfiguration()\" [disabled]=\"IsSaving\">\n Reset\n </button>\n </div>\n }\n </div>\n </div>\n}\n", styles: ["/* Knowledge Configuration - Settings Page with Left Nav */\n\n.config-loading {\n display: flex;\n justify-content: center;\n align-items: center;\n height: 400px;\n}\n\n.config-layout {\n display: flex;\n height: 100%;\n min-height: 500px;\n}\n\n/* Left Navigation */\n.config-nav {\n width: 240px;\n border-right: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n flex-shrink: 0;\n display: flex;\n flex-direction: column;\n padding: 0.5rem 0;\n}\n\n.config-nav-header {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.75rem 1rem;\n font-weight: 600;\n font-size: 0.9rem;\n color: var(--mj-text-primary);\n border-bottom: 1px solid var(--mj-border-subtle);\n margin-bottom: 0.5rem;\n}\n\n.config-nav-item {\n display: flex;\n align-items: center;\n gap: 0.6rem;\n padding: 0.55rem 1rem;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 0.85rem;\n cursor: pointer;\n text-align: left;\n transition: all 0.15s ease;\n width: 100%;\n}\n\n.config-nav-item:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n}\n\n.config-nav-item-active {\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-left: 3px solid var(--mj-brand-primary);\n}\n\n/* Content Area */\n.config-content {\n flex: 1;\n padding: 1.5rem 2rem;\n overflow-y: auto;\n position: relative;\n}\n\n.config-section {\n max-width: 700px;\n}\n\n.config-section-title {\n font-size: 1.3rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 0.5rem;\n}\n\n.config-section-desc {\n color: var(--mj-text-secondary);\n font-size: 0.9rem;\n margin-bottom: 1.5rem;\n line-height: 1.5;\n}\n\n/* Config Groups */\n.config-group {\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n}\n\n.config-toggle-row,\n.config-field-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0.75rem 1rem;\n border-radius: 8px;\n transition: background 0.1s ease;\n gap: 1rem;\n}\n\n.config-toggle-row:hover,\n.config-field-row:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.config-toggle-info,\n.config-field-info {\n display: flex;\n flex-direction: column;\n gap: 0.15rem;\n flex: 1;\n}\n\n.config-label {\n font-weight: 500;\n font-size: 0.9rem;\n color: var(--mj-text-primary);\n}\n\n.config-hint {\n font-size: 0.78rem;\n color: var(--mj-text-muted);\n}\n\n.config-checkbox {\n width: 1.1rem;\n height: 1.1rem;\n cursor: pointer;\n accent-color: var(--mj-brand-primary);\n}\n\n.config-input {\n padding: 0.4rem 0.6rem;\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: 0.85rem;\n font-family: inherit;\n}\n\n.config-input-number {\n width: 80px;\n text-align: center;\n}\n\n.config-input:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.config-slider {\n width: 200px;\n accent-color: var(--mj-brand-primary);\n cursor: pointer;\n}\n\n.config-value-display {\n font-size: 0.85rem;\n color: var(--mj-text-secondary);\n padding: 0.3rem 0.6rem;\n background: var(--mj-bg-surface-sunken);\n border-radius: 4px;\n font-family: monospace;\n}\n\n/* Placeholder */\n.config-placeholder {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 3rem 1.5rem;\n text-align: center;\n gap: 1rem;\n color: var(--mj-text-muted);\n}\n\n.config-placeholder-icon {\n font-size: 2.5rem;\n}\n\n/* ---- Setup Progress Bar ---- */\n\n.setup-progress {\n margin-bottom: 1.5rem;\n padding: 1rem 1.25rem;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 10px;\n}\n\n.setup-progress-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 0.5rem;\n}\n\n.setup-progress-label {\n font-size: 0.82rem;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.setup-progress-count {\n font-size: 0.78rem;\n color: var(--mj-text-muted);\n}\n\n.setup-progress-bar {\n height: 6px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 3px;\n overflow: hidden;\n}\n\n.setup-progress-fill {\n height: 100%;\n background: var(--mj-brand-primary);\n border-radius: 3px;\n transition: width 0.4s ease;\n}\n\n/* ---- Setup Steps ---- */\n\n.setup-step {\n padding: 1rem 1.25rem;\n border: 1px solid var(--mj-border-subtle);\n border-radius: 10px;\n margin-bottom: 0.75rem;\n transition: border-color 0.2s;\n}\n\n.setup-step-complete {\n border-color: var(--mj-status-success-border);\n background: color-mix(in srgb, var(--mj-status-success) 3%, var(--mj-bg-surface));\n}\n\n.setup-step-pending {\n border-color: var(--mj-border-default);\n background: var(--mj-bg-surface);\n}\n\n.setup-step-header {\n display: flex;\n align-items: flex-start;\n gap: 0.85rem;\n}\n\n.setup-step-indicator {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n flex-shrink: 0;\n margin-top: 1px;\n}\n\n.setup-step-complete .setup-step-indicator i {\n font-size: 1.25rem;\n color: var(--mj-status-success);\n}\n\n.setup-step-number {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n border-radius: 50%;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n font-size: 0.75rem;\n font-weight: 700;\n}\n\n.setup-step-info {\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n flex: 1;\n}\n\n.setup-step-title {\n font-size: 0.9rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.setup-step-status {\n font-size: 0.8rem;\n color: var(--mj-text-muted);\n line-height: 1.4;\n}\n\n.setup-step-complete .setup-step-status {\n color: var(--mj-status-success-text);\n}\n\n/* ---- Config Group Title ---- */\n\n.config-group-title {\n margin: 0 0 0.75rem 0;\n font-size: 0.85rem;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.04em;\n}\n\n/* ---- Status Badge ---- */\n\n.config-status-badge {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 4px 10px;\n border-radius: 999px;\n font-size: 0.75rem;\n font-weight: 600;\n}\n\n.config-status-active {\n background: color-mix(in srgb, var(--mj-status-success) 12%, var(--mj-bg-surface));\n color: var(--mj-status-success-text);\n}\n\n/* ---- Step Detail Area ---- */\n\n.setup-step-detail {\n margin-top: 0.75rem;\n padding-left: 2.85rem;\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.setup-step-action {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 6px 14px;\n border: 1px solid var(--mj-brand-primary);\n border-radius: 6px;\n background: transparent;\n color: var(--mj-brand-primary);\n font-size: 0.78rem;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.15s;\n flex-shrink: 0;\n}\n\n.setup-step-action:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n/* ---- Provider Cards ---- */\n\n.provider-card {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1rem;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 8px;\n}\n\n.provider-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n border-radius: 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 1rem;\n flex-shrink: 0;\n}\n\n.provider-info {\n display: flex;\n flex-direction: column;\n flex: 1;\n min-width: 0;\n}\n\n.provider-name {\n font-size: 0.9rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.provider-class {\n font-size: 0.75rem;\n color: var(--mj-text-muted);\n font-family: monospace;\n}\n\n/* ---- Index Cards ---- */\n\n.index-card {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1rem;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 8px;\n transition: border-color 0.15s;\n}\n\n.index-card:hover {\n border-color: var(--mj-border-default);\n}\n\n.index-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n border-radius: 8px;\n background: color-mix(in srgb, var(--mj-status-info) 10%, var(--mj-bg-surface));\n color: var(--mj-status-info);\n font-size: 1rem;\n flex-shrink: 0;\n}\n\n.index-info {\n display: flex;\n flex-direction: column;\n flex: 1;\n min-width: 0;\n}\n\n.index-name {\n font-size: 0.9rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.index-meta {\n font-size: 0.75rem;\n color: var(--mj-text-muted);\n display: flex;\n align-items: center;\n gap: 3px;\n}\n\n.index-meta i {\n font-size: 0.65rem;\n}\n\n.index-actions {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n flex-shrink: 0;\n}\n\n.index-delete-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: transparent;\n color: var(--mj-text-muted);\n font-size: 0.75rem;\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.index-delete-btn:hover {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n border-color: var(--mj-status-error-border);\n color: var(--mj-status-error);\n}\n\n/* ---- Create Index Form ---- */\n\n.create-index-form {\n margin-top: 0.75rem;\n padding: 1.25rem;\n background: var(--mj-bg-surface-card);\n border: 2px solid var(--mj-brand-primary);\n border-radius: 10px;\n margin-left: 2.85rem;\n}\n\n.create-index-title {\n margin: 0 0 1rem 0;\n font-size: 0.9rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.create-index-title i {\n color: var(--mj-brand-primary);\n}\n\n.create-index-fields {\n display: flex;\n flex-direction: column;\n gap: 0.85rem;\n}\n\n.create-index-field {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.create-index-label {\n font-size: 0.78rem;\n font-weight: 500;\n color: var(--mj-text-secondary);\n}\n\n.config-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: 0.85rem;\n}\n\n.config-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.create-index-actions {\n display: flex;\n gap: 8px;\n margin-top: 1rem;\n}\n\n.create-index-submit {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 18px;\n border: none;\n border-radius: 6px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 0.82rem;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.15s;\n}\n\n.create-index-submit:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n.create-index-submit:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.create-index-cancel {\n padding: 8px 18px;\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 font-weight: 500;\n cursor: pointer;\n}\n\n.create-index-cancel:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n/* Empty State for unconfigured sections */\n.config-empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 3rem 2rem;\n text-align: center;\n gap: 0.75rem;\n border: 2px dashed var(--mj-border-default);\n border-radius: 12px;\n background: var(--mj-bg-surface-sunken);\n}\n\n.config-empty-icon {\n font-size: 2.5rem;\n color: var(--mj-text-disabled);\n}\n\n.config-empty-title {\n margin: 0;\n font-size: 1rem;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.config-empty-text {\n margin: 0;\n font-size: 0.85rem;\n color: var(--mj-text-muted);\n max-width: 480px;\n line-height: 1.5;\n}\n\n/* Tag list for showing multiple models */\n.config-tag-list {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n}\n\n.config-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: 0.78rem;\n font-weight: 500;\n}\n\n/* Section note */\n.config-section-note {\n margin-top: 1rem;\n font-size: 0.8rem;\n color: var(--mj-text-muted);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.config-section-note i {\n color: var(--mj-status-info);\n}\n\n/* Save Bar */\n.config-save-bar {\n position: sticky;\n bottom: 0;\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1rem;\n margin-top: 2rem;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n}\n\n.config-save-text {\n flex: 1;\n color: var(--mj-text-secondary);\n font-size: 0.85rem;\n}\n\n.config-save-btn {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n padding: 0.5rem 1rem;\n border-radius: 6px;\n border: none;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 0.85rem;\n font-weight: 500;\n cursor: pointer;\n}\n\n.config-save-btn:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n.config-save-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.config-reset-btn {\n padding: 0.5rem 0.75rem;\n border-radius: 6px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 0.85rem;\n cursor: pointer;\n}\n\n.config-reset-btn:hover:not(:disabled) {\n background: var(--mj-bg-surface-hover);\n}\n\n/* Mobile responsive */\n@media (max-width: 768px) {\n .config-layout {\n flex-direction: column;\n }\n\n .config-nav {\n width: 100%;\n flex-direction: row;\n overflow-x: auto;\n border-right: none;\n border-bottom: 1px solid var(--mj-border-default);\n padding: 0;\n }\n\n .config-nav-header {\n display: none;\n }\n\n .config-nav-item {\n white-space: nowrap;\n padding: 0.6rem 1rem;\n }\n\n .config-nav-item-active {\n border-left: none;\n border-bottom: 3px solid var(--mj-brand-primary);\n }\n\n .config-content {\n padding: 1rem;\n }\n}\n\n/* Full-Text Search Entity Management */\n.fts-entity-controls {\n margin-bottom: 16px;\n}\n\n.fts-summary {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n}\n\n.fts-summary-count {\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n\n.fts-filter-input {\n max-width: 240px;\n}\n\n.fts-entity-list {\n display: flex;\n flex-direction: column;\n gap: 6px;\n}\n\n.fts-entity-card {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 14px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n transition: border-color 0.15s, background 0.15s;\n}\n\n.fts-entity-card:hover {\n border-color: var(--mj-border-strong);\n}\n\n.fts-entity-card.fts-entity-enabled {\n border-color: color-mix(in srgb, var(--mj-brand-primary) 30%, var(--mj-border-default));\n background: color-mix(in srgb, var(--mj-brand-primary) 3%, var(--mj-bg-surface));\n}\n\n.fts-entity-toggle {\n flex-shrink: 0;\n}\n\n.fts-entity-info {\n flex: 1;\n min-width: 0;\n}\n\n.fts-entity-name {\n display: block;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin-bottom: 4px;\n}\n\n.fts-entity-fields {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n}\n\n.fts-field-tag {\n display: inline-block;\n padding: 1px 6px;\n font-size: 11px;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface-sunken);\n border-radius: 4px;\n}\n\n.fts-entity-meta {\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n gap: 2px;\n flex-shrink: 0;\n}\n\n.fts-entity-title-field,\n.fts-entity-snippet-field {\n font-size: 11px;\n color: var(--mj-text-muted);\n white-space: nowrap;\n}\n\n.fts-entity-title-field i,\n.fts-entity-snippet-field i {\n margin-right: 4px;\n font-size: 10px;\n}\n"] }]
1080
1103
  }], null, null); })();
1081
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(KnowledgeConfigResourceComponent, { className: "KnowledgeConfigResourceComponent", filePath: "src/KnowledgeHub/components/config/knowledge-config-resource.component.ts", lineNumber: 81 }); })();
1104
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(KnowledgeConfigResourceComponent, { className: "KnowledgeConfigResourceComponent", filePath: "src/KnowledgeHub/components/config/knowledge-config-resource.component.ts", lineNumber: 82 }); })();
1082
1105
  /** Tree-shaking prevention */
1083
1106
  export function LoadKnowledgeConfigResource() {
1084
1107
  // Prevents tree-shaking