@memberjunction/ng-dashboards 5.24.0 → 5.25.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 (284) hide show
  1. package/dist/AI/components/agents/agent-configuration.component.d.ts +15 -33
  2. package/dist/AI/components/agents/agent-configuration.component.d.ts.map +1 -1
  3. package/dist/AI/components/agents/agent-configuration.component.js +233 -493
  4. package/dist/AI/components/agents/agent-configuration.component.js.map +1 -1
  5. package/dist/AI/components/agents/agent-editor.component.d.ts +2 -2
  6. package/dist/AI/components/agents/agent-editor.component.d.ts.map +1 -1
  7. package/dist/AI/components/agents/agent-editor.component.js +7 -7
  8. package/dist/AI/components/agents/agent-editor.component.js.map +1 -1
  9. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts +43 -6
  10. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts.map +1 -1
  11. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js +1135 -864
  12. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js.map +1 -1
  13. package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts +4 -3
  14. package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts.map +1 -1
  15. package/dist/AI/components/duplicates/duplicate-detection-resource.component.js +1 -0
  16. package/dist/AI/components/duplicates/duplicate-detection-resource.component.js.map +1 -1
  17. package/dist/AI/components/execution-monitoring.component.d.ts +4 -5
  18. package/dist/AI/components/execution-monitoring.component.d.ts.map +1 -1
  19. package/dist/AI/components/execution-monitoring.component.js +14 -15
  20. package/dist/AI/components/execution-monitoring.component.js.map +1 -1
  21. package/dist/AI/components/models/model-management.component.d.ts +4 -4
  22. package/dist/AI/components/models/model-management.component.d.ts.map +1 -1
  23. package/dist/AI/components/models/model-management.component.js +5 -5
  24. package/dist/AI/components/models/model-management.component.js.map +1 -1
  25. package/dist/AI/components/prompts/prompt-management.component.d.ts +4 -4
  26. package/dist/AI/components/prompts/prompt-management.component.d.ts.map +1 -1
  27. package/dist/AI/components/prompts/prompt-management.component.js +5 -5
  28. package/dist/AI/components/prompts/prompt-management.component.js.map +1 -1
  29. package/dist/AI/components/requests/agent-requests-resource.component.d.ts +2 -1
  30. package/dist/AI/components/requests/agent-requests-resource.component.d.ts.map +1 -1
  31. package/dist/AI/components/requests/agent-requests-resource.component.js +1 -0
  32. package/dist/AI/components/requests/agent-requests-resource.component.js.map +1 -1
  33. package/dist/AI/components/system/system-configuration.component.d.ts +2 -3
  34. package/dist/AI/components/system/system-configuration.component.d.ts.map +1 -1
  35. package/dist/AI/components/system/system-configuration.component.js +9 -11
  36. package/dist/AI/components/system/system-configuration.component.js.map +1 -1
  37. package/dist/AI/components/vectors/vector-management-resource.component.d.ts +44 -8
  38. package/dist/AI/components/vectors/vector-management-resource.component.d.ts.map +1 -1
  39. package/dist/AI/components/vectors/vector-management-resource.component.js +648 -384
  40. package/dist/AI/components/vectors/vector-management-resource.component.js.map +1 -1
  41. package/dist/APIKeys/api-keys-resource.component.d.ts +2 -1
  42. package/dist/APIKeys/api-keys-resource.component.d.ts.map +1 -1
  43. package/dist/APIKeys/api-keys-resource.component.js +2 -0
  44. package/dist/APIKeys/api-keys-resource.component.js.map +1 -1
  45. package/dist/Actions/components/actions-overview.component.d.ts +4 -5
  46. package/dist/Actions/components/actions-overview.component.d.ts.map +1 -1
  47. package/dist/Actions/components/actions-overview.component.js +11 -12
  48. package/dist/Actions/components/actions-overview.component.js.map +1 -1
  49. package/dist/Actions/components/code-management.component.d.ts +2 -3
  50. package/dist/Actions/components/code-management.component.d.ts.map +1 -1
  51. package/dist/Actions/components/code-management.component.js +4 -6
  52. package/dist/Actions/components/code-management.component.js.map +1 -1
  53. package/dist/Actions/components/entity-integration.component.d.ts +2 -3
  54. package/dist/Actions/components/entity-integration.component.d.ts.map +1 -1
  55. package/dist/Actions/components/entity-integration.component.js +4 -6
  56. package/dist/Actions/components/entity-integration.component.js.map +1 -1
  57. package/dist/Actions/components/execution-monitoring.component.d.ts +4 -5
  58. package/dist/Actions/components/execution-monitoring.component.d.ts.map +1 -1
  59. package/dist/Actions/components/execution-monitoring.component.js +10 -11
  60. package/dist/Actions/components/execution-monitoring.component.js.map +1 -1
  61. package/dist/Actions/components/explorer/action-explorer.component.d.ts +13 -12
  62. package/dist/Actions/components/explorer/action-explorer.component.d.ts.map +1 -1
  63. package/dist/Actions/components/explorer/action-explorer.component.js +39 -66
  64. package/dist/Actions/components/explorer/action-explorer.component.js.map +1 -1
  65. package/dist/Actions/components/scheduled-actions.component.d.ts +2 -3
  66. package/dist/Actions/components/scheduled-actions.component.d.ts.map +1 -1
  67. package/dist/Actions/components/scheduled-actions.component.js +4 -6
  68. package/dist/Actions/components/scheduled-actions.component.js.map +1 -1
  69. package/dist/Actions/components/security-permissions.component.d.ts +2 -3
  70. package/dist/Actions/components/security-permissions.component.d.ts.map +1 -1
  71. package/dist/Actions/components/security-permissions.component.js +4 -6
  72. package/dist/Actions/components/security-permissions.component.js.map +1 -1
  73. package/dist/ApplicationRoles/application-roles-resource.component.d.ts +112 -0
  74. package/dist/ApplicationRoles/application-roles-resource.component.d.ts.map +1 -0
  75. package/dist/ApplicationRoles/application-roles-resource.component.js +532 -0
  76. package/dist/ApplicationRoles/application-roles-resource.component.js.map +1 -0
  77. package/dist/Communication/communication-dashboard.component.d.ts.map +1 -1
  78. package/dist/Communication/communication-dashboard.component.js +1 -0
  79. package/dist/Communication/communication-dashboard.component.js.map +1 -1
  80. package/dist/Communication/communication-logs-resource.component.d.ts.map +1 -1
  81. package/dist/Communication/communication-logs-resource.component.js +4 -1
  82. package/dist/Communication/communication-logs-resource.component.js.map +1 -1
  83. package/dist/Communication/communication-monitor-resource.component.d.ts.map +1 -1
  84. package/dist/Communication/communication-monitor-resource.component.js +4 -1
  85. package/dist/Communication/communication-monitor-resource.component.js.map +1 -1
  86. package/dist/Communication/communication-providers-resource.component.d.ts.map +1 -1
  87. package/dist/Communication/communication-providers-resource.component.js +4 -1
  88. package/dist/Communication/communication-providers-resource.component.js.map +1 -1
  89. package/dist/Communication/communication-runs-resource.component.d.ts.map +1 -1
  90. package/dist/Communication/communication-runs-resource.component.js +4 -1
  91. package/dist/Communication/communication-runs-resource.component.js.map +1 -1
  92. package/dist/Communication/communication-templates-resource.component.d.ts.map +1 -1
  93. package/dist/Communication/communication-templates-resource.component.js +4 -1
  94. package/dist/Communication/communication-templates-resource.component.js.map +1 -1
  95. package/dist/ComponentStudio/component-studio-dashboard.component.d.ts +2 -1
  96. package/dist/ComponentStudio/component-studio-dashboard.component.d.ts.map +1 -1
  97. package/dist/ComponentStudio/component-studio-dashboard.component.js +1 -0
  98. package/dist/ComponentStudio/component-studio-dashboard.component.js.map +1 -1
  99. package/dist/Credentials/components/credentials-audit-resource.component.d.ts.map +1 -1
  100. package/dist/Credentials/components/credentials-audit-resource.component.js +2 -0
  101. package/dist/Credentials/components/credentials-audit-resource.component.js.map +1 -1
  102. package/dist/Credentials/components/credentials-categories-resource.component.d.ts +2 -3
  103. package/dist/Credentials/components/credentials-categories-resource.component.d.ts.map +1 -1
  104. package/dist/Credentials/components/credentials-categories-resource.component.js +10 -11
  105. package/dist/Credentials/components/credentials-categories-resource.component.js.map +1 -1
  106. package/dist/Credentials/components/credentials-list-resource.component.d.ts +2 -1
  107. package/dist/Credentials/components/credentials-list-resource.component.d.ts.map +1 -1
  108. package/dist/Credentials/components/credentials-list-resource.component.js +2 -0
  109. package/dist/Credentials/components/credentials-list-resource.component.js.map +1 -1
  110. package/dist/Credentials/components/credentials-overview-resource.component.d.ts +4 -4
  111. package/dist/Credentials/components/credentials-overview-resource.component.d.ts.map +1 -1
  112. package/dist/Credentials/components/credentials-overview-resource.component.js +8 -9
  113. package/dist/Credentials/components/credentials-overview-resource.component.js.map +1 -1
  114. package/dist/Credentials/components/credentials-types-resource.component.d.ts +2 -3
  115. package/dist/Credentials/components/credentials-types-resource.component.d.ts.map +1 -1
  116. package/dist/Credentials/components/credentials-types-resource.component.js +11 -12
  117. package/dist/Credentials/components/credentials-types-resource.component.js.map +1 -1
  118. package/dist/Credentials/credentials-dashboard.component.d.ts.map +1 -1
  119. package/dist/Credentials/credentials-dashboard.component.js +1 -0
  120. package/dist/Credentials/credentials-dashboard.component.js.map +1 -1
  121. package/dist/DashboardBrowser/dashboard-browser-resource.component.d.ts +2 -3
  122. package/dist/DashboardBrowser/dashboard-browser-resource.component.d.ts.map +1 -1
  123. package/dist/DashboardBrowser/dashboard-browser-resource.component.js +9 -10
  124. package/dist/DashboardBrowser/dashboard-browser-resource.component.js.map +1 -1
  125. package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.js +2 -2
  126. package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.d.ts +23 -15
  127. package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.d.ts.map +1 -1
  128. package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.js +167 -213
  129. package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.js.map +1 -1
  130. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +68 -32
  131. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
  132. package/dist/DataExplorer/data-explorer-dashboard.component.js +453 -420
  133. package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
  134. package/dist/DataExplorer/data-explorer-resource.component.d.ts +10 -3
  135. package/dist/DataExplorer/data-explorer-resource.component.d.ts.map +1 -1
  136. package/dist/DataExplorer/data-explorer-resource.component.js +35 -11
  137. package/dist/DataExplorer/data-explorer-resource.component.js.map +1 -1
  138. package/dist/DataExplorer/models/explorer-state.interface.d.ts +12 -3
  139. package/dist/DataExplorer/models/explorer-state.interface.d.ts.map +1 -1
  140. package/dist/DataExplorer/models/explorer-state.interface.js +5 -1
  141. package/dist/DataExplorer/models/explorer-state.interface.js.map +1 -1
  142. package/dist/Home/home-dashboard.component.d.ts +4 -4
  143. package/dist/Home/home-dashboard.component.d.ts.map +1 -1
  144. package/dist/Home/home-dashboard.component.js +4 -5
  145. package/dist/Home/home-dashboard.component.js.map +1 -1
  146. package/dist/Integration/components/activity/activity.component.d.ts.map +1 -1
  147. package/dist/Integration/components/activity/activity.component.js +1 -0
  148. package/dist/Integration/components/activity/activity.component.js.map +1 -1
  149. package/dist/Integration/components/connections/connections.component.d.ts.map +1 -1
  150. package/dist/Integration/components/connections/connections.component.js +2 -0
  151. package/dist/Integration/components/connections/connections.component.js.map +1 -1
  152. package/dist/Integration/components/mapping-workspace/mapping-workspace.component.d.ts.map +1 -1
  153. package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js +1 -0
  154. package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js.map +1 -1
  155. package/dist/Integration/components/overview/overview.component.d.ts.map +1 -1
  156. package/dist/Integration/components/overview/overview.component.js +2 -0
  157. package/dist/Integration/components/overview/overview.component.js.map +1 -1
  158. package/dist/Integration/components/pipelines/pipelines.component.d.ts.map +1 -1
  159. package/dist/Integration/components/pipelines/pipelines.component.js +2 -0
  160. package/dist/Integration/components/pipelines/pipelines.component.js.map +1 -1
  161. package/dist/Integration/components/schedules/schedules.component.d.ts.map +1 -1
  162. package/dist/Integration/components/schedules/schedules.component.js +2 -0
  163. package/dist/Integration/components/schedules/schedules.component.js.map +1 -1
  164. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.d.ts +4 -3
  165. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.d.ts.map +1 -1
  166. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js +1 -0
  167. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js.map +1 -1
  168. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.d.ts +4 -3
  169. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.d.ts.map +1 -1
  170. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js +1 -0
  171. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js.map +1 -1
  172. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.d.ts +13 -3
  173. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.d.ts.map +1 -1
  174. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js +220 -138
  175. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js.map +1 -1
  176. package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.d.ts +4 -3
  177. package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.d.ts.map +1 -1
  178. package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.js +1 -0
  179. package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.js.map +1 -1
  180. package/dist/KnowledgeHub/index.d.ts +0 -1
  181. package/dist/KnowledgeHub/index.d.ts.map +1 -1
  182. package/dist/KnowledgeHub/index.js +0 -1
  183. package/dist/KnowledgeHub/index.js.map +1 -1
  184. package/dist/Lists/components/lists-browse-resource.component.d.ts +2 -1
  185. package/dist/Lists/components/lists-browse-resource.component.d.ts.map +1 -1
  186. package/dist/Lists/components/lists-browse-resource.component.js +2 -0
  187. package/dist/Lists/components/lists-browse-resource.component.js.map +1 -1
  188. package/dist/Lists/components/lists-categories-resource.component.d.ts +2 -1
  189. package/dist/Lists/components/lists-categories-resource.component.d.ts.map +1 -1
  190. package/dist/Lists/components/lists-categories-resource.component.js +2 -0
  191. package/dist/Lists/components/lists-categories-resource.component.js.map +1 -1
  192. package/dist/Lists/components/lists-my-lists-resource.component.d.ts +2 -1
  193. package/dist/Lists/components/lists-my-lists-resource.component.d.ts.map +1 -1
  194. package/dist/Lists/components/lists-my-lists-resource.component.js +2 -0
  195. package/dist/Lists/components/lists-my-lists-resource.component.js.map +1 -1
  196. package/dist/Lists/components/lists-operations-resource.component.d.ts +2 -1
  197. package/dist/Lists/components/lists-operations-resource.component.d.ts.map +1 -1
  198. package/dist/Lists/components/lists-operations-resource.component.js +2 -0
  199. package/dist/Lists/components/lists-operations-resource.component.js.map +1 -1
  200. package/dist/MCP/mcp-dashboard.component.d.ts +7 -28
  201. package/dist/MCP/mcp-dashboard.component.d.ts.map +1 -1
  202. package/dist/MCP/mcp-dashboard.component.js +25 -107
  203. package/dist/MCP/mcp-dashboard.component.js.map +1 -1
  204. package/dist/MCP/mcp-resource.component.d.ts.map +1 -1
  205. package/dist/MCP/mcp-resource.component.js +1 -0
  206. package/dist/MCP/mcp-resource.component.js.map +1 -1
  207. package/dist/QueryBrowser/query-browser-resource.component.d.ts +10 -23
  208. package/dist/QueryBrowser/query-browser-resource.component.d.ts.map +1 -1
  209. package/dist/QueryBrowser/query-browser-resource.component.js +41 -103
  210. package/dist/QueryBrowser/query-browser-resource.component.js.map +1 -1
  211. package/dist/Scheduling/components/scheduling-activity-resource.component.d.ts.map +1 -1
  212. package/dist/Scheduling/components/scheduling-activity-resource.component.js +1 -0
  213. package/dist/Scheduling/components/scheduling-activity-resource.component.js.map +1 -1
  214. package/dist/Scheduling/components/scheduling-jobs-resource.component.d.ts.map +1 -1
  215. package/dist/Scheduling/components/scheduling-jobs-resource.component.js +1 -0
  216. package/dist/Scheduling/components/scheduling-jobs-resource.component.js.map +1 -1
  217. package/dist/Scheduling/components/scheduling-overview-resource.component.d.ts.map +1 -1
  218. package/dist/Scheduling/components/scheduling-overview-resource.component.js +1 -0
  219. package/dist/Scheduling/components/scheduling-overview-resource.component.js.map +1 -1
  220. package/dist/Scheduling/scheduling-dashboard.component.d.ts.map +1 -1
  221. package/dist/Scheduling/scheduling-dashboard.component.js +1 -0
  222. package/dist/Scheduling/scheduling-dashboard.component.js.map +1 -1
  223. package/dist/SystemDiagnostics/system-diagnostics.component.d.ts +4 -4
  224. package/dist/SystemDiagnostics/system-diagnostics.component.d.ts.map +1 -1
  225. package/dist/SystemDiagnostics/system-diagnostics.component.js +9 -10
  226. package/dist/SystemDiagnostics/system-diagnostics.component.js.map +1 -1
  227. package/dist/Testing/components/testing-analytics-resource.component.d.ts.map +1 -1
  228. package/dist/Testing/components/testing-analytics-resource.component.js +2 -0
  229. package/dist/Testing/components/testing-analytics-resource.component.js.map +1 -1
  230. package/dist/Testing/components/testing-dashboard-tab-resource.component.d.ts +2 -1
  231. package/dist/Testing/components/testing-dashboard-tab-resource.component.d.ts.map +1 -1
  232. package/dist/Testing/components/testing-dashboard-tab-resource.component.js +2 -0
  233. package/dist/Testing/components/testing-dashboard-tab-resource.component.js.map +1 -1
  234. package/dist/Testing/components/testing-explorer-resource.component.d.ts.map +1 -1
  235. package/dist/Testing/components/testing-explorer-resource.component.js +2 -0
  236. package/dist/Testing/components/testing-explorer-resource.component.js.map +1 -1
  237. package/dist/Testing/components/testing-review-resource.component.d.ts.map +1 -1
  238. package/dist/Testing/components/testing-review-resource.component.js +2 -0
  239. package/dist/Testing/components/testing-review-resource.component.js.map +1 -1
  240. package/dist/Testing/components/testing-runs-resource.component.d.ts +2 -1
  241. package/dist/Testing/components/testing-runs-resource.component.d.ts.map +1 -1
  242. package/dist/Testing/components/testing-runs-resource.component.js +2 -0
  243. package/dist/Testing/components/testing-runs-resource.component.js.map +1 -1
  244. package/dist/Testing/testing-dashboard.component.d.ts +2 -1
  245. package/dist/Testing/testing-dashboard.component.d.ts.map +1 -1
  246. package/dist/Testing/testing-dashboard.component.js +1 -0
  247. package/dist/Testing/testing-dashboard.component.js.map +1 -1
  248. package/dist/VersionHistory/components/diff-resource.component.d.ts +4 -4
  249. package/dist/VersionHistory/components/diff-resource.component.d.ts.map +1 -1
  250. package/dist/VersionHistory/components/diff-resource.component.js +9 -10
  251. package/dist/VersionHistory/components/diff-resource.component.js.map +1 -1
  252. package/dist/VersionHistory/components/graph-resource.component.d.ts +2 -1
  253. package/dist/VersionHistory/components/graph-resource.component.d.ts.map +1 -1
  254. package/dist/VersionHistory/components/graph-resource.component.js +2 -0
  255. package/dist/VersionHistory/components/graph-resource.component.js.map +1 -1
  256. package/dist/VersionHistory/components/labels-resource.component.d.ts +4 -4
  257. package/dist/VersionHistory/components/labels-resource.component.d.ts.map +1 -1
  258. package/dist/VersionHistory/components/labels-resource.component.js +10 -11
  259. package/dist/VersionHistory/components/labels-resource.component.js.map +1 -1
  260. package/dist/VersionHistory/components/restore-resource.component.d.ts +2 -1
  261. package/dist/VersionHistory/components/restore-resource.component.d.ts.map +1 -1
  262. package/dist/VersionHistory/components/restore-resource.component.js +2 -0
  263. package/dist/VersionHistory/components/restore-resource.component.js.map +1 -1
  264. package/dist/ai-dashboards.module.d.ts +19 -19
  265. package/dist/ai-dashboards.module.d.ts.map +1 -1
  266. package/dist/ai-dashboards.module.js +4 -5
  267. package/dist/ai-dashboards.module.js.map +1 -1
  268. package/dist/core-dashboards.module.d.ts +19 -18
  269. package/dist/core-dashboards.module.d.ts.map +1 -1
  270. package/dist/core-dashboards.module.js +8 -0
  271. package/dist/core-dashboards.module.js.map +1 -1
  272. package/dist/data-explorer-dashboards.module.d.ts +2 -1
  273. package/dist/data-explorer-dashboards.module.d.ts.map +1 -1
  274. package/dist/data-explorer-dashboards.module.js +7 -3
  275. package/dist/data-explorer-dashboards.module.js.map +1 -1
  276. package/dist/public-api.d.ts +1 -1
  277. package/dist/public-api.d.ts.map +1 -1
  278. package/dist/public-api.js +2 -1
  279. package/dist/public-api.js.map +1 -1
  280. package/package.json +47 -47
  281. package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.d.ts +0 -166
  282. package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.d.ts.map +0 -1
  283. package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.js +0 -991
  284. package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.js.map +0 -1
