@memberjunction/ng-dashboards 5.23.0 → 5.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts +677 -5
  2. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.d.ts.map +1 -1
  3. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js +6879 -1873
  4. package/dist/AI/components/autotagging/autotagging-pipeline-resource.component.js.map +1 -1
  5. package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts +46 -1
  6. package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts.map +1 -1
  7. package/dist/AI/components/duplicates/duplicate-detection-resource.component.js +758 -491
  8. package/dist/AI/components/duplicates/duplicate-detection-resource.component.js.map +1 -1
  9. package/dist/AI/components/vectors/vector-management-resource.component.d.ts +19 -0
  10. package/dist/AI/components/vectors/vector-management-resource.component.d.ts.map +1 -1
  11. package/dist/AI/components/vectors/vector-management-resource.component.js +410 -208
  12. package/dist/AI/components/vectors/vector-management-resource.component.js.map +1 -1
  13. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
  14. package/dist/DataExplorer/data-explorer-dashboard.component.js +17 -17
  15. package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
  16. package/dist/Integration/components/activity/activity.component.d.ts.map +1 -1
  17. package/dist/Integration/components/activity/activity.component.js +1 -0
  18. package/dist/Integration/components/activity/activity.component.js.map +1 -1
  19. package/dist/Integration/components/connections/connections.component.d.ts.map +1 -1
  20. package/dist/Integration/components/connections/connections.component.js +1 -0
  21. package/dist/Integration/components/connections/connections.component.js.map +1 -1
  22. package/dist/Integration/components/mapping-workspace/mapping-workspace.component.d.ts.map +1 -1
  23. package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js +1 -0
  24. package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js.map +1 -1
  25. package/dist/Integration/components/overview/overview.component.d.ts.map +1 -1
  26. package/dist/Integration/components/overview/overview.component.js +1 -0
  27. package/dist/Integration/components/overview/overview.component.js.map +1 -1
  28. package/dist/Integration/components/pipelines/pipelines.component.d.ts.map +1 -1
  29. package/dist/Integration/components/pipelines/pipelines.component.js +1 -0
  30. package/dist/Integration/components/pipelines/pipelines.component.js.map +1 -1
  31. package/dist/Integration/components/schedules/schedules.component.d.ts.map +1 -1
  32. package/dist/Integration/components/schedules/schedules.component.js +1 -0
  33. package/dist/Integration/components/schedules/schedules.component.js.map +1 -1
  34. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.d.ts +411 -0
  35. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.d.ts.map +1 -0
  36. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js +4266 -0
  37. package/dist/KnowledgeHub/components/analytics/analytics-resource.component.js.map +1 -0
  38. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.d.ts +35 -1
  39. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.d.ts.map +1 -1
  40. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js +186 -13
  41. package/dist/KnowledgeHub/components/clusters/cluster-visualization-resource.component.js.map +1 -1
  42. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.d.ts +1 -0
  43. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.d.ts.map +1 -1
  44. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js +188 -165
  45. package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js.map +1 -1
  46. package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.d.ts +75 -0
  47. package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.d.ts.map +1 -0
  48. package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.js +601 -0
  49. package/dist/KnowledgeHub/components/scheduling/scheduling-resource.component.js.map +1 -0
  50. package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.d.ts +93 -12
  51. package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.d.ts.map +1 -1
  52. package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.js +637 -107
  53. package/dist/KnowledgeHub/components/search/knowledge-search-resource.component.js.map +1 -1
  54. package/dist/KnowledgeHub/index.d.ts +2 -0
  55. package/dist/KnowledgeHub/index.d.ts.map +1 -1
  56. package/dist/KnowledgeHub/index.js +2 -0
  57. package/dist/KnowledgeHub/index.js.map +1 -1
  58. package/dist/__tests__/analytics-resource.test.d.ts +2 -0
  59. package/dist/__tests__/analytics-resource.test.d.ts.map +1 -0
  60. package/dist/__tests__/analytics-resource.test.js +181 -0
  61. package/dist/__tests__/analytics-resource.test.js.map +1 -0
  62. package/dist/__tests__/scheduling.test.d.ts +2 -0
  63. package/dist/__tests__/scheduling.test.d.ts.map +1 -0
  64. package/dist/__tests__/scheduling.test.js +205 -0
  65. package/dist/__tests__/scheduling.test.js.map +1 -0
  66. package/dist/ai-dashboards.module.d.ts +18 -14
  67. package/dist/ai-dashboards.module.d.ts.map +1 -1
  68. package/dist/ai-dashboards.module.js +25 -5
  69. package/dist/ai-dashboards.module.js.map +1 -1
  70. package/dist/public-api.d.ts +1 -0
  71. package/dist/public-api.d.ts.map +1 -1
  72. package/dist/public-api.js +1 -0
  73. package/dist/public-api.js.map +1 -1
  74. package/dist/shared/entity-field-display.d.ts +44 -0
  75. package/dist/shared/entity-field-display.d.ts.map +1 -0
  76. package/dist/shared/entity-field-display.js +118 -0
  77. package/dist/shared/entity-field-display.js.map +1 -0
  78. package/package.json +47 -46
@@ -4,6 +4,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
4
4
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
+ var KnowledgeSearchResourceComponent_1;
7
8
  /**
8
9
  * @fileoverview Knowledge Hub Search Dashboard (Task 2)
9
10
  *
@@ -14,8 +15,9 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
14
15
  import { Component, ChangeDetectorRef, inject, Injector } from '@angular/core';
15
16
  import { Subject } from 'rxjs';
16
17
  import { takeUntil } from 'rxjs/operators';
17
- import { CompositeKey, Metadata } from '@memberjunction/core';
18
- import { RegisterClass } from '@memberjunction/global';
18
+ import { CompositeKey, Metadata, RunView } from '@memberjunction/core';
19
+ import { UserInfoEngine } from '@memberjunction/core-entities';
20
+ import { RegisterClass, UUIDsEqual } from '@memberjunction/global';
19
21
  import { BaseResourceComponent, NavigationService } from '@memberjunction/ng-shared';
20
22
  import { SearchService } from '@memberjunction/ng-search';
21
23
  import { ConversationBridgeService } from '@memberjunction/ng-conversations';
@@ -24,169 +26,260 @@ import * as i1 from "@angular/forms";
24
26
  import * as i2 from "@memberjunction/ng-search";
25
27
  import * as i3 from "../results-detail/search-result-detail.component";
26
28
  import * as i4 from "@angular/common";
27
- const _forTrack0 = ($index, $item) => $item.Query;
29
+ const _forTrack0 = ($index, $item) => $item.Name;
30
+ const _forTrack1 = ($index, $item) => $item.ID;
31
+ const _forTrack2 = ($index, $item) => $item.Query;
28
32
  function KnowledgeSearchResourceComponent_Conditional_0_Conditional_2_Template(rf, ctx) { if (rf & 1) {
29
- i0.ɵɵelementStart(0, "div", 14);
30
- i0.ɵɵelement(1, "i", 15);
33
+ i0.ɵɵelementStart(0, "div", 13);
34
+ i0.ɵɵelement(1, "i", 14);
31
35
  i0.ɵɵtext(2, " Knowledge Hub ");
32
36
  i0.ɵɵelementEnd();
33
- i0.ɵɵelementStart(3, "p", 16);
37
+ i0.ɵɵelementStart(3, "p", 15);
34
38
  i0.ɵɵtext(4, "Search across all your knowledge -- entities, documents, content, and more");
35
39
  i0.ɵɵelementEnd();
36
40
  } }
37
41
  function KnowledgeSearchResourceComponent_Conditional_0_Conditional_7_Template(rf, ctx) { if (rf & 1) {
38
42
  const _r3 = i0.ɵɵgetCurrentView();
39
- i0.ɵɵelementStart(0, "button", 17);
43
+ i0.ɵɵelementStart(0, "button", 16);
40
44
  i0.ɵɵlistener("click", function KnowledgeSearchResourceComponent_Conditional_0_Conditional_7_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.ClearSearch()); });
41
- i0.ɵɵelement(1, "i", 18);
45
+ i0.ɵɵelement(1, "i", 17);
42
46
  i0.ɵɵelementEnd();
43
47
  } }
44
48
  function KnowledgeSearchResourceComponent_Conditional_0_Conditional_9_Template(rf, ctx) { if (rf & 1) {
45
- i0.ɵɵelement(0, "i", 10);
49
+ i0.ɵɵelement(0, "i", 9);
46
50
  } }
47
51
  function KnowledgeSearchResourceComponent_Conditional_0_Conditional_10_Template(rf, ctx) { if (rf & 1) {
48
52
  i0.ɵɵtext(0, " Search ");
49
53
  } }
54
+ function KnowledgeSearchResourceComponent_Conditional_0_Conditional_11_Conditional_4_For_5_Template(rf, ctx) { if (rf & 1) {
55
+ const _r5 = i0.ɵɵgetCurrentView();
56
+ i0.ɵɵelementStart(0, "button", 25);
57
+ i0.ɵɵlistener("click", function KnowledgeSearchResourceComponent_Conditional_0_Conditional_11_Conditional_4_For_5_Template_button_click_0_listener() { const tag_r6 = i0.ɵɵrestoreView(_r5).$implicit; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.FilterByTag(tag_r6.Name)); });
58
+ i0.ɵɵtext(1);
59
+ i0.ɵɵelementEnd();
60
+ } if (rf & 2) {
61
+ const tag_r6 = ctx.$implicit;
62
+ i0.ɵɵstyleProp("font-size", tag_r6.FontSize, "rem");
63
+ i0.ɵɵproperty("title", tag_r6.Name + " (" + tag_r6.Count + ")");
64
+ i0.ɵɵadvance();
65
+ i0.ɵɵtextInterpolate1(" ", tag_r6.Name, " ");
66
+ } }
67
+ function KnowledgeSearchResourceComponent_Conditional_0_Conditional_11_Conditional_4_Template(rf, ctx) { if (rf & 1) {
68
+ i0.ɵɵelementStart(0, "div", 21)(1, "span", 22);
69
+ i0.ɵɵelement(2, "i", 23);
70
+ i0.ɵɵtext(3, " Popular tags: ");
71
+ i0.ɵɵelementEnd();
72
+ i0.ɵɵrepeaterCreate(4, KnowledgeSearchResourceComponent_Conditional_0_Conditional_11_Conditional_4_For_5_Template, 2, 4, "button", 24, _forTrack0);
73
+ i0.ɵɵelementEnd();
74
+ } if (rf & 2) {
75
+ const ctx_r1 = i0.ɵɵnextContext(3);
76
+ i0.ɵɵadvance(4);
77
+ i0.ɵɵrepeater(ctx_r1.PopularTags);
78
+ } }
50
79
  function KnowledgeSearchResourceComponent_Conditional_0_Conditional_11_Template(rf, ctx) { if (rf & 1) {
51
80
  const _r4 = i0.ɵɵgetCurrentView();
52
- i0.ɵɵelementStart(0, "div", 11)(1, "button", 19);
81
+ i0.ɵɵelementStart(0, "div", 18)(1, "button", 19);
53
82
  i0.ɵɵlistener("click", function KnowledgeSearchResourceComponent_Conditional_0_Conditional_11_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnAskAgent()); });
54
83
  i0.ɵɵelement(2, "i", 20);
55
84
  i0.ɵɵtext(3, " Ask Knowledge Agent ");
56
85
  i0.ɵɵelementEnd()();
86
+ i0.ɵɵconditionalCreate(4, KnowledgeSearchResourceComponent_Conditional_0_Conditional_11_Conditional_4_Template, 6, 0, "div", 21);
87
+ } if (rf & 2) {
88
+ const ctx_r1 = i0.ɵɵnextContext(2);
89
+ i0.ɵɵadvance(4);
90
+ i0.ɵɵconditional(ctx_r1.PopularTags.length > 0 ? 4 : -1);
57
91
  } }
58
92
  function KnowledgeSearchResourceComponent_Conditional_0_Conditional_12_Conditional_1_Template(rf, ctx) { if (rf & 1) {
59
- const _r6 = i0.ɵɵgetCurrentView();
60
- i0.ɵɵelementStart(0, "aside", 21)(1, "mj-search-filter", 30);
61
- i0.ɵɵlistener("FilterChanged", function KnowledgeSearchResourceComponent_Conditional_0_Conditional_12_Conditional_1_Template_mj_search_filter_FilterChanged_1_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnFilterChanged($event)); })("FiltersCleared", function KnowledgeSearchResourceComponent_Conditional_0_Conditional_12_Conditional_1_Template_mj_search_filter_FiltersCleared_1_listener() { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnFiltersCleared()); });
93
+ const _r8 = i0.ɵɵgetCurrentView();
94
+ i0.ɵɵelementStart(0, "aside", 26)(1, "mj-search-filter", 36);
95
+ i0.ɵɵlistener("FilterChanged", function KnowledgeSearchResourceComponent_Conditional_0_Conditional_12_Conditional_1_Template_mj_search_filter_FilterChanged_1_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnFilterChanged($event)); })("FiltersCleared", function KnowledgeSearchResourceComponent_Conditional_0_Conditional_12_Conditional_1_Template_mj_search_filter_FiltersCleared_1_listener() { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnFiltersCleared()); })("CloseRequested", function KnowledgeSearchResourceComponent_Conditional_0_Conditional_12_Conditional_1_Template_mj_search_filter_CloseRequested_1_listener() { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.ToggleFilters()); });
62
96
  i0.ɵɵelementEnd();
63
- i0.ɵɵelementStart(2, "div", 31)(3, "label", 32);
97
+ i0.ɵɵelementStart(2, "div", 37)(3, "label", 38);
64
98
  i0.ɵɵtext(4, " Min Relevance ");
65
- i0.ɵɵelementStart(5, "span", 33);
99
+ i0.ɵɵelementStart(5, "span", 39);
66
100
  i0.ɵɵtext(6);
67
101
  i0.ɵɵpipe(7, "number");
68
102
  i0.ɵɵelementEnd()();
69
- i0.ɵɵelementStart(8, "input", 34);
70
- i0.ɵɵlistener("input", function KnowledgeSearchResourceComponent_Conditional_0_Conditional_12_Conditional_1_Template_input_input_8_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnThresholdChanged($event.target.value / 100)); });
103
+ i0.ɵɵelementStart(8, "input", 40);
104
+ i0.ɵɵlistener("input", function KnowledgeSearchResourceComponent_Conditional_0_Conditional_12_Conditional_1_Template_input_input_8_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnThresholdChanged($event.target.value / 100)); });
71
105
  i0.ɵɵelementEnd();
72
- i0.ɵɵelementStart(9, "div", 35)(10, "span");
106
+ i0.ɵɵelementStart(9, "div", 41)(10, "span");
73
107
  i0.ɵɵtext(11, "All");
74
108
  i0.ɵɵelementEnd();
75
109
  i0.ɵɵelementStart(12, "span");
76
110
  i0.ɵɵtext(13, "Strict");
111
+ i0.ɵɵelementEnd()();
112
+ i0.ɵɵelementStart(14, "div", 42)(15, "span", 43);
113
+ i0.ɵɵtext(16);
114
+ i0.ɵɵelementEnd();
115
+ i0.ɵɵelementStart(17, "span", 44);
116
+ i0.ɵɵtext(18);
117
+ i0.ɵɵpipe(19, "number");
77
118
  i0.ɵɵelementEnd()()()();
78
119
  } if (rf & 2) {
79
120
  const ctx_r1 = i0.ɵɵnextContext(3);
80
121
  i0.ɵɵadvance();
81
122
  i0.ɵɵproperty("Filters", ctx_r1.Filters)("ActiveFilters", ctx_r1.ActiveFilters);
82
123
  i0.ɵɵadvance(5);
83
- i0.ɵɵtextInterpolate1("", i0.ɵɵpipeBind2(7, 7, ctx_r1.MinScoreThreshold * 100, "1.0-0"), "%");
124
+ i0.ɵɵtextInterpolate1("", i0.ɵɵpipeBind2(7, 10, ctx_r1.MinScoreThreshold * 100, "1.0-0"), "%");
84
125
  i0.ɵɵadvance(2);
85
126
  i0.ɵɵproperty("min", 0)("max", 100)("step", 5)("value", ctx_r1.MinScoreThreshold * 100);
127
+ i0.ɵɵadvance(8);
128
+ i0.ɵɵtextInterpolate2("", ctx_r1.TotalCount, " of ", ctx_r1.ServerResultCount, " results shown");
129
+ i0.ɵɵadvance(2);
130
+ i0.ɵɵtextInterpolate1("Server range: ", i0.ɵɵpipeBind2(19, 13, ctx_r1.ServerMinRelevance * 100, "1.0-0"), "%\u2013100%");
86
131
  } }
87
- function KnowledgeSearchResourceComponent_Conditional_0_Conditional_12_Conditional_6_Template(rf, ctx) { if (rf & 1) {
88
- i0.ɵɵelementStart(0, "span", 25);
132
+ function KnowledgeSearchResourceComponent_Conditional_0_Conditional_12_Conditional_4_Conditional_3_Template(rf, ctx) { if (rf & 1) {
133
+ i0.ɵɵelementStart(0, "span", 47);
89
134
  i0.ɵɵtext(1);
90
135
  i0.ɵɵelementEnd();
91
136
  } if (rf & 2) {
92
- const ctx_r1 = i0.ɵɵnextContext(3);
137
+ const ctx_r1 = i0.ɵɵnextContext(4);
93
138
  i0.ɵɵadvance();
94
- i0.ɵɵtextInterpolate1("in ", ctx_r1.ElapsedMs, "ms");
95
- } }
96
- function KnowledgeSearchResourceComponent_Conditional_0_Conditional_12_Conditional_8_Conditional_2_Template(rf, ctx) { if (rf & 1) {
97
- i0.ɵɵtext(0, " Filters Active ");
139
+ i0.ɵɵtextInterpolate(ctx_r1.GetActiveFilterCount());
98
140
  } }
99
- function KnowledgeSearchResourceComponent_Conditional_0_Conditional_12_Conditional_8_Conditional_3_Template(rf, ctx) { if (rf & 1) {
100
- i0.ɵɵtext(0, " Filters ");
141
+ function KnowledgeSearchResourceComponent_Conditional_0_Conditional_12_Conditional_4_Template(rf, ctx) { if (rf & 1) {
142
+ const _r9 = i0.ɵɵgetCurrentView();
143
+ i0.ɵɵelementStart(0, "button", 45);
144
+ i0.ɵɵlistener("click", function KnowledgeSearchResourceComponent_Conditional_0_Conditional_12_Conditional_4_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.ToggleFilters()); });
145
+ i0.ɵɵelement(1, "i", 46);
146
+ i0.ɵɵtext(2, " Filters ");
147
+ i0.ɵɵconditionalCreate(3, KnowledgeSearchResourceComponent_Conditional_0_Conditional_12_Conditional_4_Conditional_3_Template, 2, 1, "span", 47);
148
+ i0.ɵɵelementEnd();
149
+ } if (rf & 2) {
150
+ const ctx_r1 = i0.ɵɵnextContext(3);
151
+ i0.ɵɵadvance(3);
152
+ i0.ɵɵconditional(ctx_r1.HasActiveFilters() ? 3 : -1);
101
153
  } }
102
- function KnowledgeSearchResourceComponent_Conditional_0_Conditional_12_Conditional_8_Template(rf, ctx) { if (rf & 1) {
103
- const _r7 = i0.ɵɵgetCurrentView();
104
- i0.ɵɵelementStart(0, "button", 36);
105
- i0.ɵɵlistener("click", function KnowledgeSearchResourceComponent_Conditional_0_Conditional_12_Conditional_8_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.ToggleFilters()); });
106
- i0.ɵɵelement(1, "i", 37);
107
- i0.ɵɵconditionalCreate(2, KnowledgeSearchResourceComponent_Conditional_0_Conditional_12_Conditional_8_Conditional_2_Template, 1, 0)(3, KnowledgeSearchResourceComponent_Conditional_0_Conditional_12_Conditional_8_Conditional_3_Template, 1, 0);
154
+ function KnowledgeSearchResourceComponent_Conditional_0_Conditional_12_Conditional_7_Template(rf, ctx) { if (rf & 1) {
155
+ i0.ɵɵelementStart(0, "span", 31);
156
+ i0.ɵɵtext(1);
108
157
  i0.ɵɵelementEnd();
109
158
  } if (rf & 2) {
110
159
  const ctx_r1 = i0.ɵɵnextContext(3);
111
- i0.ɵɵadvance(2);
112
- i0.ɵɵconditional(ctx_r1.HasActiveFilters() ? 2 : 3);
160
+ i0.ɵɵadvance();
161
+ i0.ɵɵtextInterpolate1("in ", ctx_r1.ElapsedMs, "ms");
113
162
  } }
114
- function KnowledgeSearchResourceComponent_Conditional_0_Conditional_12_Conditional_10_Template(rf, ctx) { if (rf & 1) {
115
- const _r8 = i0.ɵɵgetCurrentView();
116
- i0.ɵɵelementStart(0, "div", 29);
117
- i0.ɵɵelement(1, "i", 38);
118
- i0.ɵɵelementStart(2, "div", 39)(3, "strong");
163
+ function KnowledgeSearchResourceComponent_Conditional_0_Conditional_12_Conditional_12_Template(rf, ctx) { if (rf & 1) {
164
+ const _r10 = i0.ɵɵgetCurrentView();
165
+ i0.ɵɵelementStart(0, "div", 35);
166
+ i0.ɵɵelement(1, "i", 48);
167
+ i0.ɵɵelementStart(2, "div", 49)(3, "strong");
119
168
  i0.ɵɵtext(4, "Can't find what you're looking for?");
120
169
  i0.ɵɵelementEnd();
121
170
  i0.ɵɵelementStart(5, "p");
122
171
  i0.ɵɵtext(6, "Ask the Knowledge Agent for a deeper analysis");
123
172
  i0.ɵɵelementEnd()();
124
- i0.ɵɵelementStart(7, "button", 40);
125
- i0.ɵɵlistener("click", function KnowledgeSearchResourceComponent_Conditional_0_Conditional_12_Conditional_10_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnAskAgent()); });
173
+ i0.ɵɵelementStart(7, "button", 50);
174
+ i0.ɵɵlistener("click", function KnowledgeSearchResourceComponent_Conditional_0_Conditional_12_Conditional_12_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnAskAgent()); });
126
175
  i0.ɵɵtext(8, " Ask Agent ");
127
176
  i0.ɵɵelementEnd()();
128
177
  } }
129
178
  function KnowledgeSearchResourceComponent_Conditional_0_Conditional_12_Template(rf, ctx) { if (rf & 1) {
130
- const _r5 = i0.ɵɵgetCurrentView();
131
- i0.ɵɵelementStart(0, "div", 12);
132
- i0.ɵɵconditionalCreate(1, KnowledgeSearchResourceComponent_Conditional_0_Conditional_12_Conditional_1_Template, 14, 10, "aside", 21);
133
- i0.ɵɵelementStart(2, "div", 22)(3, "div", 23)(4, "span", 24);
134
- i0.ɵɵtext(5);
135
- i0.ɵɵconditionalCreate(6, KnowledgeSearchResourceComponent_Conditional_0_Conditional_12_Conditional_6_Template, 2, 1, "span", 25);
179
+ const _r7 = i0.ɵɵgetCurrentView();
180
+ i0.ɵɵelementStart(0, "div", 10);
181
+ i0.ɵɵconditionalCreate(1, KnowledgeSearchResourceComponent_Conditional_0_Conditional_12_Conditional_1_Template, 20, 16, "aside", 26);
182
+ i0.ɵɵelementStart(2, "div", 27)(3, "div", 28);
183
+ i0.ɵɵconditionalCreate(4, KnowledgeSearchResourceComponent_Conditional_0_Conditional_12_Conditional_4_Template, 4, 1, "button", 29);
184
+ i0.ɵɵelementStart(5, "span", 30);
185
+ i0.ɵɵtext(6);
186
+ i0.ɵɵconditionalCreate(7, KnowledgeSearchResourceComponent_Conditional_0_Conditional_12_Conditional_7_Template, 2, 1, "span", 31);
136
187
  i0.ɵɵelementEnd();
137
- i0.ɵɵelementStart(7, "div", 26);
138
- i0.ɵɵconditionalCreate(8, KnowledgeSearchResourceComponent_Conditional_0_Conditional_12_Conditional_8_Template, 4, 1, "button", 27);
188
+ i0.ɵɵelementStart(8, "button", 32);
189
+ i0.ɵɵlistener("click", function KnowledgeSearchResourceComponent_Conditional_0_Conditional_12_Template_button_click_8_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OpenSaveDialog()); });
190
+ i0.ɵɵelement(9, "i", 33);
191
+ i0.ɵɵtext(10, " Save Search ");
139
192
  i0.ɵɵelementEnd()();
140
- i0.ɵɵelementStart(9, "mj-search-results", 28);
141
- i0.ɵɵlistener("ResultSelected", function KnowledgeSearchResourceComponent_Conditional_0_Conditional_12_Template_mj_search_results_ResultSelected_9_listener($event) { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnResultSelected($event)); })("OpenRecordRequested", function KnowledgeSearchResourceComponent_Conditional_0_Conditional_12_Template_mj_search_results_OpenRecordRequested_9_listener($event) { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnOpenRecord($event)); });
193
+ i0.ɵɵelementStart(11, "mj-search-results", 34);
194
+ i0.ɵɵlistener("ResultSelected", function KnowledgeSearchResourceComponent_Conditional_0_Conditional_12_Template_mj_search_results_ResultSelected_11_listener($event) { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnResultSelected($event)); })("OpenRecordRequested", function KnowledgeSearchResourceComponent_Conditional_0_Conditional_12_Template_mj_search_results_OpenRecordRequested_11_listener($event) { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnOpenRecord($event)); })("MoreLikeThisRequested", function KnowledgeSearchResourceComponent_Conditional_0_Conditional_12_Template_mj_search_results_MoreLikeThisRequested_11_listener($event) { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnMoreLikeThis($event)); });
142
195
  i0.ɵɵelementEnd();
143
- i0.ɵɵconditionalCreate(10, KnowledgeSearchResourceComponent_Conditional_0_Conditional_12_Conditional_10_Template, 9, 0, "div", 29);
196
+ i0.ɵɵconditionalCreate(12, KnowledgeSearchResourceComponent_Conditional_0_Conditional_12_Conditional_12_Template, 9, 0, "div", 35);
144
197
  i0.ɵɵelementEnd()();
145
198
  } if (rf & 2) {
146
199
  const ctx_r1 = i0.ɵɵnextContext(2);
147
200
  i0.ɵɵadvance();
148
201
  i0.ɵɵconditional(ctx_r1.ShowFilters && ctx_r1.Filters.length > 0 ? 1 : -1);
149
- i0.ɵɵadvance(4);
150
- i0.ɵɵtextInterpolate1(" ", ctx_r1.TotalCount, " results ");
151
- i0.ɵɵadvance();
152
- i0.ɵɵconditional(ctx_r1.ElapsedMs > 0 ? 6 : -1);
202
+ i0.ɵɵadvance(3);
203
+ i0.ɵɵconditional(!ctx_r1.ShowFilters && ctx_r1.Filters.length > 0 ? 4 : -1);
153
204
  i0.ɵɵadvance(2);
154
- i0.ɵɵconditional(ctx_r1.Filters.length > 0 ? 8 : -1);
205
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.TotalCount, " results ");
155
206
  i0.ɵɵadvance();
156
- i0.ɵɵproperty("ResultGroups", ctx_r1.ResultGroups)("IsLoading", ctx_r1.IsSearching)("TotalCount", ctx_r1.TotalCount)("ElapsedMs", ctx_r1.ElapsedMs);
207
+ i0.ɵɵconditional(ctx_r1.ElapsedMs > 0 ? 7 : -1);
208
+ i0.ɵɵadvance(4);
209
+ i0.ɵɵproperty("ShowSummary", false)("FlatResults", ctx_r1.AllResults)("ResultGroups", ctx_r1.ResultGroups)("IsLoading", ctx_r1.IsSearching)("TotalCount", ctx_r1.TotalCount)("ElapsedMs", ctx_r1.ElapsedMs);
157
210
  i0.ɵɵadvance();
158
- i0.ɵɵconditional(ctx_r1.TotalCount === 0 && !ctx_r1.IsSearching ? 10 : -1);
211
+ i0.ɵɵconditional(ctx_r1.TotalCount === 0 && !ctx_r1.IsSearching ? 12 : -1);
159
212
  } }
160
213
  function KnowledgeSearchResourceComponent_Conditional_0_Conditional_13_Conditional_1_For_4_Conditional_0_Template(rf, ctx) { if (rf & 1) {
161
- const _r9 = i0.ɵɵgetCurrentView();
162
- i0.ɵɵelementStart(0, "div", 44);
163
- i0.ɵɵlistener("click", function KnowledgeSearchResourceComponent_Conditional_0_Conditional_13_Conditional_1_For_4_Conditional_0_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r9); const recent_r10 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.ApplyRecentSearch(recent_r10)); });
164
- i0.ɵɵelement(1, "i", 45);
165
- i0.ɵɵelementStart(2, "span", 46);
214
+ const _r11 = i0.ɵɵgetCurrentView();
215
+ i0.ɵɵelementStart(0, "div", 54);
216
+ i0.ɵɵlistener("click", function KnowledgeSearchResourceComponent_Conditional_0_Conditional_13_Conditional_1_For_4_Conditional_0_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r11); const saved_r12 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.ApplySavedSearch(saved_r12)); });
217
+ i0.ɵɵelement(1, "i", 55);
218
+ i0.ɵɵelementStart(2, "span", 56);
166
219
  i0.ɵɵtext(3);
167
220
  i0.ɵɵelementEnd();
168
- i0.ɵɵelementStart(4, "span", 47);
221
+ i0.ɵɵelementStart(4, "span", 57);
169
222
  i0.ɵɵtext(5);
223
+ i0.ɵɵelementEnd();
224
+ i0.ɵɵelementStart(6, "button", 58);
225
+ i0.ɵɵlistener("click", function KnowledgeSearchResourceComponent_Conditional_0_Conditional_13_Conditional_1_For_4_Conditional_0_Template_button_click_6_listener($event) { i0.ɵɵrestoreView(_r11); const saved_r12 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.DeleteSavedSearch(saved_r12, $event)); });
226
+ i0.ɵɵelement(7, "i", 17);
170
227
  i0.ɵɵelementEnd()();
171
228
  } if (rf & 2) {
172
- const recent_r10 = i0.ɵɵnextContext().$implicit;
229
+ const saved_r12 = i0.ɵɵnextContext().$implicit;
173
230
  i0.ɵɵadvance(3);
174
- i0.ɵɵtextInterpolate(recent_r10.Query);
231
+ i0.ɵɵtextInterpolate(saved_r12.Name);
175
232
  i0.ɵɵadvance(2);
176
- i0.ɵɵtextInterpolate1("", recent_r10.ResultCount, " results");
233
+ i0.ɵɵtextInterpolate(saved_r12.Query);
177
234
  } }
178
235
  function KnowledgeSearchResourceComponent_Conditional_0_Conditional_13_Conditional_1_For_4_Template(rf, ctx) { if (rf & 1) {
179
- i0.ɵɵconditionalCreate(0, KnowledgeSearchResourceComponent_Conditional_0_Conditional_13_Conditional_1_For_4_Conditional_0_Template, 6, 2, "div", 43);
236
+ i0.ɵɵconditionalCreate(0, KnowledgeSearchResourceComponent_Conditional_0_Conditional_13_Conditional_1_For_4_Conditional_0_Template, 8, 2, "div", 53);
180
237
  } if (rf & 2) {
181
- const ɵ$index_119_r11 = ctx.$index;
182
- i0.ɵɵconditional(ɵ$index_119_r11 < 8 ? 0 : -1);
238
+ const ɵ$index_144_r13 = ctx.$index;
239
+ i0.ɵɵconditional(ɵ$index_144_r13 < 8 ? 0 : -1);
183
240
  } }
184
241
  function KnowledgeSearchResourceComponent_Conditional_0_Conditional_13_Conditional_1_Template(rf, ctx) { if (rf & 1) {
185
- i0.ɵɵelementStart(0, "h3", 41);
242
+ i0.ɵɵelementStart(0, "h3", 51);
243
+ i0.ɵɵtext(1, "Saved Searches");
244
+ i0.ɵɵelementEnd();
245
+ i0.ɵɵelementStart(2, "div", 52);
246
+ i0.ɵɵrepeaterCreate(3, KnowledgeSearchResourceComponent_Conditional_0_Conditional_13_Conditional_1_For_4_Template, 1, 1, null, null, _forTrack1);
247
+ i0.ɵɵelementEnd();
248
+ } if (rf & 2) {
249
+ const ctx_r1 = i0.ɵɵnextContext(3);
250
+ i0.ɵɵadvance(3);
251
+ i0.ɵɵrepeater(ctx_r1.SavedSearches);
252
+ } }
253
+ function KnowledgeSearchResourceComponent_Conditional_0_Conditional_13_Conditional_2_For_4_Conditional_0_Template(rf, ctx) { if (rf & 1) {
254
+ const _r14 = i0.ɵɵgetCurrentView();
255
+ i0.ɵɵelementStart(0, "div", 60);
256
+ i0.ɵɵlistener("click", function KnowledgeSearchResourceComponent_Conditional_0_Conditional_13_Conditional_2_For_4_Conditional_0_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r14); const recent_r15 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.ApplyRecentSearch(recent_r15)); });
257
+ i0.ɵɵelement(1, "i", 61);
258
+ i0.ɵɵelementStart(2, "span", 56);
259
+ i0.ɵɵtext(3);
260
+ i0.ɵɵelementEnd();
261
+ i0.ɵɵelementStart(4, "span", 62);
262
+ i0.ɵɵtext(5);
263
+ i0.ɵɵelementEnd()();
264
+ } if (rf & 2) {
265
+ const recent_r15 = i0.ɵɵnextContext().$implicit;
266
+ i0.ɵɵadvance(3);
267
+ i0.ɵɵtextInterpolate(recent_r15.Query);
268
+ i0.ɵɵadvance(2);
269
+ i0.ɵɵtextInterpolate1("", recent_r15.ResultCount, " results");
270
+ } }
271
+ function KnowledgeSearchResourceComponent_Conditional_0_Conditional_13_Conditional_2_For_4_Template(rf, ctx) { if (rf & 1) {
272
+ i0.ɵɵconditionalCreate(0, KnowledgeSearchResourceComponent_Conditional_0_Conditional_13_Conditional_2_For_4_Conditional_0_Template, 6, 2, "div", 59);
273
+ } if (rf & 2) {
274
+ const ɵ$index_166_r16 = ctx.$index;
275
+ i0.ɵɵconditional(ɵ$index_166_r16 < 8 ? 0 : -1);
276
+ } }
277
+ function KnowledgeSearchResourceComponent_Conditional_0_Conditional_13_Conditional_2_Template(rf, ctx) { if (rf & 1) {
278
+ i0.ɵɵelementStart(0, "h3", 51);
186
279
  i0.ɵɵtext(1, "Recent Searches");
187
280
  i0.ɵɵelementEnd();
188
- i0.ɵɵelementStart(2, "div", 42);
189
- i0.ɵɵrepeaterCreate(3, KnowledgeSearchResourceComponent_Conditional_0_Conditional_13_Conditional_1_For_4_Template, 1, 1, null, null, _forTrack0);
281
+ i0.ɵɵelementStart(2, "div", 52);
282
+ i0.ɵɵrepeaterCreate(3, KnowledgeSearchResourceComponent_Conditional_0_Conditional_13_Conditional_2_For_4_Template, 1, 1, null, null, _forTrack2);
190
283
  i0.ɵɵelementEnd();
191
284
  } if (rf & 2) {
192
285
  const ctx_r1 = i0.ɵɵnextContext(3);
@@ -194,33 +287,74 @@ function KnowledgeSearchResourceComponent_Conditional_0_Conditional_13_Condition
194
287
  i0.ɵɵrepeater(ctx_r1.RecentSearches);
195
288
  } }
196
289
  function KnowledgeSearchResourceComponent_Conditional_0_Conditional_13_Template(rf, ctx) { if (rf & 1) {
197
- i0.ɵɵelementStart(0, "div", 13);
290
+ i0.ɵɵelementStart(0, "div", 11);
198
291
  i0.ɵɵconditionalCreate(1, KnowledgeSearchResourceComponent_Conditional_0_Conditional_13_Conditional_1_Template, 5, 0);
292
+ i0.ɵɵconditionalCreate(2, KnowledgeSearchResourceComponent_Conditional_0_Conditional_13_Conditional_2_Template, 5, 0);
199
293
  i0.ɵɵelementEnd();
200
294
  } if (rf & 2) {
201
295
  const ctx_r1 = i0.ɵɵnextContext(2);
202
296
  i0.ɵɵadvance();
203
- i0.ɵɵconditional(ctx_r1.RecentSearches.length > 0 ? 1 : -1);
297
+ i0.ɵɵconditional(ctx_r1.SavedSearches.length > 0 ? 1 : -1);
298
+ i0.ɵɵadvance();
299
+ i0.ɵɵconditional(ctx_r1.RecentSearches.length > 0 ? 2 : -1);
300
+ } }
301
+ function KnowledgeSearchResourceComponent_Conditional_0_Conditional_14_Template(rf, ctx) { if (rf & 1) {
302
+ const _r17 = i0.ɵɵgetCurrentView();
303
+ i0.ɵɵelementStart(0, "div", 63);
304
+ i0.ɵɵlistener("click", function KnowledgeSearchResourceComponent_Conditional_0_Conditional_14_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r17); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.CancelSaveDialog()); });
305
+ i0.ɵɵelementStart(1, "div", 64);
306
+ i0.ɵɵlistener("click", function KnowledgeSearchResourceComponent_Conditional_0_Conditional_14_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r17); return i0.ɵɵresetView($event.stopPropagation()); });
307
+ i0.ɵɵelementStart(2, "h3", 65);
308
+ i0.ɵɵtext(3, "Save Search");
309
+ i0.ɵɵelementEnd();
310
+ i0.ɵɵelementStart(4, "p", 66);
311
+ i0.ɵɵtext(5);
312
+ i0.ɵɵelementEnd();
313
+ i0.ɵɵelementStart(6, "label", 67);
314
+ i0.ɵɵtext(7, "Name");
315
+ i0.ɵɵelementEnd();
316
+ i0.ɵɵelementStart(8, "input", 68);
317
+ i0.ɵɵtwoWayListener("ngModelChange", function KnowledgeSearchResourceComponent_Conditional_0_Conditional_14_Template_input_ngModelChange_8_listener($event) { i0.ɵɵrestoreView(_r17); const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r1.SaveSearchName, $event) || (ctx_r1.SaveSearchName = $event); return i0.ɵɵresetView($event); });
318
+ i0.ɵɵlistener("keydown.enter", function KnowledgeSearchResourceComponent_Conditional_0_Conditional_14_Template_input_keydown_enter_8_listener() { i0.ɵɵrestoreView(_r17); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.ConfirmSaveSearch()); });
319
+ i0.ɵɵelementEnd();
320
+ i0.ɵɵelementStart(9, "div", 69)(10, "button", 70);
321
+ i0.ɵɵlistener("click", function KnowledgeSearchResourceComponent_Conditional_0_Conditional_14_Template_button_click_10_listener() { i0.ɵɵrestoreView(_r17); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.ConfirmSaveSearch()); });
322
+ i0.ɵɵelement(11, "i", 33);
323
+ i0.ɵɵtext(12, " Save ");
324
+ i0.ɵɵelementEnd();
325
+ i0.ɵɵelementStart(13, "button", 71);
326
+ i0.ɵɵlistener("click", function KnowledgeSearchResourceComponent_Conditional_0_Conditional_14_Template_button_click_13_listener() { i0.ɵɵrestoreView(_r17); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.CancelSaveDialog()); });
327
+ i0.ɵɵtext(14, "Cancel");
328
+ i0.ɵɵelementEnd()()()();
329
+ } if (rf & 2) {
330
+ const ctx_r1 = i0.ɵɵnextContext(2);
331
+ i0.ɵɵadvance(5);
332
+ i0.ɵɵtextInterpolate1("Save \"", ctx_r1.Query, "\" for quick access later");
333
+ i0.ɵɵadvance(3);
334
+ i0.ɵɵtwoWayProperty("ngModel", ctx_r1.SaveSearchName);
335
+ i0.ɵɵadvance(2);
336
+ i0.ɵɵproperty("disabled", !ctx_r1.SaveSearchName.trim());
204
337
  } }
205
338
  function KnowledgeSearchResourceComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
206
339
  const _r1 = i0.ɵɵgetCurrentView();
207
- i0.ɵɵelementStart(0, "div", 2)(1, "div", 3);
340
+ i0.ɵɵelementStart(0, "div", 1)(1, "div", 2);
208
341
  i0.ɵɵconditionalCreate(2, KnowledgeSearchResourceComponent_Conditional_0_Conditional_2_Template, 5, 0);
209
- i0.ɵɵelementStart(3, "div", 4)(4, "div", 5);
210
- i0.ɵɵelement(5, "i", 6);
211
- i0.ɵɵelementStart(6, "input", 7);
342
+ i0.ɵɵelementStart(3, "div", 3)(4, "div", 4);
343
+ i0.ɵɵelement(5, "i", 5);
344
+ i0.ɵɵelementStart(6, "input", 6);
212
345
  i0.ɵɵtwoWayListener("ngModelChange", function KnowledgeSearchResourceComponent_Conditional_0_Template_input_ngModelChange_6_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.Query, $event) || (ctx_r1.Query = $event); return i0.ɵɵresetView($event); });
213
346
  i0.ɵɵlistener("keydown", function KnowledgeSearchResourceComponent_Conditional_0_Template_input_keydown_6_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnSearchKeydown($event)); });
214
347
  i0.ɵɵelementEnd();
215
- i0.ɵɵconditionalCreate(7, KnowledgeSearchResourceComponent_Conditional_0_Conditional_7_Template, 2, 0, "button", 8);
216
- i0.ɵɵelementStart(8, "button", 9);
348
+ i0.ɵɵconditionalCreate(7, KnowledgeSearchResourceComponent_Conditional_0_Conditional_7_Template, 2, 0, "button", 7);
349
+ i0.ɵɵelementStart(8, "button", 8);
217
350
  i0.ɵɵlistener("click", function KnowledgeSearchResourceComponent_Conditional_0_Template_button_click_8_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.RunSearch()); });
218
- i0.ɵɵconditionalCreate(9, KnowledgeSearchResourceComponent_Conditional_0_Conditional_9_Template, 1, 0, "i", 10)(10, KnowledgeSearchResourceComponent_Conditional_0_Conditional_10_Template, 1, 0);
351
+ i0.ɵɵconditionalCreate(9, KnowledgeSearchResourceComponent_Conditional_0_Conditional_9_Template, 1, 0, "i", 9)(10, KnowledgeSearchResourceComponent_Conditional_0_Conditional_10_Template, 1, 0);
219
352
  i0.ɵɵelementEnd()();
220
- i0.ɵɵconditionalCreate(11, KnowledgeSearchResourceComponent_Conditional_0_Conditional_11_Template, 4, 0, "div", 11);
353
+ i0.ɵɵconditionalCreate(11, KnowledgeSearchResourceComponent_Conditional_0_Conditional_11_Template, 5, 1);
221
354
  i0.ɵɵelementEnd()();
222
- i0.ɵɵconditionalCreate(12, KnowledgeSearchResourceComponent_Conditional_0_Conditional_12_Template, 11, 9, "div", 12)(13, KnowledgeSearchResourceComponent_Conditional_0_Conditional_13_Template, 2, 1, "div", 13);
355
+ i0.ɵɵconditionalCreate(12, KnowledgeSearchResourceComponent_Conditional_0_Conditional_12_Template, 13, 11, "div", 10)(13, KnowledgeSearchResourceComponent_Conditional_0_Conditional_13_Template, 3, 2, "div", 11);
223
356
  i0.ɵɵelementEnd();
357
+ i0.ɵɵconditionalCreate(14, KnowledgeSearchResourceComponent_Conditional_0_Conditional_14_Template, 15, 3, "div", 12);
224
358
  } if (rf & 2) {
225
359
  const ctx_r1 = i0.ɵɵnextContext();
226
360
  i0.ɵɵclassProp("search-page-has-results", ctx_r1.HasSearched);
@@ -240,17 +374,20 @@ function KnowledgeSearchResourceComponent_Conditional_0_Template(rf, ctx) { if (
240
374
  i0.ɵɵconditional(!ctx_r1.HasSearched ? 11 : -1);
241
375
  i0.ɵɵadvance();
242
376
  i0.ɵɵconditional(ctx_r1.HasSearched ? 12 : !ctx_r1.IsSearching ? 13 : -1);
377
+ i0.ɵɵadvance(2);
378
+ i0.ɵɵconditional(ctx_r1.ShowSaveDialog ? 14 : -1);
243
379
  } }
244
380
  function KnowledgeSearchResourceComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
245
- const _r12 = i0.ɵɵgetCurrentView();
246
- i0.ɵɵelementStart(0, "app-search-result-detail", 48);
247
- i0.ɵɵlistener("BackClicked", function KnowledgeSearchResourceComponent_Conditional_1_Template_app_search_result_detail_BackClicked_0_listener() { i0.ɵɵrestoreView(_r12); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.CloseResultDetail()); })("NavigateToRecord", function KnowledgeSearchResourceComponent_Conditional_1_Template_app_search_result_detail_NavigateToRecord_0_listener($event) { i0.ɵɵrestoreView(_r12); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnOpenRecord($event)); });
381
+ const _r18 = i0.ɵɵgetCurrentView();
382
+ i0.ɵɵelementStart(0, "app-search-result-detail", 72);
383
+ i0.ɵɵlistener("BackClicked", function KnowledgeSearchResourceComponent_Conditional_1_Template_app_search_result_detail_BackClicked_0_listener() { i0.ɵɵrestoreView(_r18); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.CloseResultDetail()); })("NavigateToRecord", function KnowledgeSearchResourceComponent_Conditional_1_Template_app_search_result_detail_NavigateToRecord_0_listener($event) { i0.ɵɵrestoreView(_r18); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnOpenRecord($event)); });
248
384
  i0.ɵɵelementEnd();
249
385
  } if (rf & 2) {
250
386
  const ctx_r1 = i0.ɵɵnextContext();
251
387
  i0.ɵɵproperty("Result", ctx_r1.DetailResult);
252
388
  } }
253
389
  let KnowledgeSearchResourceComponent = class KnowledgeSearchResourceComponent extends BaseResourceComponent {
390
+ static { KnowledgeSearchResourceComponent_1 = this; }
254
391
  cdr = inject(ChangeDetectorRef);
255
392
  searchService = inject(SearchService);
256
393
  injector = inject(Injector);
@@ -272,28 +409,108 @@ let KnowledgeSearchResourceComponent = class KnowledgeSearchResourceComponent ex
272
409
  ElapsedMs = 0;
273
410
  /** Minimum relevance score threshold (0-1). Results below this are hidden. */
274
411
  MinScoreThreshold = 0.35;
412
+ /**
413
+ * The minimum relevance threshold that was last sent to the server.
414
+ * When the slider moves above this, we filter client-side.
415
+ * When it moves below, we must re-fetch from the server.
416
+ */
417
+ ServerMinRelevance = 0.35;
418
+ /** Count of server-side results before any client-side filtering */
419
+ ServerResultCount = 0;
275
420
  // --- Recent & Saved ---
276
421
  RecentSearches = [];
277
422
  SavedSearches = [];
423
+ /** Popular tags for "Filter by Tag" preset buttons, sized by relative frequency */
424
+ PopularTags = [];
425
+ // --- Save Search Dialog ---
426
+ ShowSaveDialog = false;
427
+ SaveSearchName = '';
278
428
  async GetResourceDisplayName(_data) {
279
429
  return 'Knowledge Search';
280
430
  }
281
431
  async GetResourceIconClass(_data) {
282
432
  return 'fa-solid fa-magnifying-glass';
283
433
  }
284
- ngAfterViewInit() {
434
+ async ngAfterViewInit() {
435
+ await UserInfoEngine.Instance.Config(false);
436
+ this.LoadSearchPreferences();
285
437
  this.subscribeToSearchState();
286
438
  this.parseUrlParameters();
439
+ this.registerAgentTools();
440
+ this.emitAgentContext();
441
+ this.loadSavedSearches();
442
+ this.loadPopularTags();
443
+ this.NotifyLoadComplete();
287
444
  }
288
445
  ngOnDestroy() {
289
446
  this.destroy$.next();
290
447
  this.destroy$.complete();
291
448
  }
449
+ /** Report current search state to the agent via NavigationService */
450
+ emitAgentContext() {
451
+ this.navigationService.SetAgentContext(this, {
452
+ CurrentQuery: this.Query || null,
453
+ ResultCount: this.TotalCount,
454
+ ElapsedMs: this.ElapsedMs,
455
+ HasSearched: this.HasSearched,
456
+ ShowFilters: this.ShowFilters,
457
+ MinScoreThreshold: this.MinScoreThreshold,
458
+ ActiveFilterCount: this.GetActiveFilterCount(),
459
+ TopResults: this.AllResults.slice(0, 5).map(r => ({
460
+ Title: r.Title,
461
+ EntityName: r.EntityName,
462
+ Score: Math.round(r.Score * 100),
463
+ })),
464
+ });
465
+ }
466
+ /** Register client tools the agent can invoke on this dashboard */
467
+ registerAgentTools() {
468
+ this.navigationService.SetAgentClientTools(this, [
469
+ {
470
+ Name: 'RunKnowledgeSearch',
471
+ Description: 'Execute a knowledge search query across all indexed content',
472
+ ParameterSchema: {
473
+ type: 'object',
474
+ properties: {
475
+ query: { type: 'string', description: 'The search query text' },
476
+ minScore: { type: 'number', description: 'Minimum relevance score 0-1 (default 0.35)' },
477
+ },
478
+ required: ['query'],
479
+ },
480
+ Handler: async (params) => {
481
+ this.Query = String(params['query'] ?? '');
482
+ if (params['minScore'] != null)
483
+ this.MinScoreThreshold = Number(params['minScore']);
484
+ await this.RunSearch();
485
+ return { Success: true, Data: { ResultCount: this.TotalCount, ElapsedMs: this.ElapsedMs } };
486
+ },
487
+ },
488
+ {
489
+ Name: 'ClearKnowledgeSearch',
490
+ Description: 'Clear the current search query and results',
491
+ ParameterSchema: { type: 'object', properties: {} },
492
+ Handler: async () => {
493
+ this.ClearSearch();
494
+ return { Success: true };
495
+ },
496
+ },
497
+ {
498
+ Name: 'ToggleSearchFilters',
499
+ Description: 'Show or hide the search filter panel',
500
+ ParameterSchema: { type: 'object', properties: {} },
501
+ Handler: async () => {
502
+ this.ToggleFilters();
503
+ return { Success: true, Data: { ShowFilters: this.ShowFilters } };
504
+ },
505
+ },
506
+ ]);
507
+ }
292
508
  /** Execute a search query */
293
509
  async RunSearch() {
294
510
  const query = this.Query.trim();
295
511
  if (!query)
296
512
  return;
513
+ this.ServerMinRelevance = this.MinScoreThreshold;
297
514
  const request = {
298
515
  Query: query,
299
516
  MaxResults: 50,
@@ -340,23 +557,83 @@ let KnowledgeSearchResourceComponent = class KnowledgeSearchResourceComponent ex
340
557
  /** Toggle the filter sidebar */
341
558
  ToggleFilters() {
342
559
  this.ShowFilters = !this.ShowFilters;
560
+ this.PersistSearchPreferences();
343
561
  this.cdr.detectChanges();
344
562
  }
345
- /** Handle a filter change from the filter component */
563
+ /**
564
+ * Handle a filter change from the filter component.
565
+ * Uses client-side filtering on the cached full result set — no server re-query.
566
+ */
346
567
  OnFilterChanged(event) {
347
568
  this.ActiveFilters[event.Category] = event.SelectedValues;
348
- this.RunSearch();
569
+ this.applyClientSideFilters();
570
+ this.PersistSearchPreferences();
349
571
  }
350
572
  /** Handle clearing all filters */
351
573
  OnFiltersCleared() {
352
574
  this.ActiveFilters = {};
353
575
  this.MinScoreThreshold = 0.35;
354
- this.RunSearch();
576
+ this.applyClientSideFilters();
577
+ this.PersistSearchPreferences();
355
578
  }
356
- /** Handle relevance threshold slider change */
579
+ /**
580
+ * Handle relevance threshold slider change.
581
+ * - Moving UP (narrowing): filter client-side from cached server results.
582
+ * - Moving DOWN past ServerMinRelevance (widening): re-fetch from server.
583
+ */
357
584
  OnThresholdChanged(value) {
358
585
  this.MinScoreThreshold = value;
359
- this.RunSearch();
586
+ if (value >= this.ServerMinRelevance) {
587
+ // Narrowing — client-side filter is sufficient
588
+ this.applyClientSideFilters();
589
+ }
590
+ else {
591
+ // Widening past what the server returned — need fresh data
592
+ this.RunSearchWithThreshold(value);
593
+ }
594
+ }
595
+ /**
596
+ * Re-fetch from the server with a new minimum relevance threshold,
597
+ * then update the server baseline so future narrowing stays client-side.
598
+ */
599
+ async RunSearchWithThreshold(threshold) {
600
+ const query = this.Query.trim();
601
+ if (!query)
602
+ return;
603
+ const request = {
604
+ Query: query,
605
+ MaxResults: 50,
606
+ ActiveFilters: this.ActiveFilters,
607
+ IncludeSources: ['vector', 'fulltext', 'entity'],
608
+ MinScore: threshold,
609
+ };
610
+ const response = await this.searchService.ExecuteSearch(request);
611
+ this.ServerMinRelevance = threshold;
612
+ this.applySearchResponse(response);
613
+ }
614
+ /** Toggle select all / unselect all for a filter category (Kayak-style) */
615
+ ToggleSelectAll(category) {
616
+ const filter = this.Filters.find(f => f.Category === category);
617
+ if (!filter)
618
+ return;
619
+ const currentSelection = this.ActiveFilters[category] ?? [];
620
+ if (currentSelection.length === filter.Options.length) {
621
+ // All selected → unselect all
622
+ this.ActiveFilters[category] = [];
623
+ }
624
+ else {
625
+ // Some or none selected → select all
626
+ this.ActiveFilters[category] = filter.Options.map(o => o.Value);
627
+ }
628
+ this.applyClientSideFilters();
629
+ }
630
+ /** Check if all options in a category are selected */
631
+ IsAllSelected(category) {
632
+ const filter = this.Filters.find(f => f.Category === category);
633
+ if (!filter)
634
+ return false;
635
+ const selection = this.ActiveFilters[category] ?? [];
636
+ return selection.length === filter.Options.length;
360
637
  }
361
638
  /** Open the chat overlay with Knowledge Agent context */
362
639
  OnAskAgent() {
@@ -373,11 +650,109 @@ let KnowledgeSearchResourceComponent = class KnowledgeSearchResourceComponent ex
373
650
  console.warn('[KnowledgeSearch] ConversationBridgeService not available');
374
651
  }
375
652
  }
653
+ /**
654
+ * Handle "See Similar Items" — re-runs the search using the result's title as the query.
655
+ * This provides a lightweight "more like this" experience without needing raw vector access.
656
+ */
657
+ OnMoreLikeThis(result) {
658
+ this.ActiveFilters = {};
659
+ this.Query = result.RecordName ?? result.Title;
660
+ this.RunSearch();
661
+ }
376
662
  /** Apply a recent search */
377
663
  ApplyRecentSearch(recent) {
378
664
  this.Query = recent.Query;
379
665
  this.RunSearch();
380
666
  }
667
+ // --- Saved Searches ---
668
+ /** Open the save search dialog */
669
+ OpenSaveDialog() {
670
+ this.SaveSearchName = this.Query;
671
+ this.ShowSaveDialog = true;
672
+ this.cdr.detectChanges();
673
+ }
674
+ /** Cancel the save dialog */
675
+ CancelSaveDialog() {
676
+ this.ShowSaveDialog = false;
677
+ this.SaveSearchName = '';
678
+ this.cdr.detectChanges();
679
+ }
680
+ /**
681
+ * Save the current search as a named saved search using MJKnowledgeHubSavedSearchEntity.
682
+ * Persists query, active filters, min score, and max results.
683
+ */
684
+ async ConfirmSaveSearch() {
685
+ const name = this.SaveSearchName.trim();
686
+ if (!name || !this.Query.trim())
687
+ return;
688
+ try {
689
+ const md = new Metadata();
690
+ const entity = await md.GetEntityObject('MJ: Knowledge Hub Saved Searches');
691
+ entity.Name = name;
692
+ entity.Query = this.Query;
693
+ entity.Filters = Object.keys(this.ActiveFilters).length > 0
694
+ ? JSON.stringify(this.ActiveFilters)
695
+ : null;
696
+ entity.MinScore = this.MinScoreThreshold > 0 ? this.MinScoreThreshold : null;
697
+ entity.MaxResults = 50;
698
+ entity.NotifyOnNewResults = false;
699
+ const saved = await entity.Save();
700
+ if (saved) {
701
+ this.SavedSearches = [entity, ...this.SavedSearches];
702
+ }
703
+ }
704
+ catch (error) {
705
+ console.error('[KnowledgeSearch] Failed to save search:', error);
706
+ }
707
+ this.ShowSaveDialog = false;
708
+ this.SaveSearchName = '';
709
+ this.cdr.detectChanges();
710
+ }
711
+ /**
712
+ * Apply a saved search — populates query, filters, and threshold, then executes.
713
+ */
714
+ ApplySavedSearch(saved) {
715
+ this.Query = saved.Query;
716
+ if (saved.Filters) {
717
+ try {
718
+ this.ActiveFilters = JSON.parse(saved.Filters);
719
+ }
720
+ catch {
721
+ this.ActiveFilters = {};
722
+ }
723
+ }
724
+ else {
725
+ this.ActiveFilters = {};
726
+ }
727
+ if (saved.MinScore != null) {
728
+ this.MinScoreThreshold = saved.MinScore;
729
+ }
730
+ this.RunSearch();
731
+ }
732
+ /**
733
+ * Delete a saved search by ID and remove it from the local list.
734
+ */
735
+ async DeleteSavedSearch(saved, event) {
736
+ event.stopPropagation();
737
+ try {
738
+ const success = await saved.Delete();
739
+ if (success) {
740
+ this.SavedSearches = this.SavedSearches.filter(s => !UUIDsEqual(s.ID, saved.ID));
741
+ this.cdr.detectChanges();
742
+ }
743
+ }
744
+ catch (error) {
745
+ console.error('[KnowledgeSearch] Failed to delete saved search:', error);
746
+ }
747
+ }
748
+ /**
749
+ * Search by a popular tag: sets the query text and runs a search.
750
+ * Does NOT add a sticky filter — just a simple text search.
751
+ */
752
+ FilterByTag(tagName) {
753
+ this.Query = tagName;
754
+ this.RunSearch();
755
+ }
381
756
  /** Clear the current search */
382
757
  ClearSearch() {
383
758
  this.Query = '';
@@ -386,6 +761,8 @@ let KnowledgeSearchResourceComponent = class KnowledgeSearchResourceComponent ex
386
761
  this.Filters = [];
387
762
  this.ActiveFilters = {};
388
763
  this.TotalCount = 0;
764
+ this.ServerResultCount = 0;
765
+ this.ServerMinRelevance = 0.35;
389
766
  this.HasSearched = false;
390
767
  this.ShowFilters = false;
391
768
  this.cdr.detectChanges();
@@ -394,6 +771,9 @@ let KnowledgeSearchResourceComponent = class KnowledgeSearchResourceComponent ex
394
771
  HasActiveFilters() {
395
772
  return Object.values(this.ActiveFilters).some(v => v.length > 0);
396
773
  }
774
+ GetActiveFilterCount() {
775
+ return Object.values(this.ActiveFilters).reduce((sum, v) => sum + v.length, 0);
776
+ }
397
777
  // --- Private Methods ---
398
778
  /** Parse URL parameters for deep links (e.g., ?conversationId=xxx or ?q=search+term) */
399
779
  parseUrlParameters() {
@@ -414,6 +794,85 @@ let KnowledgeSearchResourceComponent = class KnowledgeSearchResourceComponent ex
414
794
  // Ignore URL parsing errors
415
795
  }
416
796
  }
797
+ /**
798
+ * Load saved searches for the current user from the database.
799
+ * Runs in the background — does not block initialization.
800
+ */
801
+ async loadSavedSearches() {
802
+ try {
803
+ const rv = new RunView();
804
+ const result = await rv.RunView({
805
+ EntityName: 'MJ: Knowledge Hub Saved Searches',
806
+ OrderBy: '__mj_CreatedAt DESC',
807
+ MaxRows: 50,
808
+ ResultType: 'entity_object'
809
+ });
810
+ if (result.Success) {
811
+ this.SavedSearches = result.Results;
812
+ this.cdr.detectChanges();
813
+ }
814
+ }
815
+ catch (error) {
816
+ console.error('[KnowledgeSearch] Failed to load saved searches:', error);
817
+ }
818
+ }
819
+ /**
820
+ * Load the top 10 most-used tags for the "Filter by Tag" preset buttons.
821
+ * Loads TaggedItems (TagID only), aggregates counts client-side, resolves
822
+ * display names from Tags, then sizes each tag by relative frequency.
823
+ * Font sizes range from 0.8rem (least used in top 10) to 1.3rem (most used).
824
+ */
825
+ async loadPopularTags() {
826
+ try {
827
+ const rv = new RunView();
828
+ const [taggedResult, tagResult] = await rv.RunViews([
829
+ {
830
+ EntityName: 'MJ: Tagged Items',
831
+ Fields: ['TagID'],
832
+ ResultType: 'simple'
833
+ },
834
+ {
835
+ EntityName: 'MJ: Tags',
836
+ Fields: ['ID', 'DisplayName'],
837
+ ResultType: 'simple'
838
+ }
839
+ ]);
840
+ if (!taggedResult.Success || !tagResult.Success)
841
+ return;
842
+ // Count occurrences per TagID
843
+ const counts = new Map();
844
+ for (const row of taggedResult.Results) {
845
+ counts.set(row.TagID, (counts.get(row.TagID) ?? 0) + 1);
846
+ }
847
+ // Build name lookup
848
+ const tagNames = new Map();
849
+ for (const row of tagResult.Results) {
850
+ tagNames.set(row.ID, row.DisplayName);
851
+ }
852
+ // Sort by count descending, take top 10
853
+ const sorted = [...counts.entries()]
854
+ .sort((a, b) => b[1] - a[1])
855
+ .slice(0, 10);
856
+ if (sorted.length === 0)
857
+ return;
858
+ const maxCount = sorted[0][1];
859
+ const minCount = sorted[sorted.length - 1][1];
860
+ const range = maxCount - minCount || 1;
861
+ const minFont = 0.8;
862
+ const maxFont = 1.3;
863
+ this.PopularTags = sorted
864
+ .map(([tagID, count]) => ({
865
+ Name: tagNames.get(tagID) ?? '',
866
+ Count: count,
867
+ FontSize: minFont + ((count - minCount) / range) * (maxFont - minFont)
868
+ }))
869
+ .filter(t => t.Name.length > 0);
870
+ this.cdr.detectChanges();
871
+ }
872
+ catch {
873
+ // Non-critical — tags are a convenience, not a blocker
874
+ }
875
+ }
417
876
  subscribeToSearchState() {
418
877
  this.searchService.IsSearching$
419
878
  .pipe(takeUntil(this.destroy$))
@@ -428,32 +887,103 @@ let KnowledgeSearchResourceComponent = class KnowledgeSearchResourceComponent ex
428
887
  this.cdr.detectChanges();
429
888
  });
430
889
  }
890
+ /** Full unfiltered result set from the last server query */
891
+ cachedFullResults = [];
892
+ /**
893
+ * Apply filters client-side on the cached full result set.
894
+ * This avoids re-querying the server when entity/tag checkboxes change.
895
+ */
896
+ applyClientSideFilters() {
897
+ let filtered = [...this.cachedFullResults];
898
+ // Apply entity filter
899
+ const entityFilter = this.ActiveFilters['Entity'];
900
+ if (entityFilter?.length > 0) {
901
+ filtered = filtered.filter(r => entityFilter.includes(r.EntityName));
902
+ }
903
+ // Apply tag filter
904
+ const tagFilter = this.ActiveFilters['Tags'];
905
+ if (tagFilter?.length > 0) {
906
+ filtered = filtered.filter(r => r.Tags?.some(t => tagFilter.includes(t)));
907
+ }
908
+ // Apply score threshold
909
+ if (this.MinScoreThreshold > 0) {
910
+ filtered = filtered.filter(r => r.Score >= this.MinScoreThreshold);
911
+ }
912
+ // Rebuild groups and update counts
913
+ this.AllResults = filtered;
914
+ this.ResultGroups = this.searchService.GroupResults(filtered);
915
+ this.TotalCount = filtered.length;
916
+ // SR-3 fix: Build filters from FULL result set so options don't disappear
917
+ // when a filter is checked. Counts reflect the filtered results for context.
918
+ this.Filters = this.searchService.BuildFilters(this.cachedFullResults);
919
+ // Remove Source Type filter — it confuses users
920
+ this.Filters = this.Filters.filter(f => f.Category !== 'Source Type');
921
+ this.cdr.detectChanges();
922
+ this.emitAgentContext();
923
+ }
924
+ static PREFS_KEY = 'KH_Search_Preferences';
925
+ /** Persist user search preferences via UserInfoEngine */
926
+ PersistSearchPreferences() {
927
+ const prefs = JSON.stringify({
928
+ ShowFilters: this.ShowFilters,
929
+ MinScoreThreshold: this.MinScoreThreshold,
930
+ });
931
+ UserInfoEngine.Instance.SetSettingDebounced(KnowledgeSearchResourceComponent_1.PREFS_KEY, prefs);
932
+ }
933
+ /** Load persisted search preferences from UserInfoEngine */
934
+ LoadSearchPreferences() {
935
+ const raw = UserInfoEngine.Instance.GetSetting(KnowledgeSearchResourceComponent_1.PREFS_KEY);
936
+ if (raw) {
937
+ try {
938
+ const prefs = JSON.parse(raw);
939
+ if (prefs.ShowFilters != null)
940
+ this.ShowFilters = prefs.ShowFilters;
941
+ if (prefs.MinScoreThreshold != null)
942
+ this.MinScoreThreshold = prefs.MinScoreThreshold;
943
+ }
944
+ catch { /* ignore parse errors */ }
945
+ }
946
+ }
431
947
  applySearchResponse(response) {
432
- this.AllResults = response.Results;
433
- this.ResultGroups = response.Groups;
434
- this.Filters = response.Filters;
435
- this.TotalCount = response.TotalCount;
948
+ // Cache full results (sorted by score descending) for client-side filtering
949
+ this.cachedFullResults = response.Results.sort((a, b) => b.Score - a.Score);
950
+ this.ServerResultCount = this.cachedFullResults.length;
951
+ // Apply current threshold client-side (may be higher than server threshold)
952
+ let filtered = this.cachedFullResults;
953
+ if (this.MinScoreThreshold > 0) {
954
+ filtered = filtered.filter(r => r.Score >= this.MinScoreThreshold);
955
+ }
956
+ this.AllResults = [...filtered];
957
+ this.ResultGroups = this.searchService.GroupResults(filtered);
958
+ // Remove Source Type filter — confuses users
959
+ this.Filters = response.Filters.filter(f => f.Category !== 'Source Type');
960
+ this.TotalCount = filtered.length;
436
961
  this.ElapsedMs = response.ElapsedMs;
437
962
  this.HasSearched = true;
438
- this.ShowFilters = response.Filters.length > 0;
963
+ // Only auto-show filters on first search if user hasn't set a preference
964
+ const savedPref = UserInfoEngine.Instance.GetSetting(KnowledgeSearchResourceComponent_1.PREFS_KEY);
965
+ if (!savedPref) {
966
+ this.ShowFilters = response.Filters.length > 0;
967
+ }
439
968
  this.cdr.detectChanges();
969
+ this.emitAgentContext();
440
970
  }
441
971
  static ɵfac = /*@__PURE__*/ (() => { let ɵKnowledgeSearchResourceComponent_BaseFactory; return function KnowledgeSearchResourceComponent_Factory(__ngFactoryType__) { return (ɵKnowledgeSearchResourceComponent_BaseFactory || (ɵKnowledgeSearchResourceComponent_BaseFactory = i0.ɵɵgetInheritedFactory(KnowledgeSearchResourceComponent)))(__ngFactoryType__ || KnowledgeSearchResourceComponent); }; })();
442
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: KnowledgeSearchResourceComponent, selectors: [["app-knowledge-search-resource"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 2, vars: 1, consts: [[1, "search-page", 3, "search-page-has-results"], [3, "Result"], [1, "search-page"], [1, "search-hero"], [1, "search-container"], [1, "search-box"], [1, "fa-solid", "fa-magnifying-glass", "search-box-icon"], ["type", "text", "placeholder", "Search across all your knowledge...", "autocomplete", "off", "spellcheck", "false", 1, "search-box-input", 3, "ngModelChange", "keydown", "ngModel"], [1, "search-clear-btn"], [1, "search-submit-btn", 3, "click", "disabled"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "search-quick-actions"], [1, "search-results-layout"], [1, "search-recent-area"], [1, "search-logo"], [1, "fa-solid", "fa-brain"], [1, "search-subtitle"], [1, "search-clear-btn", 3, "click"], [1, "fa-solid", "fa-times"], [1, "quick-action-btn", 3, "click"], [1, "fa-solid", "fa-robot"], [1, "search-sidebar"], [1, "search-results-main"], [1, "search-results-header"], [1, "search-results-count"], [1, "search-results-time"], [1, "search-results-actions"], [1, "toggle-filters-btn"], [3, "ResultSelected", "OpenRecordRequested", "ResultGroups", "IsLoading", "TotalCount", "ElapsedMs"], [1, "search-agent-cta"], [3, "FilterChanged", "FiltersCleared", "Filters", "ActiveFilters"], [1, "threshold-section"], [1, "threshold-label"], [1, "threshold-value"], ["type", "range", 1, "threshold-slider", 3, "input", "min", "max", "step", "value"], [1, "threshold-range-labels"], [1, "toggle-filters-btn", 3, "click"], [1, "fa-solid", "fa-filter"], [1, "fa-solid", "fa-robot", "cta-icon"], [1, "cta-text"], [1, "cta-btn", 3, "click"], [1, "recent-title"], [1, "recent-list"], [1, "recent-item"], [1, "recent-item", 3, "click"], [1, "fa-solid", "fa-clock", "recent-icon"], [1, "recent-query"], [1, "recent-count"], [3, "BackClicked", "NavigateToRecord", "Result"]], template: function KnowledgeSearchResourceComponent_Template(rf, ctx) { if (rf & 1) {
443
- i0.ɵɵconditionalCreate(0, KnowledgeSearchResourceComponent_Conditional_0_Template, 14, 11, "div", 0)(1, KnowledgeSearchResourceComponent_Conditional_1_Template, 1, 1, "app-search-result-detail", 1);
972
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: KnowledgeSearchResourceComponent, selectors: [["app-knowledge-search-resource"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 2, vars: 1, consts: [[3, "Result"], [1, "search-page"], [1, "search-hero"], [1, "search-container"], [1, "search-box"], [1, "fa-solid", "fa-magnifying-glass", "search-box-icon"], ["type", "text", "placeholder", "Search across all your knowledge...", "autocomplete", "off", "spellcheck", "false", 1, "search-box-input", 3, "ngModelChange", "keydown", "ngModel"], [1, "search-clear-btn"], [1, "search-submit-btn", 3, "click", "disabled"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "search-results-layout"], [1, "search-recent-area"], [1, "save-dialog-overlay"], [1, "search-logo"], [1, "fa-solid", "fa-brain"], [1, "search-subtitle"], [1, "search-clear-btn", 3, "click"], [1, "fa-solid", "fa-times"], [1, "search-quick-actions"], [1, "quick-action-btn", 3, "click"], [1, "fa-solid", "fa-robot"], [1, "search-tag-presets"], [1, "tag-presets-label"], [1, "fa-solid", "fa-tags"], [1, "tag-preset-btn", 3, "fontSize", "title"], [1, "tag-preset-btn", 3, "click", "title"], [1, "search-sidebar"], [1, "search-results-main"], [1, "search-results-header"], [1, "show-filters-btn"], [1, "search-results-count"], [1, "search-results-time"], ["title", "Save this search", 1, "save-search-btn", 3, "click"], [1, "fa-solid", "fa-bookmark"], ["DisplayMode", "flat", 3, "ResultSelected", "OpenRecordRequested", "MoreLikeThisRequested", "ShowSummary", "FlatResults", "ResultGroups", "IsLoading", "TotalCount", "ElapsedMs"], [1, "search-agent-cta"], [3, "FilterChanged", "FiltersCleared", "CloseRequested", "Filters", "ActiveFilters"], [1, "threshold-section"], [1, "threshold-label"], [1, "threshold-value"], ["type", "range", 1, "threshold-slider", 3, "input", "min", "max", "step", "value"], [1, "threshold-range-labels"], [1, "threshold-stats"], [1, "threshold-stats-shown"], [1, "threshold-stats-range"], [1, "show-filters-btn", 3, "click"], [1, "fa-solid", "fa-filter"], [1, "filter-active-badge"], [1, "fa-solid", "fa-robot", "cta-icon"], [1, "cta-text"], [1, "cta-btn", 3, "click"], [1, "recent-title"], [1, "recent-list"], [1, "recent-item", "saved-item"], [1, "recent-item", "saved-item", 3, "click"], [1, "fa-solid", "fa-bookmark", "saved-icon"], [1, "recent-query"], [1, "saved-query-text"], ["title", "Delete saved search", 1, "saved-delete-btn", 3, "click"], [1, "recent-item"], [1, "recent-item", 3, "click"], [1, "fa-solid", "fa-clock", "recent-icon"], [1, "recent-count"], [1, "save-dialog-overlay", 3, "click"], [1, "save-dialog", 3, "click"], [1, "save-dialog-title"], [1, "save-dialog-subtitle"], [1, "save-dialog-label"], ["type", "text", "placeholder", "Give this search a name...", "autofocus", "", 1, "mj-input", "save-dialog-input", 3, "ngModelChange", "keydown.enter", "ngModel"], [1, "save-dialog-actions"], [1, "save-dialog-confirm", 3, "click", "disabled"], [1, "save-dialog-cancel", 3, "click"], [3, "BackClicked", "NavigateToRecord", "Result"]], template: function KnowledgeSearchResourceComponent_Template(rf, ctx) { if (rf & 1) {
973
+ i0.ɵɵconditionalCreate(0, KnowledgeSearchResourceComponent_Conditional_0_Template, 15, 12)(1, KnowledgeSearchResourceComponent_Conditional_1_Template, 1, 1, "app-search-result-detail", 0);
444
974
  } if (rf & 2) {
445
975
  i0.ɵɵconditional(!ctx.ShowResultDetail ? 0 : 1);
446
- } }, dependencies: [i1.DefaultValueAccessor, i1.NgControlStatus, i1.NgModel, i2.SearchResultsComponent, i2.SearchFilterComponent, i3.SearchResultDetailComponent, i4.DecimalPipe], styles: ["\n\n\n.search-page[_ngcontent-%COMP%] {\n min-height: 100%;\n display: flex;\n flex-direction: column;\n}\n\n\n\n.search-hero[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 6rem 2rem 2rem;\n transition: padding 0.4s ease;\n}\n\n.search-hero-compact[_ngcontent-%COMP%] {\n padding: 1.5rem 2rem 1rem;\n}\n\n.search-logo[_ngcontent-%COMP%] {\n font-size: 2.2rem;\n font-weight: 700;\n color: var(--mj-brand-primary);\n display: flex;\n align-items: center;\n gap: 0.75rem;\n margin-bottom: 0.5rem;\n transition: font-size 0.4s ease;\n}\n\n.search-hero-compact[_ngcontent-%COMP%] .search-logo[_ngcontent-%COMP%] {\n font-size: 0;\n height: 0;\n margin: 0;\n overflow: hidden;\n}\n\n.search-subtitle[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n font-size: 1rem;\n margin-bottom: 2rem;\n text-align: center;\n transition: all 0.4s ease;\n}\n\n.search-hero-compact[_ngcontent-%COMP%] .search-subtitle[_ngcontent-%COMP%] {\n font-size: 0;\n height: 0;\n margin: 0;\n overflow: hidden;\n opacity: 0;\n}\n\n\n\n.search-container[_ngcontent-%COMP%] {\n width: 100%;\n max-width: 720px;\n}\n\n.search-box[_ngcontent-%COMP%] {\n width: 100%;\n display: flex;\n align-items: center;\n background: var(--mj-bg-surface);\n border: 1.5px solid var(--mj-border-default);\n border-radius: 12px;\n padding: 0 0.25rem 0 1rem;\n gap: 0.5rem;\n transition: border-color 0.2s ease, box-shadow 0.2s ease;\n}\n\n.search-box[_ngcontent-%COMP%]:focus-within {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.search-box-icon[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 1rem;\n}\n\n.search-box-input[_ngcontent-%COMP%] {\n flex: 1;\n border: none;\n background: transparent;\n padding: 0.85rem 0;\n font-size: 1rem;\n color: var(--mj-text-primary);\n outline: none;\n font-family: inherit;\n}\n\n.search-box-input[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-muted);\n}\n\n.search-clear-btn[_ngcontent-%COMP%] {\n border: none;\n background: transparent;\n color: var(--mj-text-muted);\n cursor: pointer;\n padding: 0.5rem;\n border-radius: 6px;\n font-size: 0.85rem;\n}\n\n.search-clear-btn[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n}\n\n.search-submit-btn[_ngcontent-%COMP%] {\n padding: 0.55rem 1.25rem;\n border-radius: 8px;\n border: none;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 0.9rem;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.15s ease;\n white-space: nowrap;\n}\n\n.search-submit-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n.search-submit-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n\n\n.search-quick-actions[_ngcontent-%COMP%] {\n display: flex;\n justify-content: center;\n gap: 0.75rem;\n margin-top: 1rem;\n}\n\n.quick-action-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n padding: 0.45rem 1rem;\n border-radius: 9999px;\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 transition: all 0.15s ease;\n}\n\n.quick-action-btn[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n\n\n.search-results-layout[_ngcontent-%COMP%] {\n display: flex;\n flex: 1;\n gap: 1.5rem;\n padding: 0 2rem 2rem;\n max-width: 1200px;\n margin: 0 auto;\n width: 100%;\n}\n\n.search-sidebar[_ngcontent-%COMP%] {\n width: 260px;\n flex-shrink: 0;\n}\n\n.search-results-main[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n overflow-y: auto;\n max-height: calc(100vh - 220px);\n}\n\n\n\n.search-results-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 0.75rem;\n}\n\n.search-results-count[_ngcontent-%COMP%] {\n font-size: 0.85rem;\n color: var(--mj-text-secondary);\n}\n\n.search-results-time[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n}\n\n.toggle-filters-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n padding: 0.35rem 0.75rem;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 0.82rem;\n cursor: pointer;\n}\n\n.toggle-filters-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n\n\n.search-agent-cta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 1rem;\n padding: 1.25rem;\n margin-top: 1.5rem;\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n.cta-icon[_ngcontent-%COMP%] {\n font-size: 1.5rem;\n color: var(--mj-brand-primary);\n flex-shrink: 0;\n}\n\n.cta-text[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.cta-text[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n font-size: 0.9rem;\n}\n\n.cta-text[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 0.82rem;\n margin: 0.2rem 0 0;\n}\n\n.cta-btn[_ngcontent-%COMP%] {\n padding: 0.5rem 1rem;\n border-radius: 8px;\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 white-space: nowrap;\n}\n\n.cta-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary-hover);\n}\n\n\n\n.search-recent-area[_ngcontent-%COMP%] {\n max-width: 600px;\n margin: 0 auto;\n padding: 1rem 2rem;\n}\n\n.recent-title[_ngcontent-%COMP%] {\n font-size: 0.82rem;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n font-weight: 600;\n margin-bottom: 0.75rem;\n}\n\n.recent-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n}\n\n.recent-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.6rem 0.75rem;\n border-radius: 8px;\n cursor: pointer;\n transition: background 0.1s ease;\n}\n\n.recent-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.recent-icon[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 0.82rem;\n}\n\n.recent-query[_ngcontent-%COMP%] {\n flex: 1;\n color: var(--mj-text-primary);\n font-size: 0.9rem;\n}\n\n.recent-count[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 0.78rem;\n}\n\n\n\n.threshold-section[_ngcontent-%COMP%] {\n margin-top: 1.25rem;\n padding-top: 1rem;\n border-top: 1px solid var(--mj-border-subtle);\n}\n\n.threshold-label[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n font-size: 0.82rem;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n margin-bottom: 0.5rem;\n}\n\n.threshold-value[_ngcontent-%COMP%] {\n font-weight: 700;\n color: var(--mj-brand-primary);\n font-size: 0.85rem;\n}\n\n.threshold-slider[_ngcontent-%COMP%] {\n width: 100%;\n height: 4px;\n appearance: none;\n -webkit-appearance: none;\n background: var(--mj-border-default);\n border-radius: 2px;\n outline: none;\n cursor: pointer;\n}\n\n.threshold-slider[_ngcontent-%COMP%]::-webkit-slider-thumb {\n -webkit-appearance: none;\n width: 16px;\n height: 16px;\n border-radius: 50%;\n background: var(--mj-brand-primary);\n border: 2px solid var(--mj-bg-surface);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n cursor: pointer;\n}\n\n.threshold-slider[_ngcontent-%COMP%]::-moz-range-thumb {\n width: 16px;\n height: 16px;\n border-radius: 50%;\n background: var(--mj-brand-primary);\n border: 2px solid var(--mj-bg-surface);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n cursor: pointer;\n}\n\n.threshold-range-labels[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n font-size: 0.72rem;\n color: var(--mj-text-muted);\n margin-top: 0.25rem;\n}\n\n\n\n@media (max-width: 768px) {\n .search-results-layout[_ngcontent-%COMP%] {\n flex-direction: column;\n padding: 0 1rem 1rem;\n }\n\n .search-sidebar[_ngcontent-%COMP%] {\n width: 100%;\n }\n\n .search-hero[_ngcontent-%COMP%] {\n padding: 3rem 1rem 1rem;\n }\n}"] });
976
+ } }, dependencies: [i1.DefaultValueAccessor, i1.NgControlStatus, i1.NgModel, i2.SearchResultsComponent, i2.SearchFilterComponent, i3.SearchResultDetailComponent, i4.DecimalPipe], styles: ["\n\n\n.search-page[_ngcontent-%COMP%] {\n min-height: 100%;\n display: flex;\n flex-direction: column;\n}\n\n\n\n.search-hero[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 6rem 2rem 2rem;\n transition: padding 0.4s ease;\n}\n\n.search-hero-compact[_ngcontent-%COMP%] {\n padding: 1.5rem 2rem 1rem;\n}\n\n.search-logo[_ngcontent-%COMP%] {\n font-size: 2.2rem;\n font-weight: 700;\n color: var(--mj-brand-primary);\n display: flex;\n align-items: center;\n gap: 0.75rem;\n margin-bottom: 0.5rem;\n transition: font-size 0.4s ease;\n}\n\n.search-hero-compact[_ngcontent-%COMP%] .search-logo[_ngcontent-%COMP%] {\n font-size: 0;\n height: 0;\n margin: 0;\n overflow: hidden;\n}\n\n.search-subtitle[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n font-size: 1rem;\n margin-bottom: 2rem;\n text-align: center;\n transition: all 0.4s ease;\n}\n\n.search-hero-compact[_ngcontent-%COMP%] .search-subtitle[_ngcontent-%COMP%] {\n font-size: 0;\n height: 0;\n margin: 0;\n overflow: hidden;\n opacity: 0;\n}\n\n\n\n.search-container[_ngcontent-%COMP%] {\n width: 100%;\n max-width: 720px;\n}\n\n.search-box[_ngcontent-%COMP%] {\n width: 100%;\n display: flex;\n align-items: center;\n background: var(--mj-bg-surface);\n border: 1.5px solid var(--mj-border-default);\n border-radius: 12px;\n padding: 0 0.25rem 0 1rem;\n gap: 0.5rem;\n transition: border-color 0.2s ease, box-shadow 0.2s ease;\n}\n\n.search-box[_ngcontent-%COMP%]:focus-within {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.search-box-icon[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 1rem;\n}\n\n.search-box-input[_ngcontent-%COMP%] {\n flex: 1;\n border: none;\n background: transparent;\n padding: 0.85rem 0;\n font-size: 1rem;\n color: var(--mj-text-primary);\n outline: none;\n font-family: inherit;\n}\n\n.search-box-input[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-muted);\n}\n\n.search-clear-btn[_ngcontent-%COMP%] {\n border: none;\n background: transparent;\n color: var(--mj-text-muted);\n cursor: pointer;\n padding: 0.5rem;\n border-radius: 6px;\n font-size: 0.85rem;\n}\n\n.search-clear-btn[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n}\n\n.search-submit-btn[_ngcontent-%COMP%] {\n padding: 0.55rem 1.25rem;\n border-radius: 8px;\n border: none;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 0.9rem;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.15s ease;\n white-space: nowrap;\n}\n\n.search-submit-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n.search-submit-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n\n\n.search-quick-actions[_ngcontent-%COMP%] {\n display: flex;\n justify-content: center;\n gap: 0.75rem;\n margin-top: 1rem;\n}\n\n.quick-action-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n padding: 0.45rem 1rem;\n border-radius: 9999px;\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 transition: all 0.15s ease;\n}\n\n.quick-action-btn[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n\n\n.search-tag-presets[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 0.4rem;\n margin-top: 0.5rem;\n}\n\n.tag-presets-label[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n font-size: 0.78rem;\n color: var(--mj-text-muted);\n margin-right: 0.25rem;\n}\n\n.tag-preset-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 0.25rem 0.65rem;\n border-radius: 9999px;\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, var(--mj-border-default));\n background: color-mix(in srgb, var(--mj-brand-primary) 6%, var(--mj-bg-surface));\n color: var(--mj-text-secondary);\n font-size: 0.78rem;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.tag-preset-btn[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n}\n\n\n\n.search-results-layout[_ngcontent-%COMP%] {\n display: flex;\n flex: 1;\n gap: 1.5rem;\n padding: 0 2rem 2rem;\n max-width: 1200px;\n margin: 0 auto;\n width: 100%;\n}\n\n.search-sidebar[_ngcontent-%COMP%] {\n width: 260px;\n flex-shrink: 0;\n}\n\n.search-results-main[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n max-height: calc(100vh - 220px);\n overflow: hidden;\n}\n\n\n\n.search-results-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n margin-bottom: 0.75rem;\n flex-shrink: 0;\n}\n\n.search-results-count[_ngcontent-%COMP%] {\n font-size: 0.85rem;\n color: var(--mj-text-secondary);\n}\n\n.search-results-time[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n}\n\n\n\n.show-filters-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n padding: 0.35rem 0.75rem;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 0.82rem;\n cursor: pointer;\n transition: all 0.15s;\n flex-shrink: 0;\n}\n\n.show-filters-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n.filter-active-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 18px;\n height: 18px;\n padding: 0 5px;\n border-radius: 9px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 0.65rem;\n font-weight: 700;\n}\n\n\n\n.search-agent-cta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 1rem;\n padding: 1.25rem;\n margin-top: 1.5rem;\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n.cta-icon[_ngcontent-%COMP%] {\n font-size: 1.5rem;\n color: var(--mj-brand-primary);\n flex-shrink: 0;\n}\n\n.cta-text[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.cta-text[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n font-size: 0.9rem;\n}\n\n.cta-text[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 0.82rem;\n margin: 0.2rem 0 0;\n}\n\n.cta-btn[_ngcontent-%COMP%] {\n padding: 0.5rem 1rem;\n border-radius: 8px;\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 white-space: nowrap;\n}\n\n.cta-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary-hover);\n}\n\n\n\n.search-recent-area[_ngcontent-%COMP%] {\n max-width: 600px;\n margin: 0 auto;\n padding: 1rem 2rem;\n}\n\n.recent-title[_ngcontent-%COMP%] {\n font-size: 0.82rem;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n font-weight: 600;\n margin-bottom: 0.75rem;\n}\n\n.recent-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n}\n\n.recent-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.6rem 0.75rem;\n border-radius: 8px;\n cursor: pointer;\n transition: background 0.1s ease;\n}\n\n.recent-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.recent-icon[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 0.82rem;\n}\n\n.recent-query[_ngcontent-%COMP%] {\n flex: 1;\n color: var(--mj-text-primary);\n font-size: 0.9rem;\n}\n\n.recent-count[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 0.78rem;\n}\n\n\n\n.threshold-section[_ngcontent-%COMP%] {\n margin-top: 1.25rem;\n padding-top: 1rem;\n border-top: 1px solid var(--mj-border-subtle);\n}\n\n.threshold-label[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n font-size: 0.82rem;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n margin-bottom: 0.5rem;\n}\n\n.threshold-value[_ngcontent-%COMP%] {\n font-weight: 700;\n color: var(--mj-brand-primary);\n font-size: 0.85rem;\n}\n\n.threshold-slider[_ngcontent-%COMP%] {\n width: 100%;\n height: 4px;\n appearance: none;\n -webkit-appearance: none;\n background: var(--mj-border-default);\n border-radius: 2px;\n outline: none;\n cursor: pointer;\n}\n\n.threshold-slider[_ngcontent-%COMP%]::-webkit-slider-thumb {\n -webkit-appearance: none;\n width: 16px;\n height: 16px;\n border-radius: 50%;\n background: var(--mj-brand-primary);\n border: 2px solid var(--mj-bg-surface);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n cursor: pointer;\n}\n\n.threshold-slider[_ngcontent-%COMP%]::-moz-range-thumb {\n width: 16px;\n height: 16px;\n border-radius: 50%;\n background: var(--mj-brand-primary);\n border: 2px solid var(--mj-bg-surface);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n cursor: pointer;\n}\n\n.threshold-range-labels[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n font-size: 0.72rem;\n color: var(--mj-text-muted);\n margin-top: 0.25rem;\n}\n\n.threshold-stats[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.15rem;\n margin-top: 0.6rem;\n padding: 0.45rem 0.6rem;\n border-radius: 6px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-subtle);\n}\n\n.threshold-stats-shown[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.threshold-stats-range[_ngcontent-%COMP%] {\n font-size: 0.7rem;\n color: var(--mj-text-muted);\n}\n\n\n\n.save-search-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n padding: 0.3rem 0.65rem;\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.78rem;\n cursor: pointer;\n transition: all 0.15s;\n margin-left: auto;\n}\n\n.save-search-btn[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n\n\n.saved-icon[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 0.82rem;\n}\n\n.saved-item[_ngcontent-%COMP%] {\n position: relative;\n}\n\n.saved-query-text[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 0.78rem;\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.saved-delete-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border: none;\n border-radius: 4px;\n background: transparent;\n color: var(--mj-text-muted);\n font-size: 0.7rem;\n cursor: pointer;\n opacity: 0;\n transition: all 0.15s;\n flex-shrink: 0;\n}\n\n.saved-item[_ngcontent-%COMP%]:hover .saved-delete-btn[_ngcontent-%COMP%] {\n opacity: 1;\n}\n\n.saved-delete-btn[_ngcontent-%COMP%]:hover {\n color: var(--mj-status-error);\n background: var(--mj-status-error-bg);\n}\n\n\n\n.save-dialog-overlay[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n}\n\n.save-dialog[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n padding: 1.5rem;\n width: 400px;\n max-width: 90vw;\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15);\n}\n\n.save-dialog-title[_ngcontent-%COMP%] {\n margin: 0 0 0.25rem;\n font-size: 1.1rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.save-dialog-subtitle[_ngcontent-%COMP%] {\n margin: 0 0 1rem;\n font-size: 0.82rem;\n color: var(--mj-text-muted);\n}\n\n.save-dialog-label[_ngcontent-%COMP%] {\n display: block;\n font-size: 0.78rem;\n font-weight: 600;\n color: var(--mj-text-secondary);\n margin-bottom: 0.35rem;\n}\n\n.save-dialog-input[_ngcontent-%COMP%] {\n width: 100%;\n box-sizing: border-box;\n margin-bottom: 1rem;\n}\n\n.save-dialog-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.5rem;\n}\n\n.save-dialog-confirm[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n padding: 0.5rem 1rem;\n border: none;\n border-radius: 6px;\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 transition: background 0.15s;\n}\n\n.save-dialog-confirm[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n.save-dialog-confirm[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.save-dialog-cancel[_ngcontent-%COMP%] {\n padding: 0.5rem 1rem;\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.85rem;\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.save-dialog-cancel[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n\n\n@media (max-width: 768px) {\n .search-results-layout[_ngcontent-%COMP%] {\n flex-direction: column;\n padding: 0 1rem 1rem;\n }\n\n .search-sidebar[_ngcontent-%COMP%] {\n width: 100%;\n }\n\n .search-hero[_ngcontent-%COMP%] {\n padding: 3rem 1rem 1rem;\n }\n}"] });
447
977
  };
448
- KnowledgeSearchResourceComponent = __decorate([
978
+ KnowledgeSearchResourceComponent = KnowledgeSearchResourceComponent_1 = __decorate([
449
979
  RegisterClass(BaseResourceComponent, 'KnowledgeSearchResource')
450
980
  ], KnowledgeSearchResourceComponent);
451
981
  export { KnowledgeSearchResourceComponent };
452
982
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(KnowledgeSearchResourceComponent, [{
453
983
  type: Component,
454
- args: [{ standalone: false, selector: 'app-knowledge-search-resource', template: "@if (!ShowResultDetail) {\n <div class=\"search-page\" [class.search-page-has-results]=\"HasSearched\">\n <!-- Search Hero Section -->\n <div class=\"search-hero\" [class.search-hero-compact]=\"HasSearched\">\n @if (!HasSearched) {\n <div class=\"search-logo\">\n <i class=\"fa-solid fa-brain\"></i>\n Knowledge Hub\n </div>\n <p class=\"search-subtitle\">Search across all your knowledge -- entities, documents, content, and more</p>\n }\n\n <!-- Search Bar -->\n <div class=\"search-container\">\n <div class=\"search-box\">\n <i class=\"fa-solid fa-magnifying-glass search-box-icon\"></i>\n <input\n type=\"text\"\n class=\"search-box-input\"\n placeholder=\"Search across all your knowledge...\"\n [(ngModel)]=\"Query\"\n (keydown)=\"OnSearchKeydown($event)\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n />\n @if (Query.length > 0) {\n <button class=\"search-clear-btn\" (click)=\"ClearSearch()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n }\n <button class=\"search-submit-btn\" (click)=\"RunSearch()\" [disabled]=\"IsSearching || !Query.trim()\">\n @if (IsSearching) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n } @else {\n Search\n }\n </button>\n </div>\n\n <!-- Quick filters row -->\n @if (!HasSearched) {\n <div class=\"search-quick-actions\">\n <button class=\"quick-action-btn\" (click)=\"OnAskAgent()\">\n <i class=\"fa-solid fa-robot\"></i>\n Ask Knowledge Agent\n </button>\n </div>\n }\n </div>\n </div>\n\n @if (HasSearched) {\n <!-- Results Area -->\n <div class=\"search-results-layout\">\n <!-- Sidebar Filters -->\n @if (ShowFilters && Filters.length > 0) {\n <aside class=\"search-sidebar\">\n <mj-search-filter\n [Filters]=\"Filters\"\n [ActiveFilters]=\"ActiveFilters\"\n (FilterChanged)=\"OnFilterChanged($event)\"\n (FiltersCleared)=\"OnFiltersCleared()\"\n ></mj-search-filter>\n\n <!-- Relevance Threshold Slider -->\n <div class=\"threshold-section\">\n <label class=\"threshold-label\">\n Min Relevance\n <span class=\"threshold-value\">{{ (MinScoreThreshold * 100) | number:'1.0-0' }}%</span>\n </label>\n <input\n type=\"range\"\n class=\"threshold-slider\"\n [min]=\"0\"\n [max]=\"100\"\n [step]=\"5\"\n [value]=\"MinScoreThreshold * 100\"\n (input)=\"OnThresholdChanged($any($event.target).value / 100)\"\n />\n <div class=\"threshold-range-labels\">\n <span>All</span>\n <span>Strict</span>\n </div>\n </div>\n </aside>\n }\n\n <!-- Results Main -->\n <div class=\"search-results-main\">\n <!-- Results Header -->\n <div class=\"search-results-header\">\n <span class=\"search-results-count\">\n {{ TotalCount }} results\n @if (ElapsedMs > 0) {\n <span class=\"search-results-time\">in {{ ElapsedMs }}ms</span>\n }\n </span>\n <div class=\"search-results-actions\">\n @if (Filters.length > 0) {\n <button class=\"toggle-filters-btn\" (click)=\"ToggleFilters()\">\n <i class=\"fa-solid fa-filter\"></i>\n @if (HasActiveFilters()) {\n Filters Active\n } @else {\n Filters\n }\n </button>\n }\n </div>\n </div>\n\n <!-- Results List -->\n <mj-search-results\n [ResultGroups]=\"ResultGroups\"\n [IsLoading]=\"IsSearching\"\n [TotalCount]=\"TotalCount\"\n [ElapsedMs]=\"ElapsedMs\"\n (ResultSelected)=\"OnResultSelected($event)\"\n (OpenRecordRequested)=\"OnOpenRecord($event)\"\n ></mj-search-results>\n\n <!-- Agent CTA at bottom -->\n @if (TotalCount === 0 && !IsSearching) {\n <div class=\"search-agent-cta\">\n <i class=\"fa-solid fa-robot cta-icon\"></i>\n <div class=\"cta-text\">\n <strong>Can't find what you're looking for?</strong>\n <p>Ask the Knowledge Agent for a deeper analysis</p>\n </div>\n <button class=\"cta-btn\" (click)=\"OnAskAgent()\">\n Ask Agent\n </button>\n </div>\n }\n </div>\n </div>\n } @else if (!IsSearching) {\n <!-- Empty state: recent searches -->\n <div class=\"search-recent-area\">\n @if (RecentSearches.length > 0) {\n <h3 class=\"recent-title\">Recent Searches</h3>\n <div class=\"recent-list\">\n @for (recent of RecentSearches; track recent.Query; let i = $index) {\n @if (i < 8) {\n <div class=\"recent-item\" (click)=\"ApplyRecentSearch(recent)\">\n <i class=\"fa-solid fa-clock recent-icon\"></i>\n <span class=\"recent-query\">{{ recent.Query }}</span>\n <span class=\"recent-count\">{{ recent.ResultCount }} results</span>\n </div>\n }\n }\n </div>\n }\n </div>\n }\n </div>\n} @else {\n <!-- Result Detail View (Task 8) -->\n <app-search-result-detail\n [Result]=\"DetailResult\"\n (BackClicked)=\"CloseResultDetail()\"\n (NavigateToRecord)=\"OnOpenRecord($event)\"\n ></app-search-result-detail>\n}\n", styles: ["/* Knowledge Search Resource - Google-style clean */\n\n.search-page {\n min-height: 100%;\n display: flex;\n flex-direction: column;\n}\n\n/* Search Hero */\n.search-hero {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 6rem 2rem 2rem;\n transition: padding 0.4s ease;\n}\n\n.search-hero-compact {\n padding: 1.5rem 2rem 1rem;\n}\n\n.search-logo {\n font-size: 2.2rem;\n font-weight: 700;\n color: var(--mj-brand-primary);\n display: flex;\n align-items: center;\n gap: 0.75rem;\n margin-bottom: 0.5rem;\n transition: font-size 0.4s ease;\n}\n\n.search-hero-compact .search-logo {\n font-size: 0;\n height: 0;\n margin: 0;\n overflow: hidden;\n}\n\n.search-subtitle {\n color: var(--mj-text-secondary);\n font-size: 1rem;\n margin-bottom: 2rem;\n text-align: center;\n transition: all 0.4s ease;\n}\n\n.search-hero-compact .search-subtitle {\n font-size: 0;\n height: 0;\n margin: 0;\n overflow: hidden;\n opacity: 0;\n}\n\n/* Search Box */\n.search-container {\n width: 100%;\n max-width: 720px;\n}\n\n.search-box {\n width: 100%;\n display: flex;\n align-items: center;\n background: var(--mj-bg-surface);\n border: 1.5px solid var(--mj-border-default);\n border-radius: 12px;\n padding: 0 0.25rem 0 1rem;\n gap: 0.5rem;\n transition: border-color 0.2s ease, box-shadow 0.2s ease;\n}\n\n.search-box:focus-within {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.search-box-icon {\n color: var(--mj-text-muted);\n font-size: 1rem;\n}\n\n.search-box-input {\n flex: 1;\n border: none;\n background: transparent;\n padding: 0.85rem 0;\n font-size: 1rem;\n color: var(--mj-text-primary);\n outline: none;\n font-family: inherit;\n}\n\n.search-box-input::placeholder {\n color: var(--mj-text-muted);\n}\n\n.search-clear-btn {\n border: none;\n background: transparent;\n color: var(--mj-text-muted);\n cursor: pointer;\n padding: 0.5rem;\n border-radius: 6px;\n font-size: 0.85rem;\n}\n\n.search-clear-btn:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n}\n\n.search-submit-btn {\n padding: 0.55rem 1.25rem;\n border-radius: 8px;\n border: none;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 0.9rem;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.15s ease;\n white-space: nowrap;\n}\n\n.search-submit-btn:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n.search-submit-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n/* Quick Actions */\n.search-quick-actions {\n display: flex;\n justify-content: center;\n gap: 0.75rem;\n margin-top: 1rem;\n}\n\n.quick-action-btn {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n padding: 0.45rem 1rem;\n border-radius: 9999px;\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 transition: all 0.15s ease;\n}\n\n.quick-action-btn:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n/* Results Layout */\n.search-results-layout {\n display: flex;\n flex: 1;\n gap: 1.5rem;\n padding: 0 2rem 2rem;\n max-width: 1200px;\n margin: 0 auto;\n width: 100%;\n}\n\n.search-sidebar {\n width: 260px;\n flex-shrink: 0;\n}\n\n.search-results-main {\n flex: 1;\n min-width: 0;\n overflow-y: auto;\n max-height: calc(100vh - 220px);\n}\n\n/* Results Header */\n.search-results-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 0.75rem;\n}\n\n.search-results-count {\n font-size: 0.85rem;\n color: var(--mj-text-secondary);\n}\n\n.search-results-time {\n color: var(--mj-text-muted);\n}\n\n.toggle-filters-btn {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n padding: 0.35rem 0.75rem;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 0.82rem;\n cursor: pointer;\n}\n\n.toggle-filters-btn:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n/* Agent CTA */\n.search-agent-cta {\n display: flex;\n align-items: center;\n gap: 1rem;\n padding: 1.25rem;\n margin-top: 1.5rem;\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n.cta-icon {\n font-size: 1.5rem;\n color: var(--mj-brand-primary);\n flex-shrink: 0;\n}\n\n.cta-text {\n flex: 1;\n}\n\n.cta-text strong {\n color: var(--mj-text-primary);\n font-size: 0.9rem;\n}\n\n.cta-text p {\n color: var(--mj-text-muted);\n font-size: 0.82rem;\n margin: 0.2rem 0 0;\n}\n\n.cta-btn {\n padding: 0.5rem 1rem;\n border-radius: 8px;\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 white-space: nowrap;\n}\n\n.cta-btn:hover {\n background: var(--mj-brand-primary-hover);\n}\n\n/* Recent Searches */\n.search-recent-area {\n max-width: 600px;\n margin: 0 auto;\n padding: 1rem 2rem;\n}\n\n.recent-title {\n font-size: 0.82rem;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n font-weight: 600;\n margin-bottom: 0.75rem;\n}\n\n.recent-list {\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n}\n\n.recent-item {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.6rem 0.75rem;\n border-radius: 8px;\n cursor: pointer;\n transition: background 0.1s ease;\n}\n\n.recent-item:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.recent-icon {\n color: var(--mj-text-muted);\n font-size: 0.82rem;\n}\n\n.recent-query {\n flex: 1;\n color: var(--mj-text-primary);\n font-size: 0.9rem;\n}\n\n.recent-count {\n color: var(--mj-text-muted);\n font-size: 0.78rem;\n}\n\n/* Relevance Threshold */\n.threshold-section {\n margin-top: 1.25rem;\n padding-top: 1rem;\n border-top: 1px solid var(--mj-border-subtle);\n}\n\n.threshold-label {\n display: flex;\n justify-content: space-between;\n align-items: center;\n font-size: 0.82rem;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n margin-bottom: 0.5rem;\n}\n\n.threshold-value {\n font-weight: 700;\n color: var(--mj-brand-primary);\n font-size: 0.85rem;\n}\n\n.threshold-slider {\n width: 100%;\n height: 4px;\n appearance: none;\n -webkit-appearance: none;\n background: var(--mj-border-default);\n border-radius: 2px;\n outline: none;\n cursor: pointer;\n}\n\n.threshold-slider::-webkit-slider-thumb {\n -webkit-appearance: none;\n width: 16px;\n height: 16px;\n border-radius: 50%;\n background: var(--mj-brand-primary);\n border: 2px solid var(--mj-bg-surface);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n cursor: pointer;\n}\n\n.threshold-slider::-moz-range-thumb {\n width: 16px;\n height: 16px;\n border-radius: 50%;\n background: var(--mj-brand-primary);\n border: 2px solid var(--mj-bg-surface);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n cursor: pointer;\n}\n\n.threshold-range-labels {\n display: flex;\n justify-content: space-between;\n font-size: 0.72rem;\n color: var(--mj-text-muted);\n margin-top: 0.25rem;\n}\n\n/* Mobile responsive */\n@media (max-width: 768px) {\n .search-results-layout {\n flex-direction: column;\n padding: 0 1rem 1rem;\n }\n\n .search-sidebar {\n width: 100%;\n }\n\n .search-hero {\n padding: 3rem 1rem 1rem;\n }\n}\n"] }]
984
+ args: [{ standalone: false, selector: 'app-knowledge-search-resource', template: "@if (!ShowResultDetail) {\n <div class=\"search-page\" [class.search-page-has-results]=\"HasSearched\">\n <!-- Search Hero Section -->\n <div class=\"search-hero\" [class.search-hero-compact]=\"HasSearched\">\n @if (!HasSearched) {\n <div class=\"search-logo\">\n <i class=\"fa-solid fa-brain\"></i>\n Knowledge Hub\n </div>\n <p class=\"search-subtitle\">Search across all your knowledge -- entities, documents, content, and more</p>\n }\n\n <!-- Search Bar -->\n <div class=\"search-container\">\n <div class=\"search-box\">\n <i class=\"fa-solid fa-magnifying-glass search-box-icon\"></i>\n <input\n type=\"text\"\n class=\"search-box-input\"\n placeholder=\"Search across all your knowledge...\"\n [(ngModel)]=\"Query\"\n (keydown)=\"OnSearchKeydown($event)\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n />\n @if (Query.length > 0) {\n <button class=\"search-clear-btn\" (click)=\"ClearSearch()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n }\n <button class=\"search-submit-btn\" (click)=\"RunSearch()\" [disabled]=\"IsSearching || !Query.trim()\">\n @if (IsSearching) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n } @else {\n Search\n }\n </button>\n </div>\n\n <!-- Quick filters row -->\n @if (!HasSearched) {\n <div class=\"search-quick-actions\">\n <button class=\"quick-action-btn\" (click)=\"OnAskAgent()\">\n <i class=\"fa-solid fa-robot\"></i>\n Ask Knowledge Agent\n </button>\n </div>\n @if (PopularTags.length > 0) {\n <div class=\"search-tag-presets\">\n <span class=\"tag-presets-label\">\n <i class=\"fa-solid fa-tags\"></i> Popular tags:\n </span>\n @for (tag of PopularTags; track tag.Name) {\n <button class=\"tag-preset-btn\"\n [style.fontSize.rem]=\"tag.FontSize\"\n [title]=\"tag.Name + ' (' + tag.Count + ')'\"\n (click)=\"FilterByTag(tag.Name)\">\n {{ tag.Name }}\n </button>\n }\n </div>\n }\n }\n </div>\n </div>\n\n @if (HasSearched) {\n <!-- Results Area -->\n <div class=\"search-results-layout\">\n <!-- Sidebar Filters -->\n @if (ShowFilters && Filters.length > 0) {\n <aside class=\"search-sidebar\">\n <mj-search-filter\n [Filters]=\"Filters\"\n [ActiveFilters]=\"ActiveFilters\"\n (FilterChanged)=\"OnFilterChanged($event)\"\n (FiltersCleared)=\"OnFiltersCleared()\"\n (CloseRequested)=\"ToggleFilters()\"\n ></mj-search-filter>\n\n <!-- Relevance Threshold Slider -->\n <div class=\"threshold-section\">\n <label class=\"threshold-label\">\n Min Relevance\n <span class=\"threshold-value\">{{ (MinScoreThreshold * 100) | number:'1.0-0' }}%</span>\n </label>\n <input\n type=\"range\"\n class=\"threshold-slider\"\n [min]=\"0\"\n [max]=\"100\"\n [step]=\"5\"\n [value]=\"MinScoreThreshold * 100\"\n (input)=\"OnThresholdChanged($any($event.target).value / 100)\"\n />\n <div class=\"threshold-range-labels\">\n <span>All</span>\n <span>Strict</span>\n </div>\n <div class=\"threshold-stats\">\n <span class=\"threshold-stats-shown\">{{ TotalCount }} of {{ ServerResultCount }} results shown</span>\n <span class=\"threshold-stats-range\">Server range: {{ (ServerMinRelevance * 100) | number:'1.0-0' }}%&ndash;100%</span>\n </div>\n </div>\n </aside>\n }\n\n <!-- Results Main -->\n <div class=\"search-results-main\">\n <!-- Results Header -->\n <div class=\"search-results-header\">\n <!-- Show Filters button on left (visible when panel is hidden) -->\n @if (!ShowFilters && Filters.length > 0) {\n <button class=\"show-filters-btn\" (click)=\"ToggleFilters()\">\n <i class=\"fa-solid fa-filter\"></i>\n Filters\n @if (HasActiveFilters()) {\n <span class=\"filter-active-badge\">{{ GetActiveFilterCount() }}</span>\n }\n </button>\n }\n <span class=\"search-results-count\">\n {{ TotalCount }} results\n @if (ElapsedMs > 0) {\n <span class=\"search-results-time\">in {{ ElapsedMs }}ms</span>\n }\n </span>\n <button class=\"save-search-btn\" (click)=\"OpenSaveDialog()\" title=\"Save this search\">\n <i class=\"fa-solid fa-bookmark\"></i>\n Save Search\n </button>\n </div>\n\n <!-- Results List (flat blended list sorted by relevance) -->\n <mj-search-results\n DisplayMode=\"flat\"\n [ShowSummary]=\"false\"\n [FlatResults]=\"AllResults\"\n [ResultGroups]=\"ResultGroups\"\n [IsLoading]=\"IsSearching\"\n [TotalCount]=\"TotalCount\"\n [ElapsedMs]=\"ElapsedMs\"\n (ResultSelected)=\"OnResultSelected($event)\"\n (OpenRecordRequested)=\"OnOpenRecord($event)\"\n (MoreLikeThisRequested)=\"OnMoreLikeThis($event)\"\n ></mj-search-results>\n\n <!-- Agent CTA at bottom -->\n @if (TotalCount === 0 && !IsSearching) {\n <div class=\"search-agent-cta\">\n <i class=\"fa-solid fa-robot cta-icon\"></i>\n <div class=\"cta-text\">\n <strong>Can't find what you're looking for?</strong>\n <p>Ask the Knowledge Agent for a deeper analysis</p>\n </div>\n <button class=\"cta-btn\" (click)=\"OnAskAgent()\">\n Ask Agent\n </button>\n </div>\n }\n </div>\n </div>\n } @else if (!IsSearching) {\n <!-- Empty state: recent & saved searches -->\n <div class=\"search-recent-area\">\n @if (SavedSearches.length > 0) {\n <h3 class=\"recent-title\">Saved Searches</h3>\n <div class=\"recent-list\">\n @for (saved of SavedSearches; track saved.ID; let i = $index) {\n @if (i < 8) {\n <div class=\"recent-item saved-item\" (click)=\"ApplySavedSearch(saved)\">\n <i class=\"fa-solid fa-bookmark saved-icon\"></i>\n <span class=\"recent-query\">{{ saved.Name }}</span>\n <span class=\"saved-query-text\">{{ saved.Query }}</span>\n <button class=\"saved-delete-btn\" (click)=\"DeleteSavedSearch(saved, $event)\" title=\"Delete saved search\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n }\n }\n </div>\n }\n\n @if (RecentSearches.length > 0) {\n <h3 class=\"recent-title\">Recent Searches</h3>\n <div class=\"recent-list\">\n @for (recent of RecentSearches; track recent.Query; let i = $index) {\n @if (i < 8) {\n <div class=\"recent-item\" (click)=\"ApplyRecentSearch(recent)\">\n <i class=\"fa-solid fa-clock recent-icon\"></i>\n <span class=\"recent-query\">{{ recent.Query }}</span>\n <span class=\"recent-count\">{{ recent.ResultCount }} results</span>\n </div>\n }\n }\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Save Search Dialog Overlay -->\n @if (ShowSaveDialog) {\n <div class=\"save-dialog-overlay\" (click)=\"CancelSaveDialog()\">\n <div class=\"save-dialog\" (click)=\"$event.stopPropagation()\">\n <h3 class=\"save-dialog-title\">Save Search</h3>\n <p class=\"save-dialog-subtitle\">Save \"{{ Query }}\" for quick access later</p>\n <label class=\"save-dialog-label\">Name</label>\n <input\n type=\"text\"\n class=\"mj-input save-dialog-input\"\n [(ngModel)]=\"SaveSearchName\"\n placeholder=\"Give this search a name...\"\n (keydown.enter)=\"ConfirmSaveSearch()\"\n autofocus\n />\n <div class=\"save-dialog-actions\">\n <button class=\"save-dialog-confirm\" (click)=\"ConfirmSaveSearch()\" [disabled]=\"!SaveSearchName.trim()\">\n <i class=\"fa-solid fa-bookmark\"></i> Save\n </button>\n <button class=\"save-dialog-cancel\" (click)=\"CancelSaveDialog()\">Cancel</button>\n </div>\n </div>\n </div>\n }\n} @else {\n <!-- Result Detail View (Task 8) -->\n <app-search-result-detail\n [Result]=\"DetailResult\"\n (BackClicked)=\"CloseResultDetail()\"\n (NavigateToRecord)=\"OnOpenRecord($event)\"\n ></app-search-result-detail>\n}\n", styles: ["/* Knowledge Search Resource - Google-style clean */\n\n.search-page {\n min-height: 100%;\n display: flex;\n flex-direction: column;\n}\n\n/* Search Hero */\n.search-hero {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 6rem 2rem 2rem;\n transition: padding 0.4s ease;\n}\n\n.search-hero-compact {\n padding: 1.5rem 2rem 1rem;\n}\n\n.search-logo {\n font-size: 2.2rem;\n font-weight: 700;\n color: var(--mj-brand-primary);\n display: flex;\n align-items: center;\n gap: 0.75rem;\n margin-bottom: 0.5rem;\n transition: font-size 0.4s ease;\n}\n\n.search-hero-compact .search-logo {\n font-size: 0;\n height: 0;\n margin: 0;\n overflow: hidden;\n}\n\n.search-subtitle {\n color: var(--mj-text-secondary);\n font-size: 1rem;\n margin-bottom: 2rem;\n text-align: center;\n transition: all 0.4s ease;\n}\n\n.search-hero-compact .search-subtitle {\n font-size: 0;\n height: 0;\n margin: 0;\n overflow: hidden;\n opacity: 0;\n}\n\n/* Search Box */\n.search-container {\n width: 100%;\n max-width: 720px;\n}\n\n.search-box {\n width: 100%;\n display: flex;\n align-items: center;\n background: var(--mj-bg-surface);\n border: 1.5px solid var(--mj-border-default);\n border-radius: 12px;\n padding: 0 0.25rem 0 1rem;\n gap: 0.5rem;\n transition: border-color 0.2s ease, box-shadow 0.2s ease;\n}\n\n.search-box:focus-within {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.search-box-icon {\n color: var(--mj-text-muted);\n font-size: 1rem;\n}\n\n.search-box-input {\n flex: 1;\n border: none;\n background: transparent;\n padding: 0.85rem 0;\n font-size: 1rem;\n color: var(--mj-text-primary);\n outline: none;\n font-family: inherit;\n}\n\n.search-box-input::placeholder {\n color: var(--mj-text-muted);\n}\n\n.search-clear-btn {\n border: none;\n background: transparent;\n color: var(--mj-text-muted);\n cursor: pointer;\n padding: 0.5rem;\n border-radius: 6px;\n font-size: 0.85rem;\n}\n\n.search-clear-btn:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n}\n\n.search-submit-btn {\n padding: 0.55rem 1.25rem;\n border-radius: 8px;\n border: none;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 0.9rem;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.15s ease;\n white-space: nowrap;\n}\n\n.search-submit-btn:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n.search-submit-btn:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n/* Quick Actions */\n.search-quick-actions {\n display: flex;\n justify-content: center;\n gap: 0.75rem;\n margin-top: 1rem;\n}\n\n.quick-action-btn {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n padding: 0.45rem 1rem;\n border-radius: 9999px;\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 transition: all 0.15s ease;\n}\n\n.quick-action-btn:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n/* Tag Preset Buttons */\n.search-tag-presets {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 0.4rem;\n margin-top: 0.5rem;\n}\n\n.tag-presets-label {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n font-size: 0.78rem;\n color: var(--mj-text-muted);\n margin-right: 0.25rem;\n}\n\n.tag-preset-btn {\n display: inline-flex;\n align-items: center;\n padding: 0.25rem 0.65rem;\n border-radius: 9999px;\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, var(--mj-border-default));\n background: color-mix(in srgb, var(--mj-brand-primary) 6%, var(--mj-bg-surface));\n color: var(--mj-text-secondary);\n font-size: 0.78rem;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.tag-preset-btn:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n}\n\n/* Results Layout */\n.search-results-layout {\n display: flex;\n flex: 1;\n gap: 1.5rem;\n padding: 0 2rem 2rem;\n max-width: 1200px;\n margin: 0 auto;\n width: 100%;\n}\n\n.search-sidebar {\n width: 260px;\n flex-shrink: 0;\n}\n\n.search-results-main {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n max-height: calc(100vh - 220px);\n overflow: hidden;\n}\n\n/* Results Header */\n.search-results-header {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n margin-bottom: 0.75rem;\n flex-shrink: 0;\n}\n\n.search-results-count {\n font-size: 0.85rem;\n color: var(--mj-text-secondary);\n}\n\n.search-results-time {\n color: var(--mj-text-muted);\n}\n\n/* Show Filters button \u2014 appears on left when panel is hidden */\n.show-filters-btn {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n padding: 0.35rem 0.75rem;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 0.82rem;\n cursor: pointer;\n transition: all 0.15s;\n flex-shrink: 0;\n}\n\n.show-filters-btn:hover {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n.filter-active-badge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 18px;\n height: 18px;\n padding: 0 5px;\n border-radius: 9px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 0.65rem;\n font-weight: 700;\n}\n\n/* Agent CTA */\n.search-agent-cta {\n display: flex;\n align-items: center;\n gap: 1rem;\n padding: 1.25rem;\n margin-top: 1.5rem;\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n.cta-icon {\n font-size: 1.5rem;\n color: var(--mj-brand-primary);\n flex-shrink: 0;\n}\n\n.cta-text {\n flex: 1;\n}\n\n.cta-text strong {\n color: var(--mj-text-primary);\n font-size: 0.9rem;\n}\n\n.cta-text p {\n color: var(--mj-text-muted);\n font-size: 0.82rem;\n margin: 0.2rem 0 0;\n}\n\n.cta-btn {\n padding: 0.5rem 1rem;\n border-radius: 8px;\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 white-space: nowrap;\n}\n\n.cta-btn:hover {\n background: var(--mj-brand-primary-hover);\n}\n\n/* Recent Searches */\n.search-recent-area {\n max-width: 600px;\n margin: 0 auto;\n padding: 1rem 2rem;\n}\n\n.recent-title {\n font-size: 0.82rem;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n font-weight: 600;\n margin-bottom: 0.75rem;\n}\n\n.recent-list {\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n}\n\n.recent-item {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.6rem 0.75rem;\n border-radius: 8px;\n cursor: pointer;\n transition: background 0.1s ease;\n}\n\n.recent-item:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.recent-icon {\n color: var(--mj-text-muted);\n font-size: 0.82rem;\n}\n\n.recent-query {\n flex: 1;\n color: var(--mj-text-primary);\n font-size: 0.9rem;\n}\n\n.recent-count {\n color: var(--mj-text-muted);\n font-size: 0.78rem;\n}\n\n/* Relevance Threshold */\n.threshold-section {\n margin-top: 1.25rem;\n padding-top: 1rem;\n border-top: 1px solid var(--mj-border-subtle);\n}\n\n.threshold-label {\n display: flex;\n justify-content: space-between;\n align-items: center;\n font-size: 0.82rem;\n font-weight: 600;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n margin-bottom: 0.5rem;\n}\n\n.threshold-value {\n font-weight: 700;\n color: var(--mj-brand-primary);\n font-size: 0.85rem;\n}\n\n.threshold-slider {\n width: 100%;\n height: 4px;\n appearance: none;\n -webkit-appearance: none;\n background: var(--mj-border-default);\n border-radius: 2px;\n outline: none;\n cursor: pointer;\n}\n\n.threshold-slider::-webkit-slider-thumb {\n -webkit-appearance: none;\n width: 16px;\n height: 16px;\n border-radius: 50%;\n background: var(--mj-brand-primary);\n border: 2px solid var(--mj-bg-surface);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n cursor: pointer;\n}\n\n.threshold-slider::-moz-range-thumb {\n width: 16px;\n height: 16px;\n border-radius: 50%;\n background: var(--mj-brand-primary);\n border: 2px solid var(--mj-bg-surface);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n cursor: pointer;\n}\n\n.threshold-range-labels {\n display: flex;\n justify-content: space-between;\n font-size: 0.72rem;\n color: var(--mj-text-muted);\n margin-top: 0.25rem;\n}\n\n.threshold-stats {\n display: flex;\n flex-direction: column;\n gap: 0.15rem;\n margin-top: 0.6rem;\n padding: 0.45rem 0.6rem;\n border-radius: 6px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-subtle);\n}\n\n.threshold-stats-shown {\n font-size: 0.75rem;\n font-weight: 600;\n color: var(--mj-text-secondary);\n}\n\n.threshold-stats-range {\n font-size: 0.7rem;\n color: var(--mj-text-muted);\n}\n\n/* Save Search Button (in results header) */\n.save-search-btn {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n padding: 0.3rem 0.65rem;\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.78rem;\n cursor: pointer;\n transition: all 0.15s;\n margin-left: auto;\n}\n\n.save-search-btn:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n/* Saved search items in empty state */\n.saved-icon {\n color: var(--mj-brand-primary);\n font-size: 0.82rem;\n}\n\n.saved-item {\n position: relative;\n}\n\n.saved-query-text {\n color: var(--mj-text-muted);\n font-size: 0.78rem;\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.saved-delete-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n border: none;\n border-radius: 4px;\n background: transparent;\n color: var(--mj-text-muted);\n font-size: 0.7rem;\n cursor: pointer;\n opacity: 0;\n transition: all 0.15s;\n flex-shrink: 0;\n}\n\n.saved-item:hover .saved-delete-btn {\n opacity: 1;\n}\n\n.saved-delete-btn:hover {\n color: var(--mj-status-error);\n background: var(--mj-status-error-bg);\n}\n\n/* Save Dialog Overlay */\n.save-dialog-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n}\n\n.save-dialog {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n padding: 1.5rem;\n width: 400px;\n max-width: 90vw;\n box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15);\n}\n\n.save-dialog-title {\n margin: 0 0 0.25rem;\n font-size: 1.1rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.save-dialog-subtitle {\n margin: 0 0 1rem;\n font-size: 0.82rem;\n color: var(--mj-text-muted);\n}\n\n.save-dialog-label {\n display: block;\n font-size: 0.78rem;\n font-weight: 600;\n color: var(--mj-text-secondary);\n margin-bottom: 0.35rem;\n}\n\n.save-dialog-input {\n width: 100%;\n box-sizing: border-box;\n margin-bottom: 1rem;\n}\n\n.save-dialog-actions {\n display: flex;\n gap: 0.5rem;\n}\n\n.save-dialog-confirm {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n padding: 0.5rem 1rem;\n border: none;\n border-radius: 6px;\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 transition: background 0.15s;\n}\n\n.save-dialog-confirm:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n}\n\n.save-dialog-confirm:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.save-dialog-cancel {\n padding: 0.5rem 1rem;\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.85rem;\n cursor: pointer;\n transition: all 0.15s;\n}\n\n.save-dialog-cancel:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n/* Mobile responsive */\n@media (max-width: 768px) {\n .search-results-layout {\n flex-direction: column;\n padding: 0 1rem 1rem;\n }\n\n .search-sidebar {\n width: 100%;\n }\n\n .search-hero {\n padding: 3rem 1rem 1rem;\n }\n}\n"] }]
455
985
  }], null, null); })();
456
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(KnowledgeSearchResourceComponent, { className: "KnowledgeSearchResourceComponent", filePath: "src/KnowledgeHub/components/search/knowledge-search-resource.component.ts", lineNumber: 42 }); })();
986
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(KnowledgeSearchResourceComponent, { className: "KnowledgeSearchResourceComponent", filePath: "src/KnowledgeHub/components/search/knowledge-search-resource.component.ts", lineNumber: 35 }); })();
457
987
  /** Tree-shaking prevention */
458
988
  export function LoadKnowledgeSearchResource() {
459
989
  // Prevents tree-shaking of the component