@memberjunction/ng-explorer-core 6.2.0-edge.3 → 6.2.0-edge.4

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 (117) hide show
  1. package/README.md +10 -0
  2. package/dist/app-routing.module.d.ts.map +1 -1
  3. package/dist/app-routing.module.js +5 -0
  4. package/dist/app-routing.module.js.map +1 -1
  5. package/dist/generated/lazy-feature-config.d.ts +1 -1
  6. package/dist/generated/lazy-feature-config.d.ts.map +1 -1
  7. package/dist/generated/lazy-feature-config.js +3 -2
  8. package/dist/generated/lazy-feature-config.js.map +1 -1
  9. package/dist/lib/guards/moved-nav-item-redirect.d.ts +15 -0
  10. package/dist/lib/guards/moved-nav-item-redirect.d.ts.map +1 -0
  11. package/dist/lib/guards/moved-nav-item-redirect.js +37 -0
  12. package/dist/lib/guards/moved-nav-item-redirect.js.map +1 -0
  13. package/dist/lib/omnibar/omnibar-dashboard-matches.d.ts +34 -0
  14. package/dist/lib/omnibar/omnibar-dashboard-matches.d.ts.map +1 -0
  15. package/dist/lib/omnibar/omnibar-dashboard-matches.js +70 -0
  16. package/dist/lib/omnibar/omnibar-dashboard-matches.js.map +1 -0
  17. package/dist/lib/omnibar/omnibar-palette.component.d.ts +27 -2
  18. package/dist/lib/omnibar/omnibar-palette.component.d.ts.map +1 -1
  19. package/dist/lib/omnibar/omnibar-palette.component.js +126 -65
  20. package/dist/lib/omnibar/omnibar-palette.component.js.map +1 -1
  21. package/dist/lib/omnibar/omnibar-provider.d.ts +4 -0
  22. package/dist/lib/omnibar/omnibar-provider.d.ts.map +1 -1
  23. package/dist/lib/omnibar/omnibar-provider.js.map +1 -1
  24. package/dist/lib/omnibar/providers/omnibar-record.provider.d.ts +2 -2
  25. package/dist/lib/omnibar/providers/omnibar-record.provider.d.ts.map +1 -1
  26. package/dist/lib/omnibar/providers/omnibar-record.provider.js +3 -7
  27. package/dist/lib/omnibar/providers/omnibar-record.provider.js.map +1 -1
  28. package/dist/lib/omnibar/providers/omnibar-search.provider.d.ts +15 -2
  29. package/dist/lib/omnibar/providers/omnibar-search.provider.d.ts.map +1 -1
  30. package/dist/lib/omnibar/providers/omnibar-search.provider.js +59 -7
  31. package/dist/lib/omnibar/providers/omnibar-search.provider.js.map +1 -1
  32. package/dist/lib/profile/forking-setting.d.ts +8 -0
  33. package/dist/lib/profile/forking-setting.d.ts.map +1 -0
  34. package/dist/lib/profile/forking-setting.js +18 -0
  35. package/dist/lib/profile/forking-setting.js.map +1 -0
  36. package/dist/lib/profile/profile-dialog.component.d.ts +8 -0
  37. package/dist/lib/profile/profile-dialog.component.d.ts.map +1 -1
  38. package/dist/lib/profile/profile-dialog.component.js +182 -92
  39. package/dist/lib/profile/profile-dialog.component.js.map +1 -1
  40. package/dist/lib/resource-wrappers/artifact-resource.component.d.ts +16 -1
  41. package/dist/lib/resource-wrappers/artifact-resource.component.d.ts.map +1 -1
  42. package/dist/lib/resource-wrappers/artifact-resource.component.js +27 -4
  43. package/dist/lib/resource-wrappers/artifact-resource.component.js.map +1 -1
  44. package/dist/lib/resource-wrappers/chat-conversations-resource.component.d.ts +7 -18
  45. package/dist/lib/resource-wrappers/chat-conversations-resource.component.d.ts.map +1 -1
  46. package/dist/lib/resource-wrappers/chat-conversations-resource.component.js +20 -41
  47. package/dist/lib/resource-wrappers/chat-conversations-resource.component.js.map +1 -1
  48. package/dist/lib/resource-wrappers/chat-search-routing.d.ts +10 -3
  49. package/dist/lib/resource-wrappers/chat-search-routing.d.ts.map +1 -1
  50. package/dist/lib/resource-wrappers/chat-search-routing.js +11 -4
  51. package/dist/lib/resource-wrappers/chat-search-routing.js.map +1 -1
  52. package/dist/lib/resource-wrappers/dashboard-add-to-menu.component.d.ts +29 -0
  53. package/dist/lib/resource-wrappers/dashboard-add-to-menu.component.d.ts.map +1 -0
  54. package/dist/lib/resource-wrappers/dashboard-add-to-menu.component.js +141 -0
  55. package/dist/lib/resource-wrappers/dashboard-add-to-menu.component.js.map +1 -0
  56. package/dist/lib/resource-wrappers/dashboard-part-config.d.ts +28 -0
  57. package/dist/lib/resource-wrappers/dashboard-part-config.d.ts.map +1 -0
  58. package/dist/lib/resource-wrappers/dashboard-part-config.js +150 -0
  59. package/dist/lib/resource-wrappers/dashboard-part-config.js.map +1 -0
  60. package/dist/lib/resource-wrappers/dashboard-resource.component.d.ts +361 -56
  61. package/dist/lib/resource-wrappers/dashboard-resource.component.d.ts.map +1 -1
  62. package/dist/lib/resource-wrappers/dashboard-resource.component.js +1312 -361
  63. package/dist/lib/resource-wrappers/dashboard-resource.component.js.map +1 -1
  64. package/dist/lib/resource-wrappers/dashboard-source-search.d.ts +86 -0
  65. package/dist/lib/resource-wrappers/dashboard-source-search.d.ts.map +1 -0
  66. package/dist/lib/resource-wrappers/dashboard-source-search.js +136 -0
  67. package/dist/lib/resource-wrappers/dashboard-source-search.js.map +1 -0
  68. package/dist/lib/resource-wrappers/dashboard-studio-pane.d.ts +30 -0
  69. package/dist/lib/resource-wrappers/dashboard-studio-pane.d.ts.map +1 -0
  70. package/dist/lib/resource-wrappers/dashboard-studio-pane.js +55 -0
  71. package/dist/lib/resource-wrappers/dashboard-studio-pane.js.map +1 -0
  72. package/dist/lib/resource-wrappers/dashboard-studio-tools.d.ts +135 -0
  73. package/dist/lib/resource-wrappers/dashboard-studio-tools.d.ts.map +1 -0
  74. package/dist/lib/resource-wrappers/dashboard-studio-tools.js +856 -0
  75. package/dist/lib/resource-wrappers/dashboard-studio-tools.js.map +1 -0
  76. package/dist/lib/resource-wrappers/dashboard-tab-agent.d.ts +87 -0
  77. package/dist/lib/resource-wrappers/dashboard-tab-agent.d.ts.map +1 -0
  78. package/dist/lib/resource-wrappers/dashboard-tab-agent.js +125 -0
  79. package/dist/lib/resource-wrappers/dashboard-tab-agent.js.map +1 -0
  80. package/dist/lib/resource-wrappers/livekit-room-resource.component.d.ts +28 -7
  81. package/dist/lib/resource-wrappers/livekit-room-resource.component.d.ts.map +1 -1
  82. package/dist/lib/resource-wrappers/livekit-room-resource.component.js +174 -112
  83. package/dist/lib/resource-wrappers/livekit-room-resource.component.js.map +1 -1
  84. package/dist/lib/resource-wrappers/search-results-resource.component.d.ts.map +1 -1
  85. package/dist/lib/resource-wrappers/search-results-resource.component.js +5 -4
  86. package/dist/lib/resource-wrappers/search-results-resource.component.js.map +1 -1
  87. package/dist/lib/shell/components/tabs/tab-container.component.d.ts +7 -0
  88. package/dist/lib/shell/components/tabs/tab-container.component.d.ts.map +1 -1
  89. package/dist/lib/shell/components/tabs/tab-container.component.js +20 -2
  90. package/dist/lib/shell/components/tabs/tab-container.component.js.map +1 -1
  91. package/dist/lib/shell/dashboard-tab-for-url.d.ts +35 -0
  92. package/dist/lib/shell/dashboard-tab-for-url.d.ts.map +1 -0
  93. package/dist/lib/shell/dashboard-tab-for-url.js +39 -0
  94. package/dist/lib/shell/dashboard-tab-for-url.js.map +1 -0
  95. package/dist/lib/shell/shell.component.d.ts +31 -2
  96. package/dist/lib/shell/shell.component.d.ts.map +1 -1
  97. package/dist/lib/shell/shell.component.js +109 -35
  98. package/dist/lib/shell/shell.component.js.map +1 -1
  99. package/dist/lib/shell/shell.module.d.ts +2 -1
  100. package/dist/lib/shell/shell.module.d.ts.map +1 -1
  101. package/dist/lib/shell/shell.module.js +6 -2
  102. package/dist/lib/shell/shell.module.js.map +1 -1
  103. package/dist/lib/single-dashboard/single-dashboard.component.js +1 -1
  104. package/dist/lib/single-dashboard/single-dashboard.component.js.map +1 -1
  105. package/dist/lib/template-user/template-user-banner.component.d.ts +20 -0
  106. package/dist/lib/template-user/template-user-banner.component.d.ts.map +1 -0
  107. package/dist/lib/template-user/template-user-banner.component.js +67 -0
  108. package/dist/lib/template-user/template-user-banner.component.js.map +1 -0
  109. package/dist/module.d.ts +61 -59
  110. package/dist/module.d.ts.map +1 -1
  111. package/dist/module.js +7 -0
  112. package/dist/module.js.map +1 -1
  113. package/dist/public-api.d.ts +1 -0
  114. package/dist/public-api.d.ts.map +1 -1
  115. package/dist/public-api.js +1 -0
  116. package/dist/public-api.js.map +1 -1
  117. package/package.json +58 -53
@@ -1,5 +1,5 @@
1
1
  import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, Output, ViewChild, inject, } from '@angular/core';
2
- import { CompositeKey } from '@memberjunction/core';
2
+ import { CompositeKey, LogError } from '@memberjunction/core';
3
3
  import { Metadata } from '@memberjunction/core';
4
4
  import { NavigationService } from '@memberjunction/ng-shared';
5
5
  import { ApplicationManager } from '@memberjunction/ng-base-application';
@@ -29,7 +29,7 @@ function OmnibarPaletteComponent_Conditional_0_Conditional_6_Template(rf, ctx) {
29
29
  } }
30
30
  function OmnibarPaletteComponent_Conditional_0_Conditional_15_For_4_Template(rf, ctx) { if (rf & 1) {
31
31
  const _r4 = i0.ɵɵgetCurrentView();
32
- i0.ɵɵelementStart(0, "button", 21);
32
+ i0.ɵɵelementStart(0, "button", 20);
33
33
  i0.ɵɵlistener("click", function OmnibarPaletteComponent_Conditional_0_Conditional_15_For_4_Template_button_click_0_listener() { const scope_r5 = i0.ɵɵrestoreView(_r4).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.ToggleScope(scope_r5.ID)); });
34
34
  i0.ɵɵtext(1);
35
35
  i0.ɵɵelementEnd();
@@ -42,11 +42,11 @@ function OmnibarPaletteComponent_Conditional_0_Conditional_15_For_4_Template(rf,
42
42
  } }
43
43
  function OmnibarPaletteComponent_Conditional_0_Conditional_15_Template(rf, ctx) { if (rf & 1) {
44
44
  const _r3 = i0.ɵɵgetCurrentView();
45
- i0.ɵɵelementStart(0, "div", 12)(1, "button", 21);
45
+ i0.ɵɵelementStart(0, "div", 12)(1, "button", 20);
46
46
  i0.ɵɵlistener("click", function OmnibarPaletteComponent_Conditional_0_Conditional_15_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.ClearScopes()); });
47
47
  i0.ɵɵtext(2, "All sources");
48
48
  i0.ɵɵelementEnd();
49
- i0.ɵɵrepeaterCreate(3, OmnibarPaletteComponent_Conditional_0_Conditional_15_For_4_Template, 2, 3, "button", 22, _forTrack0);
49
+ i0.ɵɵrepeaterCreate(3, OmnibarPaletteComponent_Conditional_0_Conditional_15_For_4_Template, 2, 3, "button", 21, _forTrack0);
50
50
  i0.ɵɵelementEnd();
51
51
  } if (rf & 2) {
52
52
  const ctx_r1 = i0.ɵɵnextContext(2);
@@ -57,13 +57,13 @@ function OmnibarPaletteComponent_Conditional_0_Conditional_15_Template(rf, ctx)
57
57
  } }
58
58
  function OmnibarPaletteComponent_Conditional_0_Conditional_17_Template(rf, ctx) { if (rf & 1) {
59
59
  i0.ɵɵelementStart(0, "div", 14);
60
- i0.ɵɵelement(1, "i", 23);
60
+ i0.ɵɵelement(1, "i", 22);
61
61
  i0.ɵɵtext(2, " Searching\u2026");
62
62
  i0.ɵɵelementEnd();
63
63
  } }
64
64
  function OmnibarPaletteComponent_Conditional_0_Conditional_18_For_2_Template(rf, ctx) { if (rf & 1) {
65
65
  const _r6 = i0.ɵɵgetCurrentView();
66
- i0.ɵɵelementStart(0, "button", 26);
66
+ i0.ɵɵelementStart(0, "button", 25);
67
67
  i0.ɵɵlistener("click", function OmnibarPaletteComponent_Conditional_0_Conditional_18_For_2_Template_button_click_0_listener() { const hint_r7 = i0.ɵɵrestoreView(_r6).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.SeedTrigger(hint_r7.Char)); });
68
68
  i0.ɵɵelementStart(1, "b");
69
69
  i0.ɵɵtext(2);
@@ -80,18 +80,18 @@ function OmnibarPaletteComponent_Conditional_0_Conditional_18_For_2_Template(rf,
80
80
  } }
81
81
  function OmnibarPaletteComponent_Conditional_0_Conditional_18_Conditional_3_For_4_Template(rf, ctx) { if (rf & 1) {
82
82
  const _r8 = i0.ɵɵgetCurrentView();
83
- i0.ɵɵelementStart(0, "div", 29);
83
+ i0.ɵɵelementStart(0, "div", 28);
84
84
  i0.ɵɵlistener("focus", function OmnibarPaletteComponent_Conditional_0_Conditional_18_Conditional_3_For_4_Template_div_focus_0_listener() { const ɵ$index_67_r9 = i0.ɵɵrestoreView(_r8).$index; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.SelectedIndex = ctx_r1.RecentBaseIndex + ɵ$index_67_r9); })("keydown", function OmnibarPaletteComponent_Conditional_0_Conditional_18_Conditional_3_For_4_Template_div_keydown_0_listener($event) { const row_r10 = i0.ɵɵrestoreView(_r8).$implicit; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.OnRowKeydown($event, row_r10.Suggestion)); })("mouseenter", function OmnibarPaletteComponent_Conditional_0_Conditional_18_Conditional_3_For_4_Template_div_mouseenter_0_listener() { const ɵ$index_67_r9 = i0.ɵɵrestoreView(_r8).$index; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.SelectedIndex = ctx_r1.RecentBaseIndex + ɵ$index_67_r9); })("click", function OmnibarPaletteComponent_Conditional_0_Conditional_18_Conditional_3_For_4_Template_div_click_0_listener() { const row_r10 = i0.ɵɵrestoreView(_r8).$implicit; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.Execute(row_r10.Suggestion)); });
85
- i0.ɵɵelementStart(1, "span", 30);
85
+ i0.ɵɵelementStart(1, "span", 29);
86
86
  i0.ɵɵelement(2, "i");
87
87
  i0.ɵɵelementEnd();
88
- i0.ɵɵelementStart(3, "span", 31)(4, "span", 32);
88
+ i0.ɵɵelementStart(3, "span", 30)(4, "span", 31);
89
89
  i0.ɵɵtext(5);
90
90
  i0.ɵɵelementEnd();
91
- i0.ɵɵelementStart(6, "span", 33);
91
+ i0.ɵɵelementStart(6, "span", 32);
92
92
  i0.ɵɵtext(7);
93
93
  i0.ɵɵelementEnd()();
94
- i0.ɵɵelementStart(8, "span", 34)(9, "span", 35);
94
+ i0.ɵɵelementStart(8, "span", 33)(9, "span", 34);
95
95
  i0.ɵɵtext(10);
96
96
  i0.ɵɵelementEnd()()();
97
97
  } if (rf & 2) {
@@ -110,11 +110,11 @@ function OmnibarPaletteComponent_Conditional_0_Conditional_18_Conditional_3_For_
110
110
  i0.ɵɵtextInterpolate(row_r10.Suggestion.type);
111
111
  } }
112
112
  function OmnibarPaletteComponent_Conditional_0_Conditional_18_Conditional_3_Template(rf, ctx) { if (rf & 1) {
113
- i0.ɵɵelementStart(0, "div", 27);
113
+ i0.ɵɵelementStart(0, "div", 26);
114
114
  i0.ɵɵtext(1, "Recent");
115
115
  i0.ɵɵelementEnd();
116
- i0.ɵɵelementStart(2, "div", 16);
117
- i0.ɵɵrepeaterCreate(3, OmnibarPaletteComponent_Conditional_0_Conditional_18_Conditional_3_For_4_Template, 11, 10, "div", 28, _forTrack2);
116
+ i0.ɵɵelementStart(2, "div", 15);
117
+ i0.ɵɵrepeaterCreate(3, OmnibarPaletteComponent_Conditional_0_Conditional_18_Conditional_3_For_4_Template, 11, 10, "div", 27, _forTrack2);
118
118
  i0.ɵɵelementEnd();
119
119
  } if (rf & 2) {
120
120
  const ctx_r1 = i0.ɵɵnextContext(3);
@@ -122,8 +122,8 @@ function OmnibarPaletteComponent_Conditional_0_Conditional_18_Conditional_3_Temp
122
122
  i0.ɵɵrepeater(ctx_r1.RecentRows);
123
123
  } }
124
124
  function OmnibarPaletteComponent_Conditional_0_Conditional_18_Template(rf, ctx) { if (rf & 1) {
125
- i0.ɵɵelementStart(0, "div", 24);
126
- i0.ɵɵrepeaterCreate(1, OmnibarPaletteComponent_Conditional_0_Conditional_18_For_2_Template, 5, 2, "button", 25, _forTrack1);
125
+ i0.ɵɵelementStart(0, "div", 23);
126
+ i0.ɵɵrepeaterCreate(1, OmnibarPaletteComponent_Conditional_0_Conditional_18_For_2_Template, 5, 2, "button", 24, _forTrack1);
127
127
  i0.ɵɵelementEnd();
128
128
  i0.ɵɵconditionalCreate(3, OmnibarPaletteComponent_Conditional_0_Conditional_18_Conditional_3_Template, 5, 0);
129
129
  } if (rf & 2) {
@@ -133,8 +133,8 @@ function OmnibarPaletteComponent_Conditional_0_Conditional_18_Template(rf, ctx)
133
133
  i0.ɵɵadvance(2);
134
134
  i0.ɵɵconditional(ctx_r1.RecentRows.length > 0 ? 3 : -1);
135
135
  } }
136
- function OmnibarPaletteComponent_Conditional_0_Conditional_19_Template(rf, ctx) { if (rf & 1) {
137
- i0.ɵɵelementStart(0, "div", 15);
136
+ function OmnibarPaletteComponent_Conditional_0_Conditional_19_Conditional_0_Template(rf, ctx) { if (rf & 1) {
137
+ i0.ɵɵelementStart(0, "div", 35);
138
138
  i0.ɵɵtext(1, "No matches \u2014 press ");
139
139
  i0.ɵɵelementStart(2, "kbd", 9);
140
140
  i0.ɵɵtext(3, "\u21B5");
@@ -142,12 +142,27 @@ function OmnibarPaletteComponent_Conditional_0_Conditional_19_Template(rf, ctx)
142
142
  i0.ɵɵtext(4);
143
143
  i0.ɵɵelementEnd();
144
144
  } if (rf & 2) {
145
- const ctx_r1 = i0.ɵɵnextContext(2);
145
+ const ctx_r1 = i0.ɵɵnextContext(3);
146
146
  i0.ɵɵadvance(4);
147
147
  i0.ɵɵtextInterpolate1(" to search everything for \u201C", ctx_r1.EffectiveQuery, "\u201D.");
148
148
  } }
149
+ function OmnibarPaletteComponent_Conditional_0_Conditional_19_Conditional_1_Template(rf, ctx) { if (rf & 1) {
150
+ i0.ɵɵelementStart(0, "div", 35);
151
+ i0.ɵɵtext(1);
152
+ i0.ɵɵelementEnd();
153
+ } if (rf & 2) {
154
+ const ctx_r1 = i0.ɵɵnextContext(3);
155
+ i0.ɵɵadvance();
156
+ i0.ɵɵtextInterpolate1("No matches for \u201C", ctx_r1.EffectiveQuery, "\u201D.");
157
+ } }
158
+ function OmnibarPaletteComponent_Conditional_0_Conditional_19_Template(rf, ctx) { if (rf & 1) {
159
+ i0.ɵɵconditionalCreate(0, OmnibarPaletteComponent_Conditional_0_Conditional_19_Conditional_0_Template, 5, 1, "div", 35)(1, OmnibarPaletteComponent_Conditional_0_Conditional_19_Conditional_1_Template, 2, 1, "div", 35);
160
+ } if (rf & 2) {
161
+ const ctx_r1 = i0.ɵɵnextContext(2);
162
+ i0.ɵɵconditional(ctx_r1.CanEscapeToFullSearch ? 0 : 1);
163
+ } }
149
164
  function OmnibarPaletteComponent_Conditional_0_Conditional_20_For_2_Conditional_0_Template(rf, ctx) { if (rf & 1) {
150
- i0.ɵɵelementStart(0, "div", 27);
165
+ i0.ɵɵelementStart(0, "div", 26);
151
166
  i0.ɵɵtext(1);
152
167
  i0.ɵɵelementEnd();
153
168
  } if (rf & 2) {
@@ -156,7 +171,7 @@ function OmnibarPaletteComponent_Conditional_0_Conditional_20_For_2_Conditional_
156
171
  i0.ɵɵtextInterpolate(row_r12.GroupLabel);
157
172
  } }
158
173
  function OmnibarPaletteComponent_Conditional_0_Conditional_20_For_2_Conditional_7_Template(rf, ctx) { if (rf & 1) {
159
- i0.ɵɵelementStart(0, "span", 33);
174
+ i0.ɵɵelementStart(0, "span", 32);
160
175
  i0.ɵɵtext(1);
161
176
  i0.ɵɵelementEnd();
162
177
  } if (rf & 2) {
@@ -175,20 +190,20 @@ function OmnibarPaletteComponent_Conditional_0_Conditional_20_For_2_Conditional_
175
190
  } }
176
191
  function OmnibarPaletteComponent_Conditional_0_Conditional_20_For_2_Template(rf, ctx) { if (rf & 1) {
177
192
  const _r11 = i0.ɵɵgetCurrentView();
178
- i0.ɵɵconditionalCreate(0, OmnibarPaletteComponent_Conditional_0_Conditional_20_For_2_Conditional_0_Template, 2, 1, "div", 27);
179
- i0.ɵɵelementStart(1, "div", 29);
180
- i0.ɵɵlistener("focus", function OmnibarPaletteComponent_Conditional_0_Conditional_20_For_2_Template_div_focus_1_listener() { const ɵ$index_98_r13 = i0.ɵɵrestoreView(_r11).$index; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.SelectedIndex = ɵ$index_98_r13); })("keydown", function OmnibarPaletteComponent_Conditional_0_Conditional_20_For_2_Template_div_keydown_1_listener($event) { const row_r12 = i0.ɵɵrestoreView(_r11).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnRowKeydown($event, row_r12.Suggestion)); })("mouseenter", function OmnibarPaletteComponent_Conditional_0_Conditional_20_For_2_Template_div_mouseenter_1_listener() { const ɵ$index_98_r13 = i0.ɵɵrestoreView(_r11).$index; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.SelectedIndex = ɵ$index_98_r13); })("click", function OmnibarPaletteComponent_Conditional_0_Conditional_20_For_2_Template_div_click_1_listener() { const row_r12 = i0.ɵɵrestoreView(_r11).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.Execute(row_r12.Suggestion)); });
181
- i0.ɵɵelementStart(2, "span", 30);
193
+ i0.ɵɵconditionalCreate(0, OmnibarPaletteComponent_Conditional_0_Conditional_20_For_2_Conditional_0_Template, 2, 1, "div", 26);
194
+ i0.ɵɵelementStart(1, "div", 28);
195
+ i0.ɵɵlistener("focus", function OmnibarPaletteComponent_Conditional_0_Conditional_20_For_2_Template_div_focus_1_listener() { const ɵ$index_103_r13 = i0.ɵɵrestoreView(_r11).$index; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.SelectedIndex = ɵ$index_103_r13); })("keydown", function OmnibarPaletteComponent_Conditional_0_Conditional_20_For_2_Template_div_keydown_1_listener($event) { const row_r12 = i0.ɵɵrestoreView(_r11).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnRowKeydown($event, row_r12.Suggestion)); })("mouseenter", function OmnibarPaletteComponent_Conditional_0_Conditional_20_For_2_Template_div_mouseenter_1_listener() { const ɵ$index_103_r13 = i0.ɵɵrestoreView(_r11).$index; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.SelectedIndex = ɵ$index_103_r13); })("click", function OmnibarPaletteComponent_Conditional_0_Conditional_20_For_2_Template_div_click_1_listener() { const row_r12 = i0.ɵɵrestoreView(_r11).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.Execute(row_r12.Suggestion)); });
196
+ i0.ɵɵelementStart(2, "span", 29);
182
197
  i0.ɵɵelement(3, "i");
183
198
  i0.ɵɵelementEnd();
184
- i0.ɵɵelementStart(4, "span", 31)(5, "span", 32);
199
+ i0.ɵɵelementStart(4, "span", 30)(5, "span", 31);
185
200
  i0.ɵɵtext(6);
186
201
  i0.ɵɵelementEnd();
187
- i0.ɵɵconditionalCreate(7, OmnibarPaletteComponent_Conditional_0_Conditional_20_For_2_Conditional_7_Template, 2, 1, "span", 33);
202
+ i0.ɵɵconditionalCreate(7, OmnibarPaletteComponent_Conditional_0_Conditional_20_For_2_Conditional_7_Template, 2, 1, "span", 32);
188
203
  i0.ɵɵelementEnd();
189
- i0.ɵɵelementStart(8, "span", 34);
204
+ i0.ɵɵelementStart(8, "span", 33);
190
205
  i0.ɵɵconditionalCreate(9, OmnibarPaletteComponent_Conditional_0_Conditional_20_For_2_Conditional_9_Template, 2, 2, "span", 36);
191
- i0.ɵɵelementStart(10, "span", 35);
206
+ i0.ɵɵelementStart(10, "span", 34);
192
207
  i0.ɵɵtext(11);
193
208
  i0.ɵɵelementEnd();
194
209
  i0.ɵɵelementStart(12, "span", 37);
@@ -198,12 +213,12 @@ function OmnibarPaletteComponent_Conditional_0_Conditional_20_For_2_Template(rf,
198
213
  i0.ɵɵelementEnd()()()();
199
214
  } if (rf & 2) {
200
215
  const row_r12 = ctx.$implicit;
201
- const ɵ$index_98_r13 = ctx.$index;
216
+ const ɵ$index_103_r13 = ctx.$index;
202
217
  const ctx_r1 = i0.ɵɵnextContext(3);
203
- i0.ɵɵconditional(row_r12.GroupLabel ? 0 : -1);
218
+ i0.ɵɵconditional(row_r12.GroupLabel !== null ? 0 : -1);
204
219
  i0.ɵɵadvance();
205
- i0.ɵɵclassProp("ob-row--sel", ɵ$index_98_r13 === ctx_r1.SelectedIndex);
206
- i0.ɵɵattribute("id", "ob-opt-" + ɵ$index_98_r13)("tabindex", ɵ$index_98_r13 === ctx_r1.SelectedIndex ? 0 : -1)("aria-selected", ɵ$index_98_r13 === ctx_r1.SelectedIndex);
220
+ i0.ɵɵclassProp("ob-row--sel", ɵ$index_103_r13 === ctx_r1.SelectedIndex);
221
+ i0.ɵɵattribute("id", "ob-opt-" + ɵ$index_103_r13)("tabindex", ɵ$index_103_r13 === ctx_r1.SelectedIndex ? 0 : -1)("aria-selected", ɵ$index_103_r13 === ctx_r1.SelectedIndex);
207
222
  i0.ɵɵadvance(2);
208
223
  i0.ɵɵclassMap(row_r12.Suggestion.icon || "fa-solid fa-circle");
209
224
  i0.ɵɵadvance(3);
@@ -216,7 +231,7 @@ function OmnibarPaletteComponent_Conditional_0_Conditional_20_For_2_Template(rf,
216
231
  i0.ɵɵtextInterpolate(row_r12.Suggestion.type);
217
232
  } }
218
233
  function OmnibarPaletteComponent_Conditional_0_Conditional_20_Template(rf, ctx) { if (rf & 1) {
219
- i0.ɵɵelementStart(0, "div", 16);
234
+ i0.ɵɵelementStart(0, "div", 15);
220
235
  i0.ɵɵrepeaterCreate(1, OmnibarPaletteComponent_Conditional_0_Conditional_20_For_2_Template, 16, 12, null, null, _forTrack2);
221
236
  i0.ɵɵelementEnd();
222
237
  } if (rf & 2) {
@@ -249,9 +264,9 @@ function OmnibarPaletteComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
249
264
  i0.ɵɵelementEnd()();
250
265
  i0.ɵɵconditionalCreate(15, OmnibarPaletteComponent_Conditional_0_Conditional_15_Template, 5, 2, "div", 12);
251
266
  i0.ɵɵelementStart(16, "div", 13);
252
- i0.ɵɵconditionalCreate(17, OmnibarPaletteComponent_Conditional_0_Conditional_17_Template, 3, 0, "div", 14)(18, OmnibarPaletteComponent_Conditional_0_Conditional_18_Template, 4, 1)(19, OmnibarPaletteComponent_Conditional_0_Conditional_19_Template, 5, 1, "div", 15)(20, OmnibarPaletteComponent_Conditional_0_Conditional_20_Template, 3, 0, "div", 16);
267
+ i0.ɵɵconditionalCreate(17, OmnibarPaletteComponent_Conditional_0_Conditional_17_Template, 3, 0, "div", 14)(18, OmnibarPaletteComponent_Conditional_0_Conditional_18_Template, 4, 1)(19, OmnibarPaletteComponent_Conditional_0_Conditional_19_Template, 2, 1)(20, OmnibarPaletteComponent_Conditional_0_Conditional_20_Template, 3, 0, "div", 15);
253
268
  i0.ɵɵelementEnd();
254
- i0.ɵɵelementStart(21, "div", 17)(22, "span", 18)(23, "kbd", 9);
269
+ i0.ɵɵelementStart(21, "div", 16)(22, "span", 17)(23, "kbd", 9);
255
270
  i0.ɵɵtext(24, "\u2191");
256
271
  i0.ɵɵelementEnd();
257
272
  i0.ɵɵelementStart(25, "kbd", 9);
@@ -259,14 +274,14 @@ function OmnibarPaletteComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
259
274
  i0.ɵɵelementEnd();
260
275
  i0.ɵɵtext(27, " navigate");
261
276
  i0.ɵɵelementEnd();
262
- i0.ɵɵelementStart(28, "span", 18)(29, "kbd", 9);
277
+ i0.ɵɵelementStart(28, "span", 17)(29, "kbd", 9);
263
278
  i0.ɵɵtext(30, "\u21B5");
264
279
  i0.ɵɵelementEnd();
265
280
  i0.ɵɵtext(31, " open");
266
281
  i0.ɵɵelementEnd();
267
- i0.ɵɵelementStart(32, "button", 19);
282
+ i0.ɵɵelementStart(32, "button", 18);
268
283
  i0.ɵɵlistener("click", function OmnibarPaletteComponent_Conditional_0_Template_button_click_32_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.RequestSettings()); });
269
- i0.ɵɵelement(33, "i", 20);
284
+ i0.ɵɵelement(33, "i", 19);
270
285
  i0.ɵɵelementStart(34, "span");
271
286
  i0.ɵɵtext(35, "Settings");
272
287
  i0.ɵɵelementEnd()()()();
@@ -334,6 +349,8 @@ export class OmnibarPaletteComponent {
334
349
  defaultProvider = null;
335
350
  byTrigger = new Map();
336
351
  queryGeneration = 0;
352
+ /** Trigger char of the provider that produced the current {@link Rows}. */
353
+ renderedTriggerChar = '';
337
354
  debounceHandle = null;
338
355
  /** Element focused before the palette opened — restored on close (a11y). */
339
356
  previousFocus = null;
@@ -379,8 +396,29 @@ export class OmnibarPaletteComponent {
379
396
  const char = this.ActiveTriggerChar;
380
397
  return char ? (this.byTrigger.get(char) ?? null) : this.defaultProvider;
381
398
  }
399
+ /**
400
+ * Rows that keyboard selection may target: only rendered rows. {@link RecentRows}
401
+ * render only in the empty-query state, so they are selectable only then.
402
+ */
382
403
  get selectableRows() {
383
- return this.Rows.length > 0 ? this.Rows : this.RecentRows;
404
+ if (this.Rows.length > 0) {
405
+ return this.Rows;
406
+ }
407
+ return this.Query.length === 0 ? this.RecentRows : [];
408
+ }
409
+ /**
410
+ * Whether <kbd>Enter</kbd> on a palette with no rows may open the full Search Results
411
+ * workspace for the typed text. Drives both the key handler and the empty-state wording.
412
+ *
413
+ * Default mode always allows it, because full search is that mode's own action. A trigger
414
+ * mode allows it only after its fetch settles, because there full search is a different
415
+ * action from what the rows offer (switch app, open record).
416
+ */
417
+ get CanEscapeToFullSearch() {
418
+ if (this.EffectiveQuery.trim().length <= 1) {
419
+ return false;
420
+ }
421
+ return this.ActiveTriggerChar === '' || !this.IsLoading;
384
422
  }
385
423
  /**
386
424
  * ARIA combobox wiring: the input keeps DOM focus while this points at the
@@ -404,6 +442,9 @@ export class OmnibarPaletteComponent {
404
442
  this.Query = initialQuery;
405
443
  this.Rows = [];
406
444
  this.SelectedIndex = 0;
445
+ // The empty row set we just installed belongs to no mode, so the first fetch is
446
+ // correctly seen as a mode change.
447
+ this.renderedTriggerChar = '';
407
448
  void this.loadScopes();
408
449
  void this.loadRecents();
409
450
  if (initialQuery.length > 0) {
@@ -468,8 +509,7 @@ export class OmnibarPaletteComponent {
468
509
  if (row) {
469
510
  this.Execute(row.Suggestion);
470
511
  }
471
- else if (this.ActiveTriggerChar === '' && this.EffectiveQuery.trim().length > 1) {
472
- // No rows yet (still loading / no matches): honest escape hatch to full search.
512
+ else if (this.CanEscapeToFullSearch) {
473
513
  this.openFullSearch(this.EffectiveQuery.trim());
474
514
  }
475
515
  break;
@@ -593,7 +633,13 @@ export class OmnibarPaletteComponent {
593
633
  // ---------------------------------------------------------------
594
634
  // Execution
595
635
  // ---------------------------------------------------------------
596
- /** Executes a suggestion: navigate per its payload, or re-seed for entity drill-in. */
636
+ /**
637
+ * Executes a suggestion: navigate per its payload, or re-seed for entity drill-in.
638
+ *
639
+ * Not blocked while a fetch is pending: every activation path targets a rendered row,
640
+ * because {@link selectableRows} offers only rendered rows and a mode change clears
641
+ * {@link Rows}.
642
+ */
597
643
  Execute(suggestion) {
598
644
  const nav = GetOmnibarNavPayload(suggestion);
599
645
  if (!nav) {
@@ -639,6 +685,9 @@ export class OmnibarPaletteComponent {
639
685
  void this.fileOpen.OpenFileFromSearchResult(nav.rawMetadata);
640
686
  }
641
687
  break;
688
+ case 'dashboard':
689
+ this.navigation.OpenDashboard(nav.dashboardId, nav.dashboardName);
690
+ break;
642
691
  }
643
692
  this.Close();
644
693
  }
@@ -713,20 +762,24 @@ export class OmnibarPaletteComponent {
713
762
  if (!provider || (query.trim().length === 0 && !isTriggerMode)) {
714
763
  this.Rows = [];
715
764
  this.IsLoading = false;
765
+ this.renderedTriggerChar = this.ActiveTriggerChar;
716
766
  this.cdr.markForCheck();
717
767
  return;
718
768
  }
719
- const fire = () => void this.fetchSuggestions(provider, query, generation);
720
- if (isTriggerMode) {
721
- // Short debounce: entity matching is in-memory, but record suggestions issue a
722
- // RunView per keystroke — debouncing collapses a typing burst into one backend query.
723
- this.debounceHandle = setTimeout(fire, TRIGGER_DEBOUNCE_MS);
724
- }
725
- else {
726
- this.IsLoading = this.Rows.length === 0;
727
- this.cdr.markForCheck();
728
- this.debounceHandle = setTimeout(fire, SEARCH_DEBOUNCE_MS);
769
+ // A mode change clears the rows, because a different provider answers a different
770
+ // question. Rows for the same mode stay on screen while the next fetch runs.
771
+ if (this.ActiveTriggerChar !== this.renderedTriggerChar) {
772
+ this.Rows = [];
729
773
  }
774
+ // In every mode, show the spinner while no rows are on screen, so the "No matches"
775
+ // empty state appears only after a fetch has settled.
776
+ this.IsLoading = this.Rows.length === 0;
777
+ this.cdr.markForCheck();
778
+ // Shorter debounce in trigger mode: entity matching is in-memory, but record
779
+ // suggestions issue a RunView per keystroke — debouncing collapses a typing burst
780
+ // into one backend query.
781
+ const fire = () => void this.fetchSuggestions(provider, query, generation);
782
+ this.debounceHandle = setTimeout(fire, isTriggerMode ? TRIGGER_DEBOUNCE_MS : SEARCH_DEBOUNCE_MS);
730
783
  }
731
784
  async fetchSuggestions(provider, query, generation) {
732
785
  const request = {
@@ -735,29 +788,37 @@ export class OmnibarPaletteComponent {
735
788
  ContextUser: this.currentUser,
736
789
  Provider: null,
737
790
  };
738
- const suggestions = query.trim().length === 0
739
- ? await provider.EmptyStateSuggestions(request)
740
- : await provider.GetSuggestions(request);
791
+ // A failed fetch still settles this generation, so the spinner clears and no
792
+ // rejection escapes the `void fetchSuggestions(...)` call.
793
+ let suggestions = [];
794
+ try {
795
+ suggestions = query.trim().length === 0
796
+ ? await provider.EmptyStateSuggestions(request)
797
+ : await provider.GetSuggestions(request);
798
+ }
799
+ catch (e) {
800
+ LogError(e);
801
+ }
741
802
  if (generation !== this.queryGeneration) {
742
803
  return; // stale response — a newer keystroke superseded it
743
804
  }
744
805
  this.Rows = this.toRows(suggestions);
745
806
  this.SelectedIndex = 0;
746
807
  this.IsLoading = false;
808
+ this.renderedTriggerChar = this.ActiveTriggerChar;
747
809
  this.cdr.markForCheck();
748
810
  }
749
811
  toRows(suggestions) {
750
- let lastGroup = null;
812
+ // '' = ungrouped, so ungrouped rows at the top get no header.
813
+ let previousGroup = '';
751
814
  return suggestions.map((s) => {
752
815
  const group = typeof s.data?.['group'] === 'string' ? s.data['group'] : '';
753
- const isNewGroup = group.length > 0 && group !== lastGroup;
754
- if (group.length > 0) {
755
- lastGroup = group;
756
- }
816
+ const groupLabel = group !== previousGroup ? group : null;
817
+ previousGroup = group;
757
818
  const score = typeof s.data?.['score'] === 'number' ? s.data['score'] : null;
758
819
  return {
759
820
  Suggestion: s,
760
- GroupLabel: isNewGroup ? group : null,
821
+ GroupLabel: groupLabel,
761
822
  ScorePercent: score != null ? Math.round(Math.max(0, Math.min(1, score)) * 100) : null,
762
823
  };
763
824
  });
@@ -819,7 +880,7 @@ export class OmnibarPaletteComponent {
819
880
  } if (rf & 2) {
820
881
  let _t;
821
882
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.inputRef = _t.first);
822
- } }, outputs: { Opened: "Opened", Closed: "Closed", SettingsRequested: "SettingsRequested" }, standalone: false, decls: 1, vars: 1, consts: [["paletteInput", ""], [1, "omnibar-overlay", 3, "click"], ["role", "dialog", "aria-modal", "true", "aria-label", "Command palette", 1, "omnibar-palette", 3, "keydown"], [1, "ob-input-row"], [1, "ob-field"], [1, "ob-lead"], [1, "fa-solid", "fa-magnifying-glass"], ["type", "text", "autocomplete", "off", "spellcheck", "false", "role", "combobox", "aria-controls", "ob-listbox", "aria-autocomplete", "list", 1, "ob-input", 3, "ngModelChange", "keydown", "placeholder", "ngModel"], [1, "ob-mode-badge"], [1, "ob-kbd"], ["type", "button", "aria-label", "Close", "title", "Close", 1, "ob-close", 3, "click"], [1, "fa-solid", "fa-xmark"], [1, "ob-scopes"], [1, "ob-body"], [1, "ob-loading"], [1, "ob-empty"], ["id", "ob-listbox", "role", "listbox", "aria-label", "Suggestions"], [1, "ob-foot"], [1, "ob-k"], ["type", "button", "aria-label", "Command Palette settings", "title", "Command Palette settings", 1, "ob-settings", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-gear"], ["type", "button", 1, "ob-scope", 3, "click"], ["type", "button", 1, "ob-scope", 3, "ob-scope--on"], [1, "fa-solid", "fa-circle-notch", "fa-spin"], [1, "ob-hintbar"], ["type", "button", 1, "ob-hint-chip"], ["type", "button", 1, "ob-hint-chip", 3, "click"], ["role", "presentation", 1, "ob-group-label"], ["role", "option", 1, "ob-row", 3, "ob-row--sel"], ["role", "option", 1, "ob-row", 3, "focus", "keydown", "mouseenter", "click"], [1, "ob-ric"], [1, "ob-rmain"], [1, "ob-rname"], [1, "ob-rsub"], [1, "ob-raux"], [1, "ob-rtype"], [1, "ob-score"], [1, "ob-go"]], template: function OmnibarPaletteComponent_Template(rf, ctx) { if (rf & 1) {
883
+ } }, outputs: { Opened: "Opened", Closed: "Closed", SettingsRequested: "SettingsRequested" }, standalone: false, decls: 1, vars: 1, consts: [["paletteInput", ""], [1, "omnibar-overlay", 3, "click"], ["role", "dialog", "aria-modal", "true", "aria-label", "Command palette", 1, "omnibar-palette", 3, "keydown"], [1, "ob-input-row"], [1, "ob-field"], [1, "ob-lead"], [1, "fa-solid", "fa-magnifying-glass"], ["type", "text", "autocomplete", "off", "spellcheck", "false", "role", "combobox", "aria-controls", "ob-listbox", "aria-autocomplete", "list", 1, "ob-input", 3, "ngModelChange", "keydown", "placeholder", "ngModel"], [1, "ob-mode-badge"], [1, "ob-kbd"], ["type", "button", "aria-label", "Close", "title", "Close", 1, "ob-close", 3, "click"], [1, "fa-solid", "fa-xmark"], [1, "ob-scopes"], [1, "ob-body"], [1, "ob-loading"], ["id", "ob-listbox", "role", "listbox", "aria-label", "Suggestions"], [1, "ob-foot"], [1, "ob-k"], ["type", "button", "aria-label", "Command Palette settings", "title", "Command Palette settings", 1, "ob-settings", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-gear"], ["type", "button", 1, "ob-scope", 3, "click"], ["type", "button", 1, "ob-scope", 3, "ob-scope--on"], [1, "fa-solid", "fa-circle-notch", "fa-spin"], [1, "ob-hintbar"], ["type", "button", 1, "ob-hint-chip"], ["type", "button", 1, "ob-hint-chip", 3, "click"], ["role", "presentation", 1, "ob-group-label"], ["role", "option", 1, "ob-row", 3, "ob-row--sel"], ["role", "option", 1, "ob-row", 3, "focus", "keydown", "mouseenter", "click"], [1, "ob-ric"], [1, "ob-rmain"], [1, "ob-rname"], [1, "ob-rsub"], [1, "ob-raux"], [1, "ob-rtype"], [1, "ob-empty"], [1, "ob-score"], [1, "ob-go"]], template: function OmnibarPaletteComponent_Template(rf, ctx) { if (rf & 1) {
823
884
  i0.ɵɵconditionalCreate(0, OmnibarPaletteComponent_Conditional_0_Template, 36, 10);
824
885
  } if (rf & 2) {
825
886
  i0.ɵɵconditional(ctx.IsOpen ? 0 : -1);
@@ -827,7 +888,7 @@ export class OmnibarPaletteComponent {
827
888
  }
828
889
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(OmnibarPaletteComponent, [{
829
890
  type: Component,
830
- args: [{ standalone: false, selector: 'mj-omnibar-palette', changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (IsOpen) {\n <div class=\"omnibar-overlay\" (click)=\"Close()\"></div>\n <div class=\"omnibar-palette\" role=\"dialog\" aria-modal=\"true\" aria-label=\"Command palette\"\n (keydown)=\"OnPaletteKeydown($event)\">\n\n <div class=\"ob-input-row\">\n <div class=\"ob-field\">\n <span class=\"ob-lead\" [class.ob-lead--trigger]=\"ActiveTriggerChar.length > 0\">\n @if (ActiveTriggerChar.length > 0) {\n <b>{{ ActiveTriggerChar }}</b>\n } @else {\n <i class=\"fa-solid fa-magnifying-glass\"></i>\n }\n </span>\n <input #paletteInput class=\"ob-input\" type=\"text\" autocomplete=\"off\" spellcheck=\"false\"\n role=\"combobox\" aria-controls=\"ob-listbox\" aria-autocomplete=\"list\"\n [attr.aria-expanded]=\"HasOptions\"\n [attr.aria-activedescendant]=\"ActiveDescendantId\"\n [placeholder]=\"ActivePlaceholder\"\n [ngModel]=\"Query\" (ngModelChange)=\"OnQueryChange($event)\"\n (keydown)=\"OnInputKeydown($event)\" />\n <span class=\"ob-mode-badge\">{{ ActiveModeLabel }}</span>\n <kbd class=\"ob-kbd\">esc</kbd>\n </div>\n <button type=\"button\" class=\"ob-close\" aria-label=\"Close\" title=\"Close\" (click)=\"Close()\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n\n @if (ShowScopes && Scopes.length > 0) {\n <div class=\"ob-scopes\">\n <button type=\"button\" class=\"ob-scope\" [class.ob-scope--on]=\"SelectedScopeIDs.length === 0\"\n (click)=\"ClearScopes()\">All sources</button>\n @for (scope of Scopes; track scope.ID) {\n <button type=\"button\" class=\"ob-scope\" [class.ob-scope--on]=\"IsScopeSelected(scope.ID)\"\n (click)=\"ToggleScope(scope.ID)\">{{ scope.Name }}</button>\n }\n </div>\n }\n\n <div class=\"ob-body\">\n @if (IsLoading) {\n <div class=\"ob-loading\"><i class=\"fa-solid fa-circle-notch fa-spin\"></i> Searching\u2026</div>\n } @else if (Rows.length === 0 && Query.length === 0) {\n <div class=\"ob-hintbar\">\n @for (hint of TriggerHints; track hint.Char) {\n <button type=\"button\" class=\"ob-hint-chip\" (click)=\"SeedTrigger(hint.Char)\">\n <b>{{ hint.Char }}</b><span>{{ hint.Label }}</span>\n </button>\n }\n </div>\n @if (RecentRows.length > 0) {\n <div class=\"ob-group-label\" role=\"presentation\">Recent</div>\n <div id=\"ob-listbox\" role=\"listbox\" aria-label=\"Suggestions\">\n @for (row of RecentRows; track row.Suggestion.id; let i = $index) {\n <div class=\"ob-row\" role=\"option\" [attr.id]=\"'ob-opt-' + (RecentBaseIndex + i)\"\n [attr.tabindex]=\"RecentBaseIndex + i === SelectedIndex ? 0 : -1\"\n [attr.aria-selected]=\"RecentBaseIndex + i === SelectedIndex\"\n [class.ob-row--sel]=\"RecentBaseIndex + i === SelectedIndex\"\n (focus)=\"SelectedIndex = RecentBaseIndex + i\"\n (keydown)=\"OnRowKeydown($event, row.Suggestion)\"\n (mouseenter)=\"SelectedIndex = RecentBaseIndex + i\" (click)=\"Execute(row.Suggestion)\">\n <span class=\"ob-ric\"><i [class]=\"row.Suggestion.icon || 'fa-solid fa-clock-rotate-left'\"></i></span>\n <span class=\"ob-rmain\">\n <span class=\"ob-rname\">{{ row.Suggestion.displayName }}</span>\n <span class=\"ob-rsub\">{{ row.Suggestion.description }}</span>\n </span>\n <span class=\"ob-raux\"><span class=\"ob-rtype\">{{ row.Suggestion.type }}</span></span>\n </div>\n }\n </div>\n }\n } @else if (Rows.length === 0) {\n <div class=\"ob-empty\">No matches \u2014 press <kbd class=\"ob-kbd\">\u21B5</kbd> to search everything for \u201C{{ EffectiveQuery }}\u201D.</div>\n } @else {\n <div id=\"ob-listbox\" role=\"listbox\" aria-label=\"Suggestions\">\n @for (row of Rows; track row.Suggestion.id; let i = $index) {\n @if (row.GroupLabel) {\n <div class=\"ob-group-label\" role=\"presentation\">{{ row.GroupLabel }}</div>\n }\n <div class=\"ob-row\" role=\"option\" [attr.id]=\"'ob-opt-' + i\"\n [attr.tabindex]=\"i === SelectedIndex ? 0 : -1\"\n [attr.aria-selected]=\"i === SelectedIndex\"\n [class.ob-row--sel]=\"i === SelectedIndex\"\n (focus)=\"SelectedIndex = i\"\n (keydown)=\"OnRowKeydown($event, row.Suggestion)\"\n (mouseenter)=\"SelectedIndex = i\" (click)=\"Execute(row.Suggestion)\">\n <span class=\"ob-ric\"><i [class]=\"row.Suggestion.icon || 'fa-solid fa-circle'\"></i></span>\n <span class=\"ob-rmain\">\n <span class=\"ob-rname\">{{ row.Suggestion.displayName }}</span>\n @if (row.Suggestion.description) {\n <span class=\"ob-rsub\">{{ row.Suggestion.description }}</span>\n }\n </span>\n <span class=\"ob-raux\">\n @if (row.ScorePercent != null) {\n <span class=\"ob-score\"><i [style.width.%]=\"row.ScorePercent\"></i></span>\n }\n <span class=\"ob-rtype\">{{ row.Suggestion.type }}</span>\n <span class=\"ob-go\">open <kbd class=\"ob-kbd\">\u21B5</kbd></span>\n </span>\n </div>\n }\n </div>\n }\n </div>\n\n <div class=\"ob-foot\">\n <span class=\"ob-k\"><kbd class=\"ob-kbd\">\u2191</kbd><kbd class=\"ob-kbd\">\u2193</kbd> navigate</span>\n <span class=\"ob-k\"><kbd class=\"ob-kbd\">\u21B5</kbd> open</span>\n <button type=\"button\" class=\"ob-settings\" aria-label=\"Command Palette settings\"\n title=\"Command Palette settings\" (click)=\"RequestSettings()\">\n <i class=\"fa-solid fa-gear\" aria-hidden=\"true\"></i>\n <span>Settings</span>\n </button>\n </div>\n </div>\n}\n", styles: ["/* \u2500\u2500 Unified command palette (design source: plans/composer-adoption/mockups/omnibar-command-palette.html) \u2500\u2500 */\n\n.omnibar-overlay {\n position: fixed;\n inset: 0;\n background: var(--mj-bg-overlay);\n z-index: 1400;\n}\n\n/* Shared command-surface spec (omnibar + app launcher): banner-aware top\n offset, radius-lg, shadow-xl, boxed sunken input, whole-screen scrim. */\n.omnibar-palette {\n position: fixed;\n left: 50%;\n top: calc(60px + var(--mj-connectivity-banner-height, 0px) + var(--mj-space-6));\n transform: translateX(-50%);\n width: min(680px, 92vw);\n /* Grow to content \u2014 every fetched row plus the footer stays visible without\n internal scroll on desktop. The viewport bound below is the only cap, so\n .ob-body only scrolls when the screen genuinely can't fit the panel. */\n display: flex;\n flex-direction: column;\n max-height: calc(100vh - 60px - var(--mj-connectivity-banner-height, 0px) - var(--mj-space-12));\n background: var(--mj-bg-surface-elevated);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n box-shadow: var(--mj-shadow-xl);\n z-index: 1401;\n overflow: hidden;\n animation: ob-pop .13s ease-out;\n}\n\n@keyframes ob-pop {\n from { opacity: 0; transform: translateX(-50%) scale(.985) translateY(-4px); }\n to { opacity: 1; transform: translateX(-50%) scale(1); }\n}\n\n.ob-input-row {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n padding: var(--mj-space-4) var(--mj-space-4) var(--mj-space-2);\n}\n\n/* Boxed sunken field \u2014 identical treatment to the app launcher's filter. */\n.ob-field {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2-5);\n flex: 1;\n min-width: 0;\n height: 46px;\n padding: 0 var(--mj-space-3-5);\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n transition: border-color var(--mj-transition-fast);\n}\n.ob-field:focus-within {\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.ob-lead {\n color: var(--mj-text-muted);\n font-size: 15px;\n width: 18px;\n text-align: center;\n flex-shrink: 0;\n}\n\n.ob-lead--trigger { color: var(--mj-brand-primary); }\n.ob-lead b { font-family: ui-monospace, monospace; }\n\n.ob-input {\n flex: 1;\n border: none;\n outline: none;\n background: transparent;\n font-size: 16px;\n color: var(--mj-text-primary);\n font-family: inherit;\n}\n\n.ob-input::placeholder { color: var(--mj-text-muted); }\n\n.ob-mode-badge {\n font-size: 10.5px;\n font-weight: 700;\n letter-spacing: .4px;\n text-transform: uppercase;\n padding: 3px 9px;\n border-radius: var(--mj-radius-full, 999px);\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, transparent);\n color: var(--mj-brand-primary);\n white-space: nowrap;\n}\n\n.ob-kbd {\n font-family: inherit;\n font-size: 10.5px;\n font-weight: 600;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-bottom-width: 2px;\n border-radius: 5px;\n padding: 1.5px 6px;\n}\n\n.ob-close {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n padding: 0;\n border: none;\n border-radius: var(--mj-radius-md);\n background: transparent;\n color: var(--mj-text-muted);\n font-size: var(--mj-text-base);\n cursor: pointer;\n transition: var(--mj-transition-colors);\n flex-shrink: 0;\n}\n.ob-close:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n.ob-close:focus-visible {\n outline: 2px solid var(--mj-border-focus);\n outline-offset: 2px;\n}\n\n.ob-scopes {\n display: flex;\n gap: 6px;\n padding: 9px 18px;\n border-bottom: 1px solid var(--mj-border-subtle);\n flex-wrap: wrap;\n}\n\n.ob-scope {\n font-size: 11px;\n padding: 3px 10px;\n border-radius: var(--mj-radius-full, 999px);\n border: 1px solid var(--mj-border-default);\n color: var(--mj-text-secondary);\n cursor: pointer;\n background: transparent;\n}\n\n.ob-scope--on {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n.ob-body {\n flex: 1 1 auto;\n min-height: 0;\n overflow-y: auto;\n padding: 6px 0;\n}\n\n.ob-loading,\n.ob-empty {\n padding: 18px;\n text-align: center;\n color: var(--mj-text-muted);\n font-size: 13px;\n}\n\n.ob-group-label {\n font-size: 10.5px;\n font-weight: 700;\n letter-spacing: .6px;\n text-transform: uppercase;\n color: var(--mj-text-muted);\n padding: 10px 18px 5px;\n}\n\n.ob-row {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 9px 18px;\n cursor: pointer;\n}\n\n/* Rows are focus stops (roving tabindex): the --sel background tracks focus, so\n suppress the default outline but keep a ring for keyboard :focus-visible. */\n.ob-row:focus { outline: none; }\n.ob-row:focus-visible { outline: 2px solid var(--mj-border-focus); outline-offset: -2px; }\n\n/* Brand-tint selection \u2014 the one active-state language used across the shell\n (nav pills, launcher cards); the old left inset bar was a second dialect. */\n.ob-row--sel {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.ob-ric {\n width: 30px;\n height: 30px;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 13px;\n flex-shrink: 0;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.ob-row--sel .ob-ric {\n background: color-mix(in srgb, var(--mj-brand-primary) 16%, transparent);\n color: var(--mj-brand-primary);\n}\n\n.ob-rmain { flex: 1; min-width: 0; display: flex; flex-direction: column; }\n\n.ob-rname {\n font-size: 13.5px;\n font-weight: 500;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n color: var(--mj-text-primary);\n}\n\n.ob-rsub {\n font-size: 11.5px;\n color: var(--mj-text-muted);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n margin-top: 1px;\n}\n\n.ob-raux { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }\n\n.ob-rtype {\n font-size: 10px;\n font-weight: 600;\n padding: 2px 8px;\n border-radius: var(--mj-radius-full, 999px);\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n text-transform: capitalize;\n}\n\n.ob-score {\n width: 52px;\n height: 4px;\n border-radius: 2px;\n background: var(--mj-bg-surface-sunken);\n overflow: hidden;\n}\n\n.ob-score i { display: block; height: 100%; background: var(--mj-brand-primary); }\n\n.ob-go {\n font-size: 11px;\n color: var(--mj-text-muted);\n opacity: 0;\n display: flex;\n gap: 6px;\n align-items: center;\n}\n\n.ob-row--sel .ob-go { opacity: 1; }\n\n.ob-hintbar { display: flex; gap: 8px; padding: 12px 18px; flex-wrap: wrap; }\n\n.ob-hint-chip {\n display: flex;\n align-items: center;\n gap: 9px;\n padding: 9px 13px;\n border: 1px dashed var(--mj-border-strong);\n border-radius: 10px;\n cursor: pointer;\n background: transparent;\n}\n\n.ob-hint-chip:hover {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 6%, transparent);\n}\n\n.ob-hint-chip b { font-family: ui-monospace, monospace; color: var(--mj-brand-primary); font-size: 14px; }\n.ob-hint-chip span { font-size: 12px; color: var(--mj-text-secondary); }\n\n.ob-foot {\n display: flex;\n align-items: center;\n gap: 16px;\n padding: 10px 18px;\n border-top: 1px solid var(--mj-border-subtle);\n background: var(--mj-bg-surface-card);\n font-size: 11.5px;\n color: var(--mj-text-muted);\n}\n\n.ob-k { display: flex; align-items: center; gap: 5px; }\n\n/* Footer options button \u2014 the reverse door to My Profile \u2192 Command Palette.\n Shared spec with the launcher's Configure button: quiet labeled gear,\n right-aligned. */\n.ob-settings {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n margin-left: auto;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n font-family: inherit;\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n padding: var(--mj-space-1-5) var(--mj-space-2);\n border-radius: var(--mj-radius-md);\n cursor: pointer;\n transition: background var(--mj-transition-fast), color var(--mj-transition-fast);\n}\n.ob-settings:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n.ob-settings:focus-visible {\n outline: 2px solid var(--mj-border-focus);\n outline-offset: 2px;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .omnibar-palette {\n animation: none;\n }\n}\n\n/* ========================================\n MOBILE (matches mj-search-overlay's 640px sheet treatment so the two search\n surfaces sit identically on small viewports)\n ======================================== */\n@media (max-width: 640px) {\n .omnibar-palette {\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n transform: none;\n width: 100%;\n height: 100dvh;\n max-height: none; /* desktop viewport bound would clamp the full-height sheet */\n border-radius: 0;\n animation: none; /* ob-pop animates a translateX(-50%) that no longer applies */\n display: flex;\n flex-direction: column;\n }\n\n /* Full-height sheet: the results area absorbs all remaining space. */\n .ob-body {\n flex: 1;\n min-height: 0;\n max-height: none;\n }\n\n /* Keyboard chrome is meaningless on touch: esc/\u21B5 chips, per-row 'open \u21B5'\n hints, and the footer's nav-hint spans. The footer itself stays because it\n carries the settings gear \u2014 the only in-surface door to the opt-in toggle,\n which mobile users need too. The \u2715 close button also stays. */\n .ob-kbd,\n .ob-go,\n .ob-k {\n display: none;\n }\n\n /* Touch-friendly hit areas for the surviving controls. */\n .ob-close {\n width: 40px;\n height: 40px;\n font-size: var(--mj-text-base);\n }\n .ob-settings {\n min-height: 40px;\n font-size: var(--mj-text-base);\n }\n}\n"] }]
891
+ args: [{ standalone: false, selector: 'mj-omnibar-palette', changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (IsOpen) {\n <div class=\"omnibar-overlay\" (click)=\"Close()\"></div>\n <div class=\"omnibar-palette\" role=\"dialog\" aria-modal=\"true\" aria-label=\"Command palette\"\n (keydown)=\"OnPaletteKeydown($event)\">\n\n <div class=\"ob-input-row\">\n <div class=\"ob-field\">\n <span class=\"ob-lead\" [class.ob-lead--trigger]=\"ActiveTriggerChar.length > 0\">\n @if (ActiveTriggerChar.length > 0) {\n <b>{{ ActiveTriggerChar }}</b>\n } @else {\n <i class=\"fa-solid fa-magnifying-glass\"></i>\n }\n </span>\n <input #paletteInput class=\"ob-input\" type=\"text\" autocomplete=\"off\" spellcheck=\"false\"\n role=\"combobox\" aria-controls=\"ob-listbox\" aria-autocomplete=\"list\"\n [attr.aria-expanded]=\"HasOptions\"\n [attr.aria-activedescendant]=\"ActiveDescendantId\"\n [placeholder]=\"ActivePlaceholder\"\n [ngModel]=\"Query\" (ngModelChange)=\"OnQueryChange($event)\"\n (keydown)=\"OnInputKeydown($event)\" />\n <span class=\"ob-mode-badge\">{{ ActiveModeLabel }}</span>\n <kbd class=\"ob-kbd\">esc</kbd>\n </div>\n <button type=\"button\" class=\"ob-close\" aria-label=\"Close\" title=\"Close\" (click)=\"Close()\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n\n @if (ShowScopes && Scopes.length > 0) {\n <div class=\"ob-scopes\">\n <button type=\"button\" class=\"ob-scope\" [class.ob-scope--on]=\"SelectedScopeIDs.length === 0\"\n (click)=\"ClearScopes()\">All sources</button>\n @for (scope of Scopes; track scope.ID) {\n <button type=\"button\" class=\"ob-scope\" [class.ob-scope--on]=\"IsScopeSelected(scope.ID)\"\n (click)=\"ToggleScope(scope.ID)\">{{ scope.Name }}</button>\n }\n </div>\n }\n\n <div class=\"ob-body\">\n @if (IsLoading) {\n <div class=\"ob-loading\"><i class=\"fa-solid fa-circle-notch fa-spin\"></i> Searching\u2026</div>\n } @else if (Rows.length === 0 && Query.length === 0) {\n <div class=\"ob-hintbar\">\n @for (hint of TriggerHints; track hint.Char) {\n <button type=\"button\" class=\"ob-hint-chip\" (click)=\"SeedTrigger(hint.Char)\">\n <b>{{ hint.Char }}</b><span>{{ hint.Label }}</span>\n </button>\n }\n </div>\n @if (RecentRows.length > 0) {\n <div class=\"ob-group-label\" role=\"presentation\">Recent</div>\n <div id=\"ob-listbox\" role=\"listbox\" aria-label=\"Suggestions\">\n @for (row of RecentRows; track row.Suggestion.id; let i = $index) {\n <div class=\"ob-row\" role=\"option\" [attr.id]=\"'ob-opt-' + (RecentBaseIndex + i)\"\n [attr.tabindex]=\"RecentBaseIndex + i === SelectedIndex ? 0 : -1\"\n [attr.aria-selected]=\"RecentBaseIndex + i === SelectedIndex\"\n [class.ob-row--sel]=\"RecentBaseIndex + i === SelectedIndex\"\n (focus)=\"SelectedIndex = RecentBaseIndex + i\"\n (keydown)=\"OnRowKeydown($event, row.Suggestion)\"\n (mouseenter)=\"SelectedIndex = RecentBaseIndex + i\" (click)=\"Execute(row.Suggestion)\">\n <span class=\"ob-ric\"><i [class]=\"row.Suggestion.icon || 'fa-solid fa-clock-rotate-left'\"></i></span>\n <span class=\"ob-rmain\">\n <span class=\"ob-rname\">{{ row.Suggestion.displayName }}</span>\n <span class=\"ob-rsub\">{{ row.Suggestion.description }}</span>\n </span>\n <span class=\"ob-raux\"><span class=\"ob-rtype\">{{ row.Suggestion.type }}</span></span>\n </div>\n }\n </div>\n }\n } @else if (Rows.length === 0) {\n <!-- Only promise the Enter escape hatch when Enter will actually take it \u2014\n CanEscapeToFullSearch gates both, so the two can't drift apart. It's false for\n a 1-char query, and in a trigger mode until the fetch settles. -->\n @if (CanEscapeToFullSearch) {\n <div class=\"ob-empty\">No matches \u2014 press <kbd class=\"ob-kbd\">\u21B5</kbd> to search everything for \u201C{{ EffectiveQuery }}\u201D.</div>\n } @else {\n <div class=\"ob-empty\">No matches for \u201C{{ EffectiveQuery }}\u201D.</div>\n }\n } @else {\n <div id=\"ob-listbox\" role=\"listbox\" aria-label=\"Suggestions\">\n @for (row of Rows; track row.Suggestion.id; let i = $index) {\n @if (row.GroupLabel !== null) {\n <div class=\"ob-group-label\" role=\"presentation\">{{ row.GroupLabel }}</div>\n }\n <div class=\"ob-row\" role=\"option\" [attr.id]=\"'ob-opt-' + i\"\n [attr.tabindex]=\"i === SelectedIndex ? 0 : -1\"\n [attr.aria-selected]=\"i === SelectedIndex\"\n [class.ob-row--sel]=\"i === SelectedIndex\"\n (focus)=\"SelectedIndex = i\"\n (keydown)=\"OnRowKeydown($event, row.Suggestion)\"\n (mouseenter)=\"SelectedIndex = i\" (click)=\"Execute(row.Suggestion)\">\n <span class=\"ob-ric\"><i [class]=\"row.Suggestion.icon || 'fa-solid fa-circle'\"></i></span>\n <span class=\"ob-rmain\">\n <span class=\"ob-rname\">{{ row.Suggestion.displayName }}</span>\n @if (row.Suggestion.description) {\n <span class=\"ob-rsub\">{{ row.Suggestion.description }}</span>\n }\n </span>\n <span class=\"ob-raux\">\n @if (row.ScorePercent != null) {\n <span class=\"ob-score\"><i [style.width.%]=\"row.ScorePercent\"></i></span>\n }\n <span class=\"ob-rtype\">{{ row.Suggestion.type }}</span>\n <span class=\"ob-go\">open <kbd class=\"ob-kbd\">\u21B5</kbd></span>\n </span>\n </div>\n }\n </div>\n }\n </div>\n\n <div class=\"ob-foot\">\n <span class=\"ob-k\"><kbd class=\"ob-kbd\">\u2191</kbd><kbd class=\"ob-kbd\">\u2193</kbd> navigate</span>\n <span class=\"ob-k\"><kbd class=\"ob-kbd\">\u21B5</kbd> open</span>\n <button type=\"button\" class=\"ob-settings\" aria-label=\"Command Palette settings\"\n title=\"Command Palette settings\" (click)=\"RequestSettings()\">\n <i class=\"fa-solid fa-gear\" aria-hidden=\"true\"></i>\n <span>Settings</span>\n </button>\n </div>\n </div>\n}\n", styles: ["/* \u2500\u2500 Unified command palette (design source: plans/composer-adoption/mockups/omnibar-command-palette.html) \u2500\u2500 */\n\n.omnibar-overlay {\n position: fixed;\n inset: 0;\n background: var(--mj-bg-overlay);\n z-index: 1400;\n}\n\n/* Shared command-surface spec (omnibar + app launcher): banner-aware top\n offset, radius-lg, shadow-xl, boxed sunken input, whole-screen scrim. */\n.omnibar-palette {\n position: fixed;\n left: 50%;\n top: calc(60px + var(--mj-connectivity-banner-height, 0px) + var(--mj-space-6));\n transform: translateX(-50%);\n width: min(680px, 92vw);\n /* Grow to content \u2014 every fetched row plus the footer stays visible without\n internal scroll on desktop. The viewport bound below is the only cap, so\n .ob-body only scrolls when the screen genuinely can't fit the panel. */\n display: flex;\n flex-direction: column;\n max-height: calc(100vh - 60px - var(--mj-connectivity-banner-height, 0px) - var(--mj-space-12));\n background: var(--mj-bg-surface-elevated);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n box-shadow: var(--mj-shadow-xl);\n z-index: 1401;\n overflow: hidden;\n animation: ob-pop .13s ease-out;\n}\n\n@keyframes ob-pop {\n from { opacity: 0; transform: translateX(-50%) scale(.985) translateY(-4px); }\n to { opacity: 1; transform: translateX(-50%) scale(1); }\n}\n\n.ob-input-row {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n padding: var(--mj-space-4) var(--mj-space-4) var(--mj-space-2);\n}\n\n/* Boxed sunken field \u2014 identical treatment to the app launcher's filter. */\n.ob-field {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2-5);\n flex: 1;\n min-width: 0;\n height: 46px;\n padding: 0 var(--mj-space-3-5);\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n transition: border-color var(--mj-transition-fast);\n}\n.ob-field:focus-within {\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.ob-lead {\n color: var(--mj-text-muted);\n font-size: 15px;\n width: 18px;\n text-align: center;\n flex-shrink: 0;\n}\n\n.ob-lead--trigger { color: var(--mj-brand-primary); }\n.ob-lead b { font-family: ui-monospace, monospace; }\n\n.ob-input {\n flex: 1;\n border: none;\n outline: none;\n background: transparent;\n font-size: 16px;\n color: var(--mj-text-primary);\n font-family: inherit;\n}\n\n.ob-input::placeholder { color: var(--mj-text-muted); }\n\n.ob-mode-badge {\n font-size: 10.5px;\n font-weight: 700;\n letter-spacing: .4px;\n text-transform: uppercase;\n padding: 3px 9px;\n border-radius: var(--mj-radius-full, 999px);\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, transparent);\n color: var(--mj-brand-primary);\n white-space: nowrap;\n}\n\n.ob-kbd {\n font-family: inherit;\n font-size: 10.5px;\n font-weight: 600;\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-bottom-width: 2px;\n border-radius: 5px;\n padding: 1.5px 6px;\n}\n\n.ob-close {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n padding: 0;\n border: none;\n border-radius: var(--mj-radius-md);\n background: transparent;\n color: var(--mj-text-muted);\n font-size: var(--mj-text-base);\n cursor: pointer;\n transition: var(--mj-transition-colors);\n flex-shrink: 0;\n}\n.ob-close:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n.ob-close:focus-visible {\n outline: 2px solid var(--mj-border-focus);\n outline-offset: 2px;\n}\n\n.ob-scopes {\n display: flex;\n gap: 6px;\n padding: 9px 18px;\n border-bottom: 1px solid var(--mj-border-subtle);\n flex-wrap: wrap;\n}\n\n.ob-scope {\n font-size: 11px;\n padding: 3px 10px;\n border-radius: var(--mj-radius-full, 999px);\n border: 1px solid var(--mj-border-default);\n color: var(--mj-text-secondary);\n cursor: pointer;\n background: transparent;\n}\n\n.ob-scope--on {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n.ob-body {\n flex: 1 1 auto;\n min-height: 0;\n overflow-y: auto;\n padding: 6px 0;\n}\n\n.ob-loading,\n.ob-empty {\n padding: 18px;\n text-align: center;\n color: var(--mj-text-muted);\n font-size: 13px;\n}\n\n.ob-group-label {\n font-size: 10.5px;\n font-weight: 700;\n letter-spacing: .6px;\n text-transform: uppercase;\n color: var(--mj-text-muted);\n padding: 10px 18px 5px;\n}\n\n.ob-row {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 9px 18px;\n cursor: pointer;\n}\n\n/* Rows are focus stops (roving tabindex): the --sel background tracks focus, so\n suppress the default outline but keep a ring for keyboard :focus-visible. */\n.ob-row:focus { outline: none; }\n.ob-row:focus-visible { outline: 2px solid var(--mj-border-focus); outline-offset: -2px; }\n\n/* Brand-tint selection \u2014 the one active-state language used across the shell\n (nav pills, launcher cards); the old left inset bar was a second dialect. */\n.ob-row--sel {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.ob-ric {\n width: 30px;\n height: 30px;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 13px;\n flex-shrink: 0;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.ob-row--sel .ob-ric {\n background: color-mix(in srgb, var(--mj-brand-primary) 16%, transparent);\n color: var(--mj-brand-primary);\n}\n\n.ob-rmain { flex: 1; min-width: 0; display: flex; flex-direction: column; }\n\n.ob-rname {\n font-size: 13.5px;\n font-weight: 500;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n color: var(--mj-text-primary);\n}\n\n.ob-rsub {\n font-size: 11.5px;\n color: var(--mj-text-muted);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n margin-top: 1px;\n}\n\n.ob-raux { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }\n\n.ob-rtype {\n font-size: 10px;\n font-weight: 600;\n padding: 2px 8px;\n border-radius: var(--mj-radius-full, 999px);\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n text-transform: capitalize;\n}\n\n.ob-score {\n width: 52px;\n height: 4px;\n border-radius: 2px;\n background: var(--mj-bg-surface-sunken);\n overflow: hidden;\n}\n\n.ob-score i { display: block; height: 100%; background: var(--mj-brand-primary); }\n\n.ob-go {\n font-size: 11px;\n color: var(--mj-text-muted);\n opacity: 0;\n display: flex;\n gap: 6px;\n align-items: center;\n}\n\n.ob-row--sel .ob-go { opacity: 1; }\n\n.ob-hintbar { display: flex; gap: 8px; padding: 12px 18px; flex-wrap: wrap; }\n\n.ob-hint-chip {\n display: flex;\n align-items: center;\n gap: 9px;\n padding: 9px 13px;\n border: 1px dashed var(--mj-border-strong);\n border-radius: 10px;\n cursor: pointer;\n background: transparent;\n}\n\n.ob-hint-chip:hover {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 6%, transparent);\n}\n\n.ob-hint-chip b { font-family: ui-monospace, monospace; color: var(--mj-brand-primary); font-size: 14px; }\n.ob-hint-chip span { font-size: 12px; color: var(--mj-text-secondary); }\n\n.ob-foot {\n display: flex;\n align-items: center;\n gap: 16px;\n padding: 10px 18px;\n border-top: 1px solid var(--mj-border-subtle);\n background: var(--mj-bg-surface-card);\n font-size: 11.5px;\n color: var(--mj-text-muted);\n}\n\n.ob-k { display: flex; align-items: center; gap: 5px; }\n\n/* Footer options button \u2014 the reverse door to My Profile \u2192 Command Palette.\n Shared spec with the launcher's Configure button: quiet labeled gear,\n right-aligned. */\n.ob-settings {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n margin-left: auto;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n font-family: inherit;\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n padding: var(--mj-space-1-5) var(--mj-space-2);\n border-radius: var(--mj-radius-md);\n cursor: pointer;\n transition: background var(--mj-transition-fast), color var(--mj-transition-fast);\n}\n.ob-settings:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n.ob-settings:focus-visible {\n outline: 2px solid var(--mj-border-focus);\n outline-offset: 2px;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .omnibar-palette {\n animation: none;\n }\n}\n\n/* ========================================\n MOBILE (matches mj-search-overlay's 640px sheet treatment so the two search\n surfaces sit identically on small viewports)\n ======================================== */\n@media (max-width: 640px) {\n .omnibar-palette {\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n transform: none;\n width: 100%;\n height: 100dvh;\n max-height: none; /* desktop viewport bound would clamp the full-height sheet */\n border-radius: 0;\n animation: none; /* ob-pop animates a translateX(-50%) that no longer applies */\n display: flex;\n flex-direction: column;\n }\n\n /* Full-height sheet: the results area absorbs all remaining space. */\n .ob-body {\n flex: 1;\n min-height: 0;\n max-height: none;\n }\n\n /* Keyboard chrome is meaningless on touch: esc/\u21B5 chips, per-row 'open \u21B5'\n hints, and the footer's nav-hint spans. The footer itself stays because it\n carries the settings gear \u2014 the only in-surface door to the opt-in toggle,\n which mobile users need too. The \u2715 close button also stays. */\n .ob-kbd,\n .ob-go,\n .ob-k {\n display: none;\n }\n\n /* Touch-friendly hit areas for the surviving controls. */\n .ob-close {\n width: 40px;\n height: 40px;\n font-size: var(--mj-text-base);\n }\n .ob-settings {\n min-height: 40px;\n font-size: var(--mj-text-base);\n }\n}\n"] }]
831
892
  }], null, { inputRef: [{
832
893
  type: ViewChild,
833
894
  args: ['paletteInput']
@@ -838,7 +899,7 @@ export class OmnibarPaletteComponent {
838
899
  }], SettingsRequested: [{
839
900
  type: Output
840
901
  }] }); })();
841
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(OmnibarPaletteComponent, { className: "OmnibarPaletteComponent", filePath: "src/lib/omnibar/omnibar-palette.component.ts", lineNumber: 57 }); })();
902
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(OmnibarPaletteComponent, { className: "OmnibarPaletteComponent", filePath: "src/lib/omnibar/omnibar-palette.component.ts", lineNumber: 61 }); })();
842
903
  /** Tree-shaking guard for the palette component. */
843
904
  export function LoadOmnibarPaletteComponent() {
844
905
  // intentional no-op