@@ -128,7 +128,21 @@ function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Condition
128
128
  i0.ɵɵtext(1, "No providers registered. Add a vector database provider (e.g., Pinecone, Weaviate) via the admin console.");
129
129
  i0.ɵɵelementEnd();
130
130
  } }
131
+ function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_23_For_2_For_20_Template(rf, ctx) { if (rf & 1) {
132
+ i0.ɵɵelementStart(0, "option", 53);
133
+ i0.ɵɵtext(1);
134
+ i0.ɵɵelementEnd();
135
+ } if (rf & 2) {
136
+ const cred_r7 = ctx.$implicit;
137
+ i0.ɵɵproperty("ngValue", cred_r7.ID);
138
+ i0.ɵɵadvance();
139
+ i0.ɵɵtextInterpolate(cred_r7.Name);
140
+ } }
141
+ function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_23_For_2_Conditional_21_Template(rf, ctx) { if (rf & 1) {
142
+ i0.ɵɵelement(0, "i", 54);
143
+ } }
131
144
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_23_For_2_Template(rf, ctx) { if (rf & 1) {
145
+ const _r5 = i0.ɵɵgetCurrentView();
132
146
  i0.ɵɵelementStart(0, "div", 41)(1, "div", 42);
133
147
  i0.ɵɵelement(2, "i", 43);
134
148
  i0.ɵɵelementEnd();
@@ -142,16 +156,40 @@ function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Condition
142
156
  i0.ɵɵelement(9, "i", 33);
143
157
  i0.ɵɵtext(10, " Active ");
144
158
  i0.ɵɵelementEnd()();
159
+ i0.ɵɵelementStart(11, "div", 48)(12, "label", 49);
160
+ i0.ɵɵelement(13, "i", 50);
161
+ i0.ɵɵtext(14, " API Credential ");
162
+ i0.ɵɵelementEnd();
163
+ i0.ɵɵelementStart(15, "div", 51)(16, "select", 52);
164
+ i0.ɵɵtwoWayListener("ngModelChange", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_23_For_2_Template_select_ngModelChange_16_listener($event) { const provider_r6 = i0.ɵɵrestoreView(_r5).$implicit; i0.ɵɵtwoWayBindingSet(provider_r6.CredentialID, $event) || (provider_r6.CredentialID = $event); return i0.ɵɵresetView($event); });
165
+ i0.ɵɵlistener("change", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_23_For_2_Template_select_change_16_listener() { const provider_r6 = i0.ɵɵrestoreView(_r5).$implicit; const ctx_r2 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r2.SaveProviderCredential(provider_r6)); });
166
+ i0.ɵɵelementStart(17, "option", 53);
167
+ i0.ɵɵtext(18, "None (use environment variable)");
168
+ i0.ɵɵelementEnd();
169
+ i0.ɵɵrepeaterCreate(19, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_23_For_2_For_20_Template, 2, 2, "option", 53, _forTrack0);
170
+ i0.ɵɵelementEnd();
171
+ i0.ɵɵconditionalCreate(21, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_23_For_2_Conditional_21_Template, 1, 0, "i", 54);
172
+ i0.ɵɵelementEnd()();
145
173
  } if (rf & 2) {
146
- const provider_r5 = ctx.$implicit;
174
+ const provider_r6 = ctx.$implicit;
175
+ const ctx_r2 = i0.ɵɵnextContext(4);
147
176
  i0.ɵɵadvance(5);
148
- i0.ɵɵtextInterpolate(provider_r5.Name);
177
+ i0.ɵɵtextInterpolate(provider_r6.Name);
178
+ i0.ɵɵadvance(2);
179
+ i0.ɵɵtextInterpolate(provider_r6.ClassKey);
180
+ i0.ɵɵadvance(9);
181
+ i0.ɵɵtwoWayProperty("ngModel", provider_r6.CredentialID);
182
+ i0.ɵɵproperty("disabled", ctx_r2.IsSavingCredential);
183
+ i0.ɵɵadvance();
184
+ i0.ɵɵproperty("ngValue", null);
185
+ i0.ɵɵadvance(2);
186
+ i0.ɵɵrepeater(ctx_r2.AvailableCredentials);
149
187
  i0.ɵɵadvance(2);
150
- i0.ɵɵtextInterpolate(provider_r5.ClassKey);
188
+ i0.ɵɵconditional(ctx_r2.IsSavingCredential ? 21 : -1);
151
189
  } }
152
190
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_23_Template(rf, ctx) { if (rf & 1) {
153
191
  i0.ɵɵelementStart(0, "div", 38);
154
- i0.ɵɵrepeaterCreate(1, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_23_For_2_Template, 11, 2, "div", 41, _forTrack0);
192
+ i0.ɵɵrepeaterCreate(1, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_23_For_2_Template, 22, 6, null, null, _forTrack0);
155
193
  i0.ɵɵelementEnd();
156
194
  } if (rf & 2) {
157
195
  const ctx_r2 = i0.ɵɵnextContext(3);
@@ -181,17 +219,17 @@ function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Condition
181
219
  i0.ɵɵelementEnd();
182
220
  } }
183
221
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_34_For_3_Template(rf, ctx) { if (rf & 1) {
184
- i0.ɵɵelementStart(0, "span", 49);
222
+ i0.ɵɵelementStart(0, "span", 56);
185
223
  i0.ɵɵtext(1);
186
224
  i0.ɵɵelementEnd();
187
225
  } if (rf & 2) {
188
- const model_r6 = ctx.$implicit;
226
+ const model_r8 = ctx.$implicit;
189
227
  i0.ɵɵadvance();
190
- i0.ɵɵtextInterpolate(model_r6.Name);
228
+ i0.ɵɵtextInterpolate(model_r8.Name);
191
229
  } }
192
230
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_34_Template(rf, ctx) { if (rf & 1) {
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);
231
+ i0.ɵɵelementStart(0, "div", 38)(1, "div", 55);
232
+ i0.ɵɵrepeaterCreate(2, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_34_For_3_Template, 2, 1, "span", 56, _forTrack0);
195
233
  i0.ɵɵelementEnd()();
196
234
  } if (rf & 2) {
197
235
  const ctx_r2 = i0.ɵɵnextContext(3);
@@ -226,47 +264,47 @@ function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Condition
226
264
  i0.ɵɵelementEnd();
227
265
  } }
228
266
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_46_Template(rf, ctx) { if (rf & 1) {
229
- const _r7 = i0.ɵɵgetCurrentView();
230
- i0.ɵɵelementStart(0, "button", 50);
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()); });
232
- i0.ɵɵelement(1, "i", 51);
267
+ const _r9 = i0.ɵɵgetCurrentView();
268
+ i0.ɵɵelementStart(0, "button", 57);
269
+ i0.ɵɵlistener("click", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_46_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r9); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.OpenCreateIndexForm()); });
270
+ i0.ɵɵelement(1, "i", 58);
233
271
  i0.ɵɵtext(2, " Create Index ");
234
272
  i0.ɵɵelementEnd();
235
273
  } }
236
274
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_47_For_2_Template(rf, ctx) { if (rf & 1) {
237
- const _r8 = i0.ɵɵgetCurrentView();
238
- i0.ɵɵelementStart(0, "div", 52)(1, "div", 53);
239
- i0.ɵɵelement(2, "i", 54);
275
+ const _r10 = i0.ɵɵgetCurrentView();
276
+ i0.ɵɵelementStart(0, "div", 59)(1, "div", 60);
277
+ i0.ɵɵelement(2, "i", 61);
240
278
  i0.ɵɵelementEnd();
241
- i0.ɵɵelementStart(3, "div", 55)(4, "span", 56);
279
+ i0.ɵɵelementStart(3, "div", 62)(4, "span", 63);
242
280
  i0.ɵɵtext(5);
243
281
  i0.ɵɵelementEnd();
244
- i0.ɵɵelementStart(6, "span", 57);
282
+ i0.ɵɵelementStart(6, "span", 64);
245
283
  i0.ɵɵelement(7, "i", 43);
246
284
  i0.ɵɵtext(8);
247
- i0.ɵɵelement(9, "i", 58);
285
+ i0.ɵɵelement(9, "i", 65);
248
286
  i0.ɵɵtext(10);
249
287
  i0.ɵɵelementEnd()();
250
- i0.ɵɵelementStart(11, "div", 59)(12, "span", 47);
288
+ i0.ɵɵelementStart(11, "div", 66)(12, "span", 47);
251
289
  i0.ɵɵelement(13, "i", 33);
252
290
  i0.ɵɵtext(14, " Active ");
253
291
  i0.ɵɵelementEnd();
254
- i0.ɵɵelementStart(15, "button", 60);
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)); });
256
- i0.ɵɵelement(16, "i", 61);
292
+ i0.ɵɵelementStart(15, "button", 67);
293
+ i0.ɵɵlistener("click", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_47_For_2_Template_button_click_15_listener() { const idx_r11 = i0.ɵɵrestoreView(_r10).$implicit; const ctx_r2 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r2.DeleteIndex(idx_r11.ID)); });
294
+ i0.ɵɵelement(16, "i", 68);
257
295
  i0.ɵɵelementEnd()()();
258
296
  } if (rf & 2) {
259
- const idx_r9 = ctx.$implicit;
297
+ const idx_r11 = ctx.$implicit;
260
298
  i0.ɵɵadvance(5);
261
- i0.ɵɵtextInterpolate(idx_r9.Name);
299
+ i0.ɵɵtextInterpolate(idx_r11.Name);
262
300
  i0.ɵɵadvance(3);
263
- i0.ɵɵtextInterpolate1(" ", idx_r9.VectorDatabase, " \u00A0\u00B7\u00A0 ");
301
+ i0.ɵɵtextInterpolate1(" ", idx_r11.VectorDatabase, " \u00A0\u00B7\u00A0 ");
264
302
  i0.ɵɵadvance(2);
265
- i0.ɵɵtextInterpolate1(" ", idx_r9.EmbeddingModel, " ");
303
+ i0.ɵɵtextInterpolate1(" ", idx_r11.EmbeddingModel, " ");
266
304
  } }
267
305
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_47_Template(rf, ctx) { if (rf & 1) {
268
306
  i0.ɵɵelementStart(0, "div", 38);
269
- i0.ɵɵrepeaterCreate(1, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_47_For_2_Template, 17, 3, "div", 52, _forTrack0);
307
+ i0.ɵɵrepeaterCreate(1, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_47_For_2_Template, 17, 3, "div", 59, _forTrack0);
270
308
  i0.ɵɵelementEnd();
271
309
  } if (rf & 2) {
272
310
  const ctx_r2 = i0.ɵɵnextContext(3);
@@ -274,65 +312,65 @@ function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Condition
274
312
  i0.ɵɵrepeater(ctx_r2.VectorIndexes);
275
313
  } }
276
314
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_48_For_14_Template(rf, ctx) { if (rf & 1) {
277
- i0.ɵɵelementStart(0, "option", 69);
315
+ i0.ɵɵelementStart(0, "option", 76);
278
316
  i0.ɵɵtext(1);
279
317
  i0.ɵɵelementEnd();
280
318
  } if (rf & 2) {
281
- const db_r11 = ctx.$implicit;
282
- i0.ɵɵproperty("value", db_r11.ID);
319
+ const db_r13 = ctx.$implicit;
320
+ i0.ɵɵproperty("value", db_r13.ID);
283
321
  i0.ɵɵadvance();
284
- i0.ɵɵtextInterpolate(db_r11.Name);
322
+ i0.ɵɵtextInterpolate(db_r13.Name);
285
323
  } }
286
324
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_48_For_20_Template(rf, ctx) { if (rf & 1) {
287
- i0.ɵɵelementStart(0, "option", 69);
325
+ i0.ɵɵelementStart(0, "option", 76);
288
326
  i0.ɵɵtext(1);
289
327
  i0.ɵɵelementEnd();
290
328
  } if (rf & 2) {
291
- const model_r12 = ctx.$implicit;
292
- i0.ɵɵproperty("value", model_r12.ID);
329
+ const model_r14 = ctx.$implicit;
330
+ i0.ɵɵproperty("value", model_r14.ID);
293
331
  i0.ɵɵadvance();
294
- i0.ɵɵtextInterpolate(model_r12.Name);
332
+ i0.ɵɵtextInterpolate(model_r14.Name);
295
333
  } }
296
334
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_48_Conditional_23_Template(rf, ctx) { if (rf & 1) {
297
- i0.ɵɵelement(0, "i", 73);
335
+ i0.ɵɵelement(0, "i", 80);
298
336
  i0.ɵɵtext(1, " Creating... ");
299
337
  } }
300
338
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_48_Conditional_24_Template(rf, ctx) { if (rf & 1) {
301
- i0.ɵɵelement(0, "i", 51);
339
+ i0.ɵɵelement(0, "i", 58);
302
340
  i0.ɵɵtext(1, " Create Index ");
303
341
  } }
304
342
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_48_Template(rf, ctx) { if (rf & 1) {
305
- const _r10 = i0.ɵɵgetCurrentView();
306
- i0.ɵɵelementStart(0, "div", 40)(1, "h4", 62);
307
- i0.ɵɵelement(2, "i", 63);
343
+ const _r12 = i0.ɵɵgetCurrentView();
344
+ i0.ɵɵelementStart(0, "div", 40)(1, "h4", 69);
345
+ i0.ɵɵelement(2, "i", 70);
308
346
  i0.ɵɵtext(3, " Create New Vector Index ");
309
347
  i0.ɵɵelementEnd();
310
- i0.ɵɵelementStart(4, "div", 64)(5, "div", 65)(6, "label", 66);
348
+ i0.ɵɵelementStart(4, "div", 71)(5, "div", 72)(6, "label", 73);
311
349
  i0.ɵɵtext(7, "Index Name");
312
350
  i0.ɵɵelementEnd();
313
- i0.ɵɵelementStart(8, "input", 67);
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); });
351
+ i0.ɵɵelementStart(8, "input", 74);
352
+ i0.ɵɵtwoWayListener("ngModelChange", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_48_Template_input_ngModelChange_8_listener($event) { i0.ɵɵrestoreView(_r12); const ctx_r2 = i0.ɵɵnextContext(3); i0.ɵɵtwoWayBindingSet(ctx_r2.NewIndexName, $event) || (ctx_r2.NewIndexName = $event); return i0.ɵɵresetView($event); });
315
353
  i0.ɵɵelementEnd()();
316
- i0.ɵɵelementStart(9, "div", 65)(10, "label", 66);
354
+ i0.ɵɵelementStart(9, "div", 72)(10, "label", 73);
317
355
  i0.ɵɵtext(11, "Vector Database");
318
356
  i0.ɵɵelementEnd();
319
- i0.ɵɵelementStart(12, "select", 68);
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); });
321
- i0.ɵɵrepeaterCreate(13, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_48_For_14_Template, 2, 2, "option", 69, _forTrack0);
357
+ i0.ɵɵelementStart(12, "select", 75);
358
+ i0.ɵɵtwoWayListener("ngModelChange", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_48_Template_select_ngModelChange_12_listener($event) { i0.ɵɵrestoreView(_r12); const ctx_r2 = i0.ɵɵnextContext(3); i0.ɵɵtwoWayBindingSet(ctx_r2.NewIndexVectorDBID, $event) || (ctx_r2.NewIndexVectorDBID = $event); return i0.ɵɵresetView($event); });
359
+ i0.ɵɵrepeaterCreate(13, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_48_For_14_Template, 2, 2, "option", 76, _forTrack0);
322
360
  i0.ɵɵelementEnd()();
323
- i0.ɵɵelementStart(15, "div", 65)(16, "label", 66);
361
+ i0.ɵɵelementStart(15, "div", 72)(16, "label", 73);
324
362
  i0.ɵɵtext(17, "Embedding Model");
325
363
  i0.ɵɵelementEnd();
326
- i0.ɵɵelementStart(18, "select", 68);
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); });
328
- i0.ɵɵrepeaterCreate(19, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_48_For_20_Template, 2, 2, "option", 69, _forTrack0);
364
+ i0.ɵɵelementStart(18, "select", 75);
365
+ i0.ɵɵtwoWayListener("ngModelChange", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_48_Template_select_ngModelChange_18_listener($event) { i0.ɵɵrestoreView(_r12); const ctx_r2 = i0.ɵɵnextContext(3); i0.ɵɵtwoWayBindingSet(ctx_r2.NewIndexEmbeddingModelID, $event) || (ctx_r2.NewIndexEmbeddingModelID = $event); return i0.ɵɵresetView($event); });
366
+ i0.ɵɵrepeaterCreate(19, KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_48_For_20_Template, 2, 2, "option", 76, _forTrack0);
329
367
  i0.ɵɵelementEnd()()();
330
- i0.ɵɵelementStart(21, "div", 70)(22, "button", 71);
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()); });
368
+ i0.ɵɵelementStart(21, "div", 77)(22, "button", 78);
369
+ i0.ɵɵlistener("click", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_48_Template_button_click_22_listener() { i0.ɵɵrestoreView(_r12); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.CreateIndex()); });
332
370
  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);
333
371
  i0.ɵɵelementEnd();
334
- i0.ɵɵelementStart(25, "button", 72);
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()); });
372
+ i0.ɵɵelementStart(25, "button", 79);
373
+ i0.ɵɵlistener("click", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Conditional_48_Template_button_click_25_listener() { i0.ɵɵrestoreView(_r12); const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.CancelCreateIndex()); });
336
374
  i0.ɵɵtext(26, " Cancel ");
337
375
  i0.ɵɵelementEnd()()();
338
376
  } if (rf & 2) {
@@ -439,79 +477,79 @@ function KnowledgeConfigResourceComponent_Conditional_1_Conditional_10_Template(
439
477
  i0.ɵɵconditional(ctx_r2.ShowCreateIndexForm ? 48 : -1);
440
478
  } }
441
479
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_11_Conditional_5_Template(rf, ctx) { if (rf & 1) {
442
- i0.ɵɵelement(0, "mj-loading", 74);
480
+ i0.ɵɵelement(0, "mj-loading", 81);
443
481
  } }
444
482
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_11_Conditional_6_Template(rf, ctx) { if (rf & 1) {
445
- i0.ɵɵelementStart(0, "div", 75);
446
- i0.ɵɵelement(1, "i", 76);
447
- i0.ɵɵelementStart(2, "h3", 77);
483
+ i0.ɵɵelementStart(0, "div", 82);
484
+ i0.ɵɵelement(1, "i", 83);
485
+ i0.ɵɵelementStart(2, "h3", 84);
448
486
  i0.ɵɵtext(3, "No Searchable Entities Found");
449
487
  i0.ɵɵelementEnd();
450
- i0.ɵɵelementStart(4, "p", 78);
488
+ i0.ɵɵelementStart(4, "p", 85);
451
489
  i0.ɵɵtext(5, "No entities with text fields were discovered. Ensure your database schema includes entities with varchar/nvarchar columns.");
452
490
  i0.ɵɵelementEnd()();
453
491
  } }
454
492
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_11_Conditional_7_For_7_For_8_Template(rf, ctx) { if (rf & 1) {
455
- i0.ɵɵelementStart(0, "span", 90);
493
+ i0.ɵɵelementStart(0, "span", 97);
456
494
  i0.ɵɵtext(1);
457
495
  i0.ɵɵelementEnd();
458
496
  } if (rf & 2) {
459
- const field_r16 = ctx.$implicit;
497
+ const field_r18 = ctx.$implicit;
460
498
  i0.ɵɵadvance();
461
- i0.ɵɵtextInterpolate(field_r16);
499
+ i0.ɵɵtextInterpolate(field_r18);
462
500
  } }
463
501
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_11_Conditional_7_For_7_Conditional_13_Template(rf, ctx) { if (rf & 1) {
464
- i0.ɵɵelementStart(0, "span", 94);
465
- i0.ɵɵelement(1, "i", 95);
502
+ i0.ɵɵelementStart(0, "span", 101);
503
+ i0.ɵɵelement(1, "i", 102);
466
504
  i0.ɵɵtext(2);
467
505
  i0.ɵɵelementEnd();
468
506
  } if (rf & 2) {
469
- const entity_r15 = i0.ɵɵnextContext().$implicit;
507
+ const entity_r17 = i0.ɵɵnextContext().$implicit;
470
508
  i0.ɵɵadvance(2);
471
- i0.ɵɵtextInterpolate1(" ", entity_r15.SnippetField, " ");
509
+ i0.ɵɵtextInterpolate1(" ", entity_r17.SnippetField, " ");
472
510
  } }
473
511
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_11_Conditional_7_For_7_Template(rf, ctx) { if (rf & 1) {
474
- const _r14 = i0.ɵɵgetCurrentView();
475
- i0.ɵɵelementStart(0, "div", 85)(1, "div", 86)(2, "input", 19);
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); });
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)); });
512
+ const _r16 = i0.ɵɵgetCurrentView();
513
+ i0.ɵɵelementStart(0, "div", 92)(1, "div", 93)(2, "input", 19);
514
+ i0.ɵɵtwoWayListener("ngModelChange", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_11_Conditional_7_For_7_Template_input_ngModelChange_2_listener($event) { const entity_r17 = i0.ɵɵrestoreView(_r16).$implicit; i0.ɵɵtwoWayBindingSet(entity_r17.Enabled, $event) || (entity_r17.Enabled = $event); return i0.ɵɵresetView($event); });
515
+ i0.ɵɵlistener("change", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_11_Conditional_7_For_7_Template_input_change_2_listener() { const entity_r17 = i0.ɵɵrestoreView(_r16).$implicit; const ctx_r2 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r2.OnFTSEntityToggled(entity_r17)); });
478
516
  i0.ɵɵelementEnd()();
479
- i0.ɵɵelementStart(3, "div", 87)(4, "span", 88);
517
+ i0.ɵɵelementStart(3, "div", 94)(4, "span", 95);
480
518
  i0.ɵɵtext(5);
481
519
  i0.ɵɵelementEnd();
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);
520
+ i0.ɵɵelementStart(6, "div", 96);
521
+ i0.ɵɵrepeaterCreate(7, KnowledgeConfigResourceComponent_Conditional_1_Conditional_11_Conditional_7_For_7_For_8_Template, 2, 1, "span", 97, i0.ɵɵrepeaterTrackByIdentity);
484
522
  i0.ɵɵelementEnd()();
485
- i0.ɵɵelementStart(9, "div", 91)(10, "span", 92);
486
- i0.ɵɵelement(11, "i", 93);
523
+ i0.ɵɵelementStart(9, "div", 98)(10, "span", 99);
524
+ i0.ɵɵelement(11, "i", 100);
487
525
  i0.ɵɵtext(12);
488
526
  i0.ɵɵelementEnd();
489
- i0.ɵɵconditionalCreate(13, KnowledgeConfigResourceComponent_Conditional_1_Conditional_11_Conditional_7_For_7_Conditional_13_Template, 3, 1, "span", 94);
527
+ i0.ɵɵconditionalCreate(13, KnowledgeConfigResourceComponent_Conditional_1_Conditional_11_Conditional_7_For_7_Conditional_13_Template, 3, 1, "span", 101);
490
528
  i0.ɵɵelementEnd()();
491
529
  } if (rf & 2) {
492
- const entity_r15 = ctx.$implicit;
493
- i0.ɵɵclassProp("fts-entity-enabled", entity_r15.Enabled);
530
+ const entity_r17 = ctx.$implicit;
531
+ i0.ɵɵclassProp("fts-entity-enabled", entity_r17.Enabled);
494
532
  i0.ɵɵadvance(2);
495
- i0.ɵɵtwoWayProperty("ngModel", entity_r15.Enabled);
533
+ i0.ɵɵtwoWayProperty("ngModel", entity_r17.Enabled);
496
534
  i0.ɵɵadvance(3);
497
- i0.ɵɵtextInterpolate(entity_r15.EntityName);
535
+ i0.ɵɵtextInterpolate(entity_r17.EntityName);
498
536
  i0.ɵɵadvance(2);
499
- i0.ɵɵrepeater(entity_r15.IndexedFields);
537
+ i0.ɵɵrepeater(entity_r17.IndexedFields);
500
538
  i0.ɵɵadvance(5);
501
- i0.ɵɵtextInterpolate1(" ", entity_r15.TitleField, " ");
539
+ i0.ɵɵtextInterpolate1(" ", entity_r17.TitleField, " ");
502
540
  i0.ɵɵadvance();
503
- i0.ɵɵconditional(entity_r15.SnippetField !== entity_r15.TitleField ? 13 : -1);
541
+ i0.ɵɵconditional(entity_r17.SnippetField !== entity_r17.TitleField ? 13 : -1);
504
542
  } }
505
543
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_11_Conditional_7_Template(rf, ctx) { if (rf & 1) {
506
- const _r13 = i0.ɵɵgetCurrentView();
507
- i0.ɵɵelementStart(0, "div", 79)(1, "div", 80)(2, "span", 81);
544
+ const _r15 = i0.ɵɵgetCurrentView();
545
+ i0.ɵɵelementStart(0, "div", 86)(1, "div", 87)(2, "span", 88);
508
546
  i0.ɵɵtext(3);
509
547
  i0.ɵɵelementEnd();
510
- i0.ɵɵelementStart(4, "input", 82);
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); });
548
+ i0.ɵɵelementStart(4, "input", 89);
549
+ i0.ɵɵtwoWayListener("ngModelChange", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_11_Conditional_7_Template_input_ngModelChange_4_listener($event) { i0.ɵɵrestoreView(_r15); const ctx_r2 = i0.ɵɵnextContext(3); i0.ɵɵtwoWayBindingSet(ctx_r2.FTSFilterText, $event) || (ctx_r2.FTSFilterText = $event); return i0.ɵɵresetView($event); });
512
550
  i0.ɵɵelementEnd()()();
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);
551
+ i0.ɵɵelementStart(5, "div", 90);
552
+ i0.ɵɵrepeaterCreate(6, KnowledgeConfigResourceComponent_Conditional_1_Conditional_11_Conditional_7_For_7_Template, 14, 6, "div", 91, _forTrack1);
515
553
  i0.ɵɵelementEnd();
516
554
  } if (rf & 2) {
517
555
  const ctx_r2 = i0.ɵɵnextContext(3);
@@ -529,7 +567,7 @@ function KnowledgeConfigResourceComponent_Conditional_1_Conditional_11_Template(
529
567
  i0.ɵɵelementStart(3, "p", 13);
530
568
  i0.ɵɵtext(4, "Configure which entities are included in full-text search. Entities with text fields (Name, Description, etc.) are automatically discovered.");
531
569
  i0.ɵɵelementEnd();
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);
570
+ i0.ɵɵconditionalCreate(5, KnowledgeConfigResourceComponent_Conditional_1_Conditional_11_Conditional_5_Template, 1, 0, "mj-loading", 81)(6, KnowledgeConfigResourceComponent_Conditional_1_Conditional_11_Conditional_6_Template, 6, 0, "div", 82)(7, KnowledgeConfigResourceComponent_Conditional_1_Conditional_11_Conditional_7_Template, 8, 3);
533
571
  i0.ɵɵelementEnd();
534
572
  } if (rf & 2) {
535
573
  const ctx_r2 = i0.ɵɵnextContext(2);
@@ -537,13 +575,13 @@ function KnowledgeConfigResourceComponent_Conditional_1_Conditional_11_Template(
537
575
  i0.ɵɵconditional(ctx_r2.IsLoadingFTSEntities ? 5 : ctx_r2.FTSEntities.length === 0 ? 6 : 7);
538
576
  } }
539
577
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_12_Conditional_5_For_17_Template(rf, ctx) { if (rf & 1) {
540
- i0.ɵɵelementStart(0, "span", 49);
578
+ i0.ɵɵelementStart(0, "span", 56);
541
579
  i0.ɵɵtext(1);
542
580
  i0.ɵɵelementEnd();
543
581
  } if (rf & 2) {
544
- const model_r17 = ctx.$implicit;
582
+ const model_r19 = ctx.$implicit;
545
583
  i0.ɵɵadvance();
546
- i0.ɵɵtextInterpolate(model_r17.Name);
584
+ i0.ɵɵtextInterpolate(model_r19.Name);
547
585
  } }
548
586
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_12_Conditional_5_Template(rf, ctx) { if (rf & 1) {
549
587
  i0.ɵɵelementStart(0, "div", 14)(1, "div", 20)(2, "div", 21)(3, "span", 17);
@@ -552,7 +590,7 @@ function KnowledgeConfigResourceComponent_Conditional_1_Conditional_12_Condition
552
590
  i0.ɵɵelementStart(5, "span", 18);
553
591
  i0.ɵɵtext(6, "Currently selected embedding model");
554
592
  i0.ɵɵelementEnd()();
555
- i0.ɵɵelementStart(7, "span", 96);
593
+ i0.ɵɵelementStart(7, "span", 103);
556
594
  i0.ɵɵtext(8);
557
595
  i0.ɵɵelementEnd()();
558
596
  i0.ɵɵelementStart(9, "div", 20)(10, "div", 21)(11, "span", 17);
@@ -561,11 +599,11 @@ function KnowledgeConfigResourceComponent_Conditional_1_Conditional_12_Condition
561
599
  i0.ɵɵelementStart(13, "span", 18);
562
600
  i0.ɵɵtext(14);
563
601
  i0.ɵɵelementEnd()();
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);
602
+ i0.ɵɵelementStart(15, "div", 55);
603
+ i0.ɵɵrepeaterCreate(16, KnowledgeConfigResourceComponent_Conditional_1_Conditional_12_Conditional_5_For_17_Template, 2, 1, "span", 56, _forTrack0);
566
604
  i0.ɵɵelementEnd()()();
567
- i0.ɵɵelementStart(18, "p", 97);
568
- i0.ɵɵelement(19, "i", 98);
605
+ i0.ɵɵelementStart(18, "p", 104);
606
+ i0.ɵɵelement(19, "i", 105);
569
607
  i0.ɵɵtext(20, " Manage embedding models in the AI Dashboard > Models tab. ");
570
608
  i0.ɵɵelementEnd();
571
609
  } if (rf & 2) {
@@ -578,12 +616,12 @@ function KnowledgeConfigResourceComponent_Conditional_1_Conditional_12_Condition
578
616
  i0.ɵɵrepeater(ctx_r2.EmbeddingModels);
579
617
  } }
580
618
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_12_Conditional_6_Template(rf, ctx) { if (rf & 1) {
581
- i0.ɵɵelementStart(0, "div", 75);
582
- i0.ɵɵelement(1, "i", 99);
583
- i0.ɵɵelementStart(2, "h3", 77);
619
+ i0.ɵɵelementStart(0, "div", 82);
620
+ i0.ɵɵelement(1, "i", 106);
621
+ i0.ɵɵelementStart(2, "h3", 84);
584
622
  i0.ɵɵtext(3, "No Embedding Models Found");
585
623
  i0.ɵɵelementEnd();
586
- i0.ɵɵelementStart(4, "p", 78);
624
+ i0.ɵɵelementStart(4, "p", 85);
587
625
  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. ");
588
626
  i0.ɵɵelementEnd()();
589
627
  } }
@@ -594,7 +632,7 @@ function KnowledgeConfigResourceComponent_Conditional_1_Conditional_12_Template(
594
632
  i0.ɵɵelementStart(3, "p", 13);
595
633
  i0.ɵɵtext(4, "AI models used for generating vector embeddings from text.");
596
634
  i0.ɵɵelementEnd();
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);
635
+ 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", 82);
598
636
  i0.ɵɵelementEnd();
599
637
  } if (rf & 2) {
600
638
  const ctx_r2 = i0.ɵɵnextContext(2);
@@ -602,7 +640,7 @@ function KnowledgeConfigResourceComponent_Conditional_1_Conditional_12_Template(
602
640
  i0.ɵɵconditional(ctx_r2.HasEmbeddingModel ? 5 : 6);
603
641
  } }
604
642
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_13_Template(rf, ctx) { if (rf & 1) {
605
- const _r18 = i0.ɵɵgetCurrentView();
643
+ const _r20 = i0.ɵɵgetCurrentView();
606
644
  i0.ɵɵelementStart(0, "div", 8)(1, "h2", 12);
607
645
  i0.ɵɵtext(2, "Scoring Thresholds");
608
646
  i0.ɵɵelementEnd();
@@ -615,9 +653,9 @@ function KnowledgeConfigResourceComponent_Conditional_1_Conditional_13_Template(
615
653
  i0.ɵɵelementStart(10, "span", 18);
616
654
  i0.ɵɵtext(11);
617
655
  i0.ɵɵelementEnd()();
618
- i0.ɵɵelementStart(12, "input", 100);
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); });
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()); });
656
+ i0.ɵɵelementStart(12, "input", 107);
657
+ i0.ɵɵtwoWayListener("ngModelChange", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_13_Template_input_ngModelChange_12_listener($event) { i0.ɵɵrestoreView(_r20); const ctx_r2 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r2.ThresholdSettings.DuplicateAbsolute, $event) || (ctx_r2.ThresholdSettings.DuplicateAbsolute = $event); return i0.ɵɵresetView($event); });
658
+ i0.ɵɵlistener("input", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_13_Template_input_input_12_listener() { i0.ɵɵrestoreView(_r20); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.OnSettingChanged()); });
621
659
  i0.ɵɵelementEnd()();
622
660
  i0.ɵɵelementStart(13, "div", 20)(14, "div", 21)(15, "span", 17);
623
661
  i0.ɵɵtext(16, "Duplicate Potential Match");
@@ -625,9 +663,9 @@ function KnowledgeConfigResourceComponent_Conditional_1_Conditional_13_Template(
625
663
  i0.ɵɵelementStart(17, "span", 18);
626
664
  i0.ɵɵtext(18);
627
665
  i0.ɵɵelementEnd()();
628
- i0.ɵɵelementStart(19, "input", 101);
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); });
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()); });
666
+ i0.ɵɵelementStart(19, "input", 108);
667
+ i0.ɵɵtwoWayListener("ngModelChange", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_13_Template_input_ngModelChange_19_listener($event) { i0.ɵɵrestoreView(_r20); const ctx_r2 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r2.ThresholdSettings.DuplicatePotential, $event) || (ctx_r2.ThresholdSettings.DuplicatePotential = $event); return i0.ɵɵresetView($event); });
668
+ i0.ɵɵlistener("input", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_13_Template_input_input_19_listener() { i0.ɵɵrestoreView(_r20); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.OnSettingChanged()); });
631
669
  i0.ɵɵelementEnd()();
632
670
  i0.ɵɵelementStart(20, "div", 20)(21, "div", 21)(22, "span", 17);
633
671
  i0.ɵɵtext(23, "Search Relevance");
@@ -635,9 +673,9 @@ function KnowledgeConfigResourceComponent_Conditional_1_Conditional_13_Template(
635
673
  i0.ɵɵelementStart(24, "span", 18);
636
674
  i0.ɵɵtext(25);
637
675
  i0.ɵɵelementEnd()();
638
- i0.ɵɵelementStart(26, "input", 102);
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); });
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()); });
676
+ i0.ɵɵelementStart(26, "input", 109);
677
+ i0.ɵɵtwoWayListener("ngModelChange", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_13_Template_input_ngModelChange_26_listener($event) { i0.ɵɵrestoreView(_r20); const ctx_r2 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r2.ThresholdSettings.SearchRelevance, $event) || (ctx_r2.ThresholdSettings.SearchRelevance = $event); return i0.ɵɵresetView($event); });
678
+ i0.ɵɵlistener("input", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_13_Template_input_input_26_listener() { i0.ɵɵrestoreView(_r20); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.OnSettingChanged()); });
641
679
  i0.ɵɵelementEnd()();
642
680
  i0.ɵɵelementStart(27, "div", 20)(28, "div", 21)(29, "span", 17);
643
681
  i0.ɵɵtext(30, "Autotag Confidence");
@@ -645,9 +683,9 @@ function KnowledgeConfigResourceComponent_Conditional_1_Conditional_13_Template(
645
683
  i0.ɵɵelementStart(31, "span", 18);
646
684
  i0.ɵɵtext(32);
647
685
  i0.ɵɵelementEnd()();
648
- i0.ɵɵelementStart(33, "input", 101);
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); });
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()); });
686
+ i0.ɵɵelementStart(33, "input", 108);
687
+ i0.ɵɵtwoWayListener("ngModelChange", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_13_Template_input_ngModelChange_33_listener($event) { i0.ɵɵrestoreView(_r20); const ctx_r2 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r2.ThresholdSettings.AutotagConfidence, $event) || (ctx_r2.ThresholdSettings.AutotagConfidence = $event); return i0.ɵɵresetView($event); });
688
+ i0.ɵɵlistener("input", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_13_Template_input_input_33_listener() { i0.ɵɵrestoreView(_r20); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.OnSettingChanged()); });
651
689
  i0.ɵɵelementEnd()()()();
652
690
  } if (rf & 2) {
653
691
  const ctx_r2 = i0.ɵɵnextContext(2);
@@ -670,35 +708,35 @@ function KnowledgeConfigResourceComponent_Conditional_1_Conditional_13_Template(
670
708
  } }
671
709
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_14_Template(rf, ctx) { if (rf & 1) {
672
710
  i0.ɵɵelementStart(0, "div", 9)(1, "h2", 12);
673
- i0.ɵɵelement(2, "i", 103);
711
+ i0.ɵɵelement(2, "i", 110);
674
712
  i0.ɵɵtext(3, " Scheduling");
675
713
  i0.ɵɵelementEnd();
676
714
  i0.ɵɵelementStart(4, "p", 13);
677
715
  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
716
  i0.ɵɵelementEnd();
679
- i0.ɵɵelementStart(6, "div", 104);
717
+ i0.ɵɵelementStart(6, "div", 111);
680
718
  i0.ɵɵelement(7, "app-scheduling-resource");
681
719
  i0.ɵɵelementEnd()();
682
720
  } }
683
721
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_15_Conditional_4_Template(rf, ctx) { if (rf & 1) {
684
- i0.ɵɵelement(0, "i", 73);
722
+ i0.ɵɵelement(0, "i", 80);
685
723
  i0.ɵɵtext(1, " Saving... ");
686
724
  } }
687
725
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_15_Conditional_5_Template(rf, ctx) { if (rf & 1) {
688
- i0.ɵɵelement(0, "i", 108);
726
+ i0.ɵɵelement(0, "i", 115);
689
727
  i0.ɵɵtext(1, " Save Changes ");
690
728
  } }
691
729
  function KnowledgeConfigResourceComponent_Conditional_1_Conditional_15_Template(rf, ctx) { if (rf & 1) {
692
- const _r19 = i0.ɵɵgetCurrentView();
693
- i0.ɵɵelementStart(0, "div", 10)(1, "span", 105);
730
+ const _r21 = i0.ɵɵgetCurrentView();
731
+ i0.ɵɵelementStart(0, "div", 10)(1, "span", 112);
694
732
  i0.ɵɵtext(2, "You have unsaved changes");
695
733
  i0.ɵɵelementEnd();
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()); });
734
+ i0.ɵɵelementStart(3, "button", 113);
735
+ i0.ɵɵlistener("click", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_15_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r21); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.SaveConfiguration()); });
698
736
  i0.ɵɵconditionalCreate(4, KnowledgeConfigResourceComponent_Conditional_1_Conditional_15_Conditional_4_Template, 2, 0)(5, KnowledgeConfigResourceComponent_Conditional_1_Conditional_15_Conditional_5_Template, 2, 0);
699
737
  i0.ɵɵelementEnd();
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()); });
738
+ i0.ɵɵelementStart(6, "button", 114);
739
+ i0.ɵɵlistener("click", function KnowledgeConfigResourceComponent_Conditional_1_Conditional_15_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r21); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.ResetConfiguration()); });
702
740
  i0.ɵɵtext(7, " Reset ");
703
741
  i0.ɵɵelementEnd()();
704
742
  } if (rf & 2) {
@@ -793,6 +831,9 @@ let KnowledgeConfigResourceComponent = class KnowledgeConfigResourceComponent ex
793
831
  EmbeddingModels = [];
794
832
  get HasEmbeddingModel() { return this.EmbeddingModels.length > 0; }
795
833
  get EmbeddingModelName() { return this.EmbeddingModels.length > 0 ? this.EmbeddingModels[0].Name : ''; }
834
+ // --- Credentials (for vector DB provider binding) ---
835
+ AvailableCredentials = [];
836
+ IsSavingCredential = false;
796
837
  // --- Entity Documents (for persisting thresholds) ---
797
838
  entityDocuments = [];
798
839
  // --- Setup Progress ---
@@ -836,6 +877,7 @@ let KnowledgeConfigResourceComponent = class KnowledgeConfigResourceComponent ex
836
877
  this.NotifyLoadComplete();
837
878
  }
838
879
  ngOnDestroy() {
880
+ super.ngOnDestroy();
839
881
  this.destroy$.next();
840
882
  this.destroy$.complete();
841
883
  }
@@ -962,6 +1004,42 @@ let KnowledgeConfigResourceComponent = class KnowledgeConfigResourceComponent ex
962
1004
  MJNotificationService.Instance.CreateSimpleNotification(`Error: ${msg}`, 'error', 5000);
963
1005
  }
964
1006
  }
1007
+ /** Update the credential linked to a vector database provider */
1008
+ async SaveProviderCredential(provider) {
1009
+ this.IsSavingCredential = true;
1010
+ this.cdr.detectChanges();
1011
+ try {
1012
+ const md = new Metadata();
1013
+ const entity = await md.GetEntityObject('MJ: Vector Databases');
1014
+ const loaded = await entity.Load(provider.ID);
1015
+ if (!loaded) {
1016
+ MJNotificationService.Instance.CreateSimpleNotification(`Could not load vector database "${provider.Name}"`, 'error', 3000);
1017
+ return;
1018
+ }
1019
+ entity.CredentialID = provider.CredentialID || null;
1020
+ const saved = await entity.Save();
1021
+ if (saved) {
1022
+ provider.CredentialName = this.AvailableCredentials.find(c => UUIDsEqual(c.ID, provider.CredentialID))?.Name ?? null;
1023
+ MJNotificationService.Instance.CreateSimpleNotification(provider.CredentialID
1024
+ ? `Credential linked to "${provider.Name}"`
1025
+ : `Credential removed from "${provider.Name}"`, 'success', 2000);
1026
+ }
1027
+ else {
1028
+ const msg = entity.LatestResult?.CompleteMessage ?? 'Unknown error';
1029
+ console.error('[KnowledgeConfig] Save credential failed:', msg);
1030
+ MJNotificationService.Instance.CreateSimpleNotification(`Save failed: ${msg}`, 'error', 5000);
1031
+ }
1032
+ }
1033
+ catch (error) {
1034
+ const msg = error instanceof Error ? error.message : String(error);
1035
+ console.error('[KnowledgeConfig] Error saving credential:', msg);
1036
+ MJNotificationService.Instance.CreateSimpleNotification(`Error: ${msg}`, 'error', 5000);
1037
+ }
1038
+ finally {
1039
+ this.IsSavingCredential = false;
1040
+ this.cdr.detectChanges();
1041
+ }
1042
+ }
965
1043
  // ================================================================
966
1044
  // Private Methods
967
1045
  // ================================================================
@@ -975,13 +1053,15 @@ let KnowledgeConfigResourceComponent = class KnowledgeConfigResourceComponent ex
975
1053
  this.loadVectorDBProvidersFromEngine(AIEngineBase.Instance.VectorDatabases);
976
1054
  this.loadVectorIndexesFromEngine(engine.VectorIndexes);
977
1055
  this.loadEntityDocumentsAndThresholds(engine.GetActiveEntityDocuments());
978
- // AI Models come from a different domain — fetch via RunView
1056
+ // AI Models and Credentials come from different domains — fetch via RunView
979
1057
  const rv = new RunView();
980
- const modelsResult = await rv.RunView({
981
- EntityName: 'MJ: AI Models',
982
- ResultType: 'simple'
983
- });
1058
+ const [modelsResult, credentialsResult] = await rv.RunViews([
1059
+ { EntityName: 'MJ: AI Models', ResultType: 'simple' },
1060
+ { EntityName: 'MJ: Credentials', ExtraFilter: 'IsActive = 1', Fields: ['ID', 'Name'], ResultType: 'simple' }
1061
+ ]);
984
1062
  this.loadEmbeddingModels(modelsResult.Success ? modelsResult.Results : []);
1063
+ this.AvailableCredentials = (credentialsResult.Success ? credentialsResult.Results : [])
1064
+ .map((c) => ({ ID: String(c['ID']), Name: String(c['Name']) }));
985
1065
  }
986
1066
  catch (error) {
987
1067
  console.error('[KnowledgeConfig] Error loading configuration:', error);
@@ -1038,7 +1118,9 @@ let KnowledgeConfigResourceComponent = class KnowledgeConfigResourceComponent ex
1038
1118
  ID: db.ID,
1039
1119
  Name: db.Name,
1040
1120
  ClassKey: db.ClassKey || '',
1041
- Description: db.Description || ''
1121
+ Description: db.Description || '',
1122
+ CredentialID: db.CredentialID,
1123
+ CredentialName: db.Credential ?? null
1042
1124
  }));
1043
1125
  }
1044
1126
  loadVectorIndexesFromEngine(indexes) {
@@ -1087,11 +1169,11 @@ let KnowledgeConfigResourceComponent = class KnowledgeConfigResourceComponent ex
1087
1169
  }));
1088
1170
  }
1089
1171
  static ɵfac = /*@__PURE__*/ (() => { let ɵKnowledgeConfigResourceComponent_BaseFactory; return function KnowledgeConfigResourceComponent_Factory(__ngFactoryType__) { return (ɵKnowledgeConfigResourceComponent_BaseFactory || (ɵKnowledgeConfigResourceComponent_BaseFactory = i0.ɵɵgetInheritedFactory(KnowledgeConfigResourceComponent)))(__ngFactoryType__ || KnowledgeConfigResourceComponent); }; })();
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) {
1172
+ 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, "provider-credential-row"], [1, "provider-credential-label"], [1, "fa-solid", "fa-key"], [1, "provider-credential-picker"], [1, "provider-credential-select", 3, "ngModelChange", "change", "ngModel", "disabled"], [3, "ngValue"], [1, "fa-solid", "fa-spinner", "fa-spin", "provider-credential-spinner"], [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
1173
  i0.ɵɵconditionalCreate(0, KnowledgeConfigResourceComponent_Conditional_0_Template, 2, 0, "div", 0)(1, KnowledgeConfigResourceComponent_Conditional_1_Template, 16, 7, "div", 1);
1092
1174
  } if (rf & 2) {
1093
1175
  i0.ɵɵconditional(ctx.IsLoading ? 0 : 1);
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}"] });
1176
+ } }, 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.provider-credential-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.5rem 1rem 0.75rem;\n margin-top: -0.25rem;\n}\n\n.provider-credential-label[_ngcontent-%COMP%] {\n font-size: 0.8rem;\n font-weight: 500;\n color: var(--mj-text-secondary);\n white-space: nowrap;\n display: flex;\n align-items: center;\n gap: 0.4rem;\n}\n\n.provider-credential-label[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n color: var(--mj-text-muted);\n}\n\n.provider-credential-picker[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n flex: 1;\n min-width: 0;\n}\n\n.provider-credential-select[_ngcontent-%COMP%] {\n flex: 1;\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.8rem;\n}\n\n.provider-credential-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.provider-credential-spinner[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 0.85rem;\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}"] });
1095
1177
  };
1096
1178
  KnowledgeConfigResourceComponent = __decorate([
1097
1179
  RegisterClass(BaseResourceComponent, 'KnowledgeConfigResource')
@@ -1099,9 +1181,9 @@ KnowledgeConfigResourceComponent = __decorate([
1099
1181
  export { KnowledgeConfigResourceComponent };
1100
1182
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(KnowledgeConfigResourceComponent, [{
1101
1183
  type: Component,
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"] }]
1184
+ 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 <div class=\"provider-credential-row\">\n <label class=\"provider-credential-label\">\n <i class=\"fa-solid fa-key\"></i> API Credential\n </label>\n <div class=\"provider-credential-picker\">\n <select class=\"provider-credential-select\"\n [(ngModel)]=\"provider.CredentialID\"\n (change)=\"SaveProviderCredential(provider)\"\n [disabled]=\"IsSavingCredential\">\n <option [ngValue]=\"null\">None (use environment variable)</option>\n @for (cred of AvailableCredentials; track cred.ID) {\n <option [ngValue]=\"cred.ID\">{{ cred.Name }}</option>\n }\n </select>\n @if (IsSavingCredential) {\n <i class=\"fa-solid fa-spinner fa-spin provider-credential-spinner\"></i>\n }\n </div>\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/* ---- Provider Credential Row ---- */\n\n.provider-credential-row {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.5rem 1rem 0.75rem;\n margin-top: -0.25rem;\n}\n\n.provider-credential-label {\n font-size: 0.8rem;\n font-weight: 500;\n color: var(--mj-text-secondary);\n white-space: nowrap;\n display: flex;\n align-items: center;\n gap: 0.4rem;\n}\n\n.provider-credential-label i {\n font-size: 0.75rem;\n color: var(--mj-text-muted);\n}\n\n.provider-credential-picker {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n flex: 1;\n min-width: 0;\n}\n\n.provider-credential-select {\n flex: 1;\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.8rem;\n}\n\n.provider-credential-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.provider-credential-spinner {\n color: var(--mj-brand-primary);\n font-size: 0.85rem;\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"] }]
1103
1185
  }], null, null); })();
1104
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(KnowledgeConfigResourceComponent, { className: "KnowledgeConfigResourceComponent", filePath: "src/KnowledgeHub/components/config/knowledge-config-resource.component.ts", lineNumber: 82 }); })();
1186
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(KnowledgeConfigResourceComponent, { className: "KnowledgeConfigResourceComponent", filePath: "src/KnowledgeHub/components/config/knowledge-config-resource.component.ts", lineNumber: 84 }); })();
1105
1187
  /** Tree-shaking prevention */
1106
1188
  export function LoadKnowledgeConfigResource() {
1107
1189
  // Prevents tree-shaking