@memberjunction/ng-explorer-core 5.23.0 → 5.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/dist/app-routing.module.d.ts.map +1 -1
  2. package/dist/app-routing.module.js +15 -22
  3. package/dist/app-routing.module.js.map +1 -1
  4. package/dist/generated/lazy-feature-config.d.ts +1 -1
  5. package/dist/generated/lazy-feature-config.d.ts.map +1 -1
  6. package/dist/generated/lazy-feature-config.js +6 -4
  7. package/dist/generated/lazy-feature-config.js.map +1 -1
  8. package/dist/lib/resource-wrappers/artifact-resource.component.d.ts.map +1 -1
  9. package/dist/lib/resource-wrappers/artifact-resource.component.js +1 -0
  10. package/dist/lib/resource-wrappers/artifact-resource.component.js.map +1 -1
  11. package/dist/lib/resource-wrappers/chat-collections-resource.component.d.ts +16 -17
  12. package/dist/lib/resource-wrappers/chat-collections-resource.component.d.ts.map +1 -1
  13. package/dist/lib/resource-wrappers/chat-collections-resource.component.js +56 -62
  14. package/dist/lib/resource-wrappers/chat-collections-resource.component.js.map +1 -1
  15. package/dist/lib/resource-wrappers/chat-conversations-resource.component.d.ts +2 -4
  16. package/dist/lib/resource-wrappers/chat-conversations-resource.component.d.ts.map +1 -1
  17. package/dist/lib/resource-wrappers/chat-conversations-resource.component.js +9 -13
  18. package/dist/lib/resource-wrappers/chat-conversations-resource.component.js.map +1 -1
  19. package/dist/lib/resource-wrappers/chat-tasks-resource.component.d.ts +2 -15
  20. package/dist/lib/resource-wrappers/chat-tasks-resource.component.d.ts.map +1 -1
  21. package/dist/lib/resource-wrappers/chat-tasks-resource.component.js +18 -52
  22. package/dist/lib/resource-wrappers/chat-tasks-resource.component.js.map +1 -1
  23. package/dist/lib/resource-wrappers/dashboard-resource.component.d.ts +2 -3
  24. package/dist/lib/resource-wrappers/dashboard-resource.component.d.ts.map +1 -1
  25. package/dist/lib/resource-wrappers/dashboard-resource.component.js +7 -9
  26. package/dist/lib/resource-wrappers/dashboard-resource.component.js.map +1 -1
  27. package/dist/lib/resource-wrappers/list-detail-resource.component.d.ts +3 -1
  28. package/dist/lib/resource-wrappers/list-detail-resource.component.d.ts.map +1 -1
  29. package/dist/lib/resource-wrappers/list-detail-resource.component.js +4 -0
  30. package/dist/lib/resource-wrappers/list-detail-resource.component.js.map +1 -1
  31. package/dist/lib/resource-wrappers/notifications-resource.component.d.ts.map +1 -1
  32. package/dist/lib/resource-wrappers/notifications-resource.component.js +2 -0
  33. package/dist/lib/resource-wrappers/notifications-resource.component.js.map +1 -1
  34. package/dist/lib/resource-wrappers/query-resource.component.js +1 -0
  35. package/dist/lib/resource-wrappers/query-resource.component.js.map +1 -1
  36. package/dist/lib/resource-wrappers/search-results-resource.component.d.ts +74 -4
  37. package/dist/lib/resource-wrappers/search-results-resource.component.d.ts.map +1 -1
  38. package/dist/lib/resource-wrappers/search-results-resource.component.js +786 -25
  39. package/dist/lib/resource-wrappers/search-results-resource.component.js.map +1 -1
  40. package/dist/lib/resource-wrappers/view-resource.component.d.ts +7 -4
  41. package/dist/lib/resource-wrappers/view-resource.component.d.ts.map +1 -1
  42. package/dist/lib/resource-wrappers/view-resource.component.js +30 -14
  43. package/dist/lib/resource-wrappers/view-resource.component.js.map +1 -1
  44. package/dist/lib/services/startup-validation.service.d.ts.map +1 -1
  45. package/dist/lib/services/startup-validation.service.js +0 -3
  46. package/dist/lib/services/startup-validation.service.js.map +1 -1
  47. package/dist/lib/shell/components/tabs/component-cache-manager.d.ts +7 -0
  48. package/dist/lib/shell/components/tabs/component-cache-manager.d.ts.map +1 -1
  49. package/dist/lib/shell/components/tabs/component-cache-manager.js.map +1 -1
  50. package/dist/lib/shell/components/tabs/tab-container.component.d.ts.map +1 -1
  51. package/dist/lib/shell/components/tabs/tab-container.component.js +10 -4
  52. package/dist/lib/shell/components/tabs/tab-container.component.js.map +1 -1
  53. package/dist/lib/shell/shell.component.d.ts +28 -8
  54. package/dist/lib/shell/shell.component.d.ts.map +1 -1
  55. package/dist/lib/shell/shell.component.js +416 -219
  56. package/dist/lib/shell/shell.component.js.map +1 -1
  57. package/dist/lib/shell/shell.module.d.ts +2 -1
  58. package/dist/lib/shell/shell.module.d.ts.map +1 -1
  59. package/dist/lib/shell/shell.module.js +7 -3
  60. package/dist/lib/shell/shell.module.js.map +1 -1
  61. package/dist/lib/single-dashboard/Components/add-item/add-item.component.d.ts +6 -0
  62. package/dist/lib/single-dashboard/Components/add-item/add-item.component.d.ts.map +1 -1
  63. package/dist/lib/single-dashboard/Components/add-item/add-item.component.js +63 -38
  64. package/dist/lib/single-dashboard/Components/add-item/add-item.component.js.map +1 -1
  65. package/dist/lib/single-dashboard/single-dashboard.component.d.ts.map +1 -1
  66. package/dist/lib/single-dashboard/single-dashboard.component.js +1 -0
  67. package/dist/lib/single-dashboard/single-dashboard.component.js.map +1 -1
  68. package/dist/lib/user-menu/base-user-menu.d.ts +7 -7
  69. package/dist/lib/user-menu/base-user-menu.d.ts.map +1 -1
  70. package/dist/lib/user-menu/base-user-menu.js +8 -1
  71. package/dist/lib/user-menu/base-user-menu.js.map +1 -1
  72. package/dist/lib/user-menu/user-menu.types.d.ts +15 -0
  73. package/dist/lib/user-menu/user-menu.types.d.ts.map +1 -1
  74. package/dist/lib/user-menu/user-menu.types.js.map +1 -1
  75. package/dist/lib/user-notifications/user-notifications.component.d.ts +6 -3
  76. package/dist/lib/user-notifications/user-notifications.component.d.ts.map +1 -1
  77. package/dist/lib/user-notifications/user-notifications.component.js +46 -19
  78. package/dist/lib/user-notifications/user-notifications.component.js.map +1 -1
  79. package/dist/module.d.ts +53 -52
  80. package/dist/module.d.ts.map +1 -1
  81. package/dist/module.js +11 -7
  82. package/dist/module.js.map +1 -1
  83. package/dist/public-api.d.ts +0 -1
  84. package/dist/public-api.d.ts.map +1 -1
  85. package/dist/public-api.js +0 -1
  86. package/dist/public-api.js.map +1 -1
  87. package/package.json +40 -37
  88. package/dist/lib/generic/form-toolbar.d.ts +0 -8
  89. package/dist/lib/generic/form-toolbar.d.ts.map +0 -1
  90. package/dist/lib/generic/form-toolbar.js +0 -114
  91. package/dist/lib/generic/form-toolbar.js.map +0 -1
@@ -9,6 +9,7 @@ import { MJNotificationService } from '@memberjunction/ng-notifications';
9
9
  import { getActiveTheme } from './loading-themes';
10
10
  import { TabContainerComponent } from './components/tabs/tab-container.component';
11
11
  import { BaseUserMenu, isUserMenuDivider } from '../user-menu';
12
+ import { InstanceConfigEngine } from '@memberjunction/core-entities';
12
13
  import * as i0 from "@angular/core";
13
14
  import * as i1 from "@memberjunction/ng-base-application";
14
15
  import * as i2 from "@memberjunction/ng-shared";
@@ -17,19 +18,22 @@ import * as i4 from "@memberjunction/ng-auth-services";
17
18
  import * as i5 from "@memberjunction/ng-user-avatar";
18
19
  import * as i6 from "./services/settings-dialog.service";
19
20
  import * as i7 from "../command-palette/command-palette.service";
20
- import * as i8 from "@angular/forms";
21
- import * as i9 from "@memberjunction/ng-ui-components";
22
- import * as i10 from "@memberjunction/ng-shared-generic";
23
- import * as i11 from "./components/header/app-switcher.component";
24
- import * as i12 from "./components/header/app-nav.component";
25
- import * as i13 from "./components/tabs/tab-container.component";
26
- import * as i14 from "./components/dialogs/app-access-dialog.component";
27
- import * as i15 from "../command-palette/command-palette.component";
21
+ import * as i8 from "@memberjunction/ng-file-storage";
22
+ import * as i9 from "@angular/forms";
23
+ import * as i10 from "@memberjunction/ng-ui-components";
24
+ import * as i11 from "@memberjunction/ng-shared-generic";
25
+ import * as i12 from "@memberjunction/ng-search";
26
+ import * as i13 from "./components/header/app-switcher.component";
27
+ import * as i14 from "./components/header/app-nav.component";
28
+ import * as i15 from "./components/tabs/tab-container.component";
29
+ import * as i16 from "./components/dialogs/app-access-dialog.component";
30
+ import * as i17 from "../command-palette/command-palette.component";
28
31
  const _c0 = ["searchInput"];
29
- const _c1 = ["appAccessDialog"];
32
+ const _c1 = ["shellSearchComposite"];
33
+ const _c2 = ["appAccessDialog"];
30
34
  function ShellComponent_Conditional_5_For_2_Template(rf, ctx) { if (rf & 1) {
31
35
  const _r2 = i0.ɵɵgetCurrentView();
32
- i0.ɵɵelementStart(0, "button", 45);
36
+ i0.ɵɵelementStart(0, "button", 46);
33
37
  i0.ɵɵlistener("click", function ShellComponent_Conditional_5_For_2_Template_button_click_0_listener($event) { const app_r3 = i0.ɵɵrestoreView(_r2).$implicit; const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.onNavBarAppClick(app_r3, $event)); })("dblclick", function ShellComponent_Conditional_5_For_2_Template_button_dblclick_0_listener($event) { const app_r3 = i0.ɵɵrestoreView(_r2).$implicit; const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.onNavBarAppDblClick(app_r3, $event)); });
34
38
  i0.ɵɵelement(1, "i");
35
39
  i0.ɵɵelementEnd();
@@ -43,8 +47,8 @@ function ShellComponent_Conditional_5_For_2_Template(rf, ctx) { if (rf & 1) {
43
47
  i0.ɵɵclassMap(app_r3.Icon);
44
48
  } }
45
49
  function ShellComponent_Conditional_5_Template(rf, ctx) { if (rf & 1) {
46
- i0.ɵɵelementStart(0, "div", 7);
47
- i0.ɵɵrepeaterCreate(1, ShellComponent_Conditional_5_For_2_Template, 2, 7, "button", 44, i0.ɵɵrepeaterTrackByIdentity);
50
+ i0.ɵɵelementStart(0, "div", 8);
51
+ i0.ɵɵrepeaterCreate(1, ShellComponent_Conditional_5_For_2_Template, 2, 7, "button", 45, i0.ɵɵrepeaterTrackByIdentity);
48
52
  i0.ɵɵelementEnd();
49
53
  } if (rf & 2) {
50
54
  const ctx_r3 = i0.ɵɵnextContext();
@@ -53,14 +57,24 @@ function ShellComponent_Conditional_5_Template(rf, ctx) { if (rf & 1) {
53
57
  } }
54
58
  function ShellComponent_Conditional_7_Template(rf, ctx) { if (rf & 1) {
55
59
  const _r5 = i0.ɵɵgetCurrentView();
56
- i0.ɵɵelementStart(0, "mj-app-nav", 46);
60
+ i0.ɵɵelementStart(0, "mj-app-nav", 47);
57
61
  i0.ɵɵlistener("navItemClick", function ShellComponent_Conditional_7_Template_mj_app_nav_navItemClick_0_listener($event) { i0.ɵɵrestoreView(_r5); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onNavItemClick($event)); })("navItemDismiss", function ShellComponent_Conditional_7_Template_mj_app_nav_navItemDismiss_0_listener($event) { i0.ɵɵrestoreView(_r5); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onNavItemDismiss($event)); });
58
62
  i0.ɵɵelementEnd();
59
63
  } if (rf & 2) {
60
64
  const ctx_r3 = i0.ɵɵnextContext();
61
65
  i0.ɵɵproperty("app", ctx_r3.activeApp);
62
66
  } }
63
- function ShellComponent_Conditional_14_Template(rf, ctx) { if (rf & 1) {
67
+ function ShellComponent_Conditional_8_Template(rf, ctx) { if (rf & 1) {
68
+ const _r6 = i0.ɵɵgetCurrentView();
69
+ i0.ɵɵelementStart(0, "div", 11)(1, "mj-search-composite", 48, 2);
70
+ i0.ɵɵlistener("ResultSelected", function ShellComponent_Conditional_8_Template_mj_search_composite_ResultSelected_1_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.OnSearchResultSelected($event)); })("SearchSubmitted", function ShellComponent_Conditional_8_Template_mj_search_composite_SearchSubmitted_1_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.OnSearchSubmitted($event)); })("SeeAllRequested", function ShellComponent_Conditional_8_Template_mj_search_composite_SeeAllRequested_1_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.OnSeeAllSearch($event)); });
71
+ i0.ɵɵelementEnd()();
72
+ } if (rf & 2) {
73
+ const ctx_r3 = i0.ɵɵnextContext();
74
+ i0.ɵɵadvance();
75
+ i0.ɵɵproperty("ShowShortcutHint", true)("EnablePreview", ctx_r3.ShowSearchPreview)("EnableRecent", true)("MaxPreviewResults", 8);
76
+ } }
77
+ function ShellComponent_Conditional_13_Template(rf, ctx) { if (rf & 1) {
64
78
  i0.ɵɵelementStart(0, "span", 16);
65
79
  i0.ɵɵtext(1);
66
80
  i0.ɵɵelementEnd();
@@ -69,37 +83,37 @@ function ShellComponent_Conditional_14_Template(rf, ctx) { if (rf & 1) {
69
83
  i0.ɵɵadvance();
70
84
  i0.ɵɵtextInterpolate1(" ", ctx_r3.unreadNotificationCount > 99 ? "99+" : ctx_r3.unreadNotificationCount, " ");
71
85
  } }
72
- function ShellComponent_Conditional_15_For_2_Template(rf, ctx) { if (rf & 1) {
73
- const _r6 = i0.ɵɵgetCurrentView();
74
- i0.ɵɵelementStart(0, "button", 45);
75
- i0.ɵɵlistener("click", function ShellComponent_Conditional_15_For_2_Template_button_click_0_listener($event) { const app_r7 = i0.ɵɵrestoreView(_r6).$implicit; const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.onNavBarAppClick(app_r7, $event)); })("dblclick", function ShellComponent_Conditional_15_For_2_Template_button_dblclick_0_listener($event) { const app_r7 = i0.ɵɵrestoreView(_r6).$implicit; const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.onNavBarAppDblClick(app_r7, $event)); });
86
+ function ShellComponent_Conditional_14_For_2_Template(rf, ctx) { if (rf & 1) {
87
+ const _r7 = i0.ɵɵgetCurrentView();
88
+ i0.ɵɵelementStart(0, "button", 46);
89
+ i0.ɵɵlistener("click", function ShellComponent_Conditional_14_For_2_Template_button_click_0_listener($event) { const app_r8 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.onNavBarAppClick(app_r8, $event)); })("dblclick", function ShellComponent_Conditional_14_For_2_Template_button_dblclick_0_listener($event) { const app_r8 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.onNavBarAppDblClick(app_r8, $event)); });
76
90
  i0.ɵɵelement(1, "i");
77
91
  i0.ɵɵelementEnd();
78
92
  } if (rf & 2) {
79
- const app_r7 = ctx.$implicit;
93
+ const app_r8 = ctx.$implicit;
80
94
  const ctx_r3 = i0.ɵɵnextContext(2);
81
- i0.ɵɵstyleProp("--app-color", app_r7.GetColor());
82
- i0.ɵɵclassProp("active", ctx_r3.IsActiveApp(app_r7));
83
- i0.ɵɵproperty("title", app_r7.Name);
95
+ i0.ɵɵstyleProp("--app-color", app_r8.GetColor());
96
+ i0.ɵɵclassProp("active", ctx_r3.IsActiveApp(app_r8));
97
+ i0.ɵɵproperty("title", app_r8.Name);
84
98
  i0.ɵɵadvance();
85
- i0.ɵɵclassMap(app_r7.Icon);
99
+ i0.ɵɵclassMap(app_r8.Icon);
86
100
  } }
87
- function ShellComponent_Conditional_15_Template(rf, ctx) { if (rf & 1) {
101
+ function ShellComponent_Conditional_14_Template(rf, ctx) { if (rf & 1) {
88
102
  i0.ɵɵelementStart(0, "div", 17);
89
- i0.ɵɵrepeaterCreate(1, ShellComponent_Conditional_15_For_2_Template, 2, 7, "button", 44, i0.ɵɵrepeaterTrackByIdentity);
103
+ i0.ɵɵrepeaterCreate(1, ShellComponent_Conditional_14_For_2_Template, 2, 7, "button", 45, i0.ɵɵrepeaterTrackByIdentity);
90
104
  i0.ɵɵelementEnd();
91
105
  } if (rf & 2) {
92
106
  const ctx_r3 = i0.ɵɵnextContext();
93
107
  i0.ɵɵadvance();
94
108
  i0.ɵɵrepeater(ctx_r3.leftOfUserMenuApps);
95
109
  } }
96
- function ShellComponent_Conditional_18_Template(rf, ctx) { if (rf & 1) {
110
+ function ShellComponent_Conditional_17_Template(rf, ctx) { if (rf & 1) {
97
111
  i0.ɵɵelement(0, "img", 20);
98
112
  } if (rf & 2) {
99
113
  const ctx_r3 = i0.ɵɵnextContext();
100
114
  i0.ɵɵproperty("src", ctx_r3.userImageURL, i0.ɵɵsanitizeUrl);
101
115
  } }
102
- function ShellComponent_Conditional_19_Template(rf, ctx) { if (rf & 1) {
116
+ function ShellComponent_Conditional_18_Template(rf, ctx) { if (rf & 1) {
103
117
  i0.ɵɵelementStart(0, "div", 21);
104
118
  i0.ɵɵelement(1, "i");
105
119
  i0.ɵɵelementEnd();
@@ -108,8 +122,8 @@ function ShellComponent_Conditional_19_Template(rf, ctx) { if (rf & 1) {
108
122
  i0.ɵɵadvance();
109
123
  i0.ɵɵclassMap(ctx_r3.userIconClass || "fa-solid fa-user");
110
124
  } }
111
- function ShellComponent_Conditional_20_Conditional_1_Conditional_4_Template(rf, ctx) { if (rf & 1) {
112
- i0.ɵɵelementStart(0, "span", 51);
125
+ function ShellComponent_Conditional_19_Conditional_1_Conditional_4_Template(rf, ctx) { if (rf & 1) {
126
+ i0.ɵɵelementStart(0, "span", 53);
113
127
  i0.ɵɵtext(1);
114
128
  i0.ɵɵelementEnd();
115
129
  } if (rf & 2) {
@@ -118,107 +132,121 @@ function ShellComponent_Conditional_20_Conditional_1_Conditional_4_Template(rf,
118
132
  i0.ɵɵadvance();
119
133
  i0.ɵɵtextInterpolate1(" ", (tmp_5_0 = ctx_r3.getUserDisplayInfo()) == null ? null : tmp_5_0.email, " ");
120
134
  } }
121
- function ShellComponent_Conditional_20_Conditional_1_Template(rf, ctx) { if (rf & 1) {
122
- i0.ɵɵelementStart(0, "div", 48)(1, "div", 49)(2, "span", 50);
135
+ function ShellComponent_Conditional_19_Conditional_1_Conditional_5_Template(rf, ctx) { if (rf & 1) {
136
+ i0.ɵɵelementStart(0, "span", 54);
137
+ i0.ɵɵtext(1);
138
+ i0.ɵɵelementEnd();
139
+ } if (rf & 2) {
140
+ let tmp_5_0;
141
+ const ctx_r3 = i0.ɵɵnextContext(3);
142
+ i0.ɵɵadvance();
143
+ i0.ɵɵtextInterpolate((tmp_5_0 = ctx_r3.getUserDisplayInfo()) == null ? null : tmp_5_0.subtitle);
144
+ } }
145
+ function ShellComponent_Conditional_19_Conditional_1_Template(rf, ctx) { if (rf & 1) {
146
+ i0.ɵɵelementStart(0, "div", 50)(1, "div", 51)(2, "span", 52);
123
147
  i0.ɵɵtext(3);
124
148
  i0.ɵɵelementEnd();
125
- i0.ɵɵconditionalCreate(4, ShellComponent_Conditional_20_Conditional_1_Conditional_4_Template, 2, 1, "span", 51);
149
+ i0.ɵɵconditionalCreate(4, ShellComponent_Conditional_19_Conditional_1_Conditional_4_Template, 2, 1, "span", 53);
150
+ i0.ɵɵconditionalCreate(5, ShellComponent_Conditional_19_Conditional_1_Conditional_5_Template, 2, 1, "span", 54);
126
151
  i0.ɵɵelementEnd()();
127
- i0.ɵɵelement(5, "div", 52);
152
+ i0.ɵɵelement(6, "div", 55);
128
153
  } if (rf & 2) {
129
154
  let tmp_4_0;
130
155
  let tmp_5_0;
156
+ let tmp_6_0;
131
157
  const ctx_r3 = i0.ɵɵnextContext(2);
132
158
  i0.ɵɵadvance(3);
133
159
  i0.ɵɵtextInterpolate(((tmp_4_0 = ctx_r3.getUserDisplayInfo()) == null ? null : tmp_4_0.name) || ctx_r3.userName);
134
160
  i0.ɵɵadvance();
135
161
  i0.ɵɵconditional(((tmp_5_0 = ctx_r3.getUserMenuOptions()) == null ? null : tmp_5_0.showUserEmail) && ((tmp_5_0 = ctx_r3.getUserDisplayInfo()) == null ? null : tmp_5_0.email) ? 4 : -1);
162
+ i0.ɵɵadvance();
163
+ i0.ɵɵconditional(((tmp_6_0 = ctx_r3.getUserDisplayInfo()) == null ? null : tmp_6_0.subtitle) ? 5 : -1);
136
164
  } }
137
- function ShellComponent_Conditional_20_For_3_Conditional_0_Template(rf, ctx) { if (rf & 1) {
138
- i0.ɵɵelement(0, "div", 52);
165
+ function ShellComponent_Conditional_19_For_3_Conditional_0_Template(rf, ctx) { if (rf & 1) {
166
+ i0.ɵɵelement(0, "div", 55);
139
167
  } }
140
- function ShellComponent_Conditional_20_For_3_Conditional_1_Conditional_0_Conditional_0_Template(rf, ctx) { if (rf & 1) {
141
- const _r8 = i0.ɵɵgetCurrentView();
142
- i0.ɵɵelementStart(0, "div", 55);
143
- i0.ɵɵlistener("click", function ShellComponent_Conditional_20_For_3_Conditional_1_Conditional_0_Conditional_0_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r8); const item_r9 = i0.ɵɵnextContext(); const ctx_r3 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r3.onUserMenuItemClick(item_r9.id)); });
168
+ function ShellComponent_Conditional_19_For_3_Conditional_1_Conditional_0_Conditional_0_Template(rf, ctx) { if (rf & 1) {
169
+ const _r9 = i0.ɵɵgetCurrentView();
170
+ i0.ɵɵelementStart(0, "div", 58);
171
+ i0.ɵɵlistener("click", function ShellComponent_Conditional_19_For_3_Conditional_1_Conditional_0_Conditional_0_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r9); const item_r10 = i0.ɵɵnextContext(); const ctx_r3 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r3.onUserMenuItemClick(item_r10.id)); });
144
172
  i0.ɵɵelement(1, "i");
145
- i0.ɵɵelementStart(2, "span", 56);
173
+ i0.ɵɵelementStart(2, "span", 59);
146
174
  i0.ɵɵtext(3);
147
175
  i0.ɵɵelementEnd();
148
- i0.ɵɵelementStart(4, "div", 57)(5, "div", 58);
149
- i0.ɵɵelement(6, "i", 59);
176
+ i0.ɵɵelementStart(4, "div", 60)(5, "div", 61);
177
+ i0.ɵɵelement(6, "i", 62);
150
178
  i0.ɵɵelementEnd()()();
151
179
  } if (rf & 2) {
152
- const item_r9 = i0.ɵɵnextContext();
180
+ const item_r10 = i0.ɵɵnextContext();
153
181
  const ctx_r3 = i0.ɵɵnextContext(4);
154
- i0.ɵɵproperty("title", item_r9.tooltip || "");
182
+ i0.ɵɵproperty("title", item_r10.tooltip || "");
155
183
  i0.ɵɵadvance();
156
- i0.ɵɵclassMap(item_r9.icon);
184
+ i0.ɵɵclassMap(item_r10.icon);
157
185
  i0.ɵɵadvance(2);
158
- i0.ɵɵtextInterpolate(item_r9.label);
186
+ i0.ɵɵtextInterpolate(item_r10.label);
159
187
  i0.ɵɵadvance();
160
188
  i0.ɵɵclassProp("dark", ctx_r3.IsDarkMode);
161
189
  i0.ɵɵadvance(2);
162
190
  i0.ɵɵclassMap(ctx_r3.IsDarkMode ? "fa-solid fa-moon" : "fa-solid fa-sun");
163
191
  } }
164
- function ShellComponent_Conditional_20_For_3_Conditional_1_Conditional_0_Conditional_1_Conditional_4_Template(rf, ctx) { if (rf & 1) {
165
- i0.ɵɵelementStart(0, "span", 61);
192
+ function ShellComponent_Conditional_19_For_3_Conditional_1_Conditional_0_Conditional_1_Conditional_4_Template(rf, ctx) { if (rf & 1) {
193
+ i0.ɵɵelementStart(0, "span", 64);
166
194
  i0.ɵɵtext(1);
167
195
  i0.ɵɵelementEnd();
168
196
  } if (rf & 2) {
169
- const item_r9 = i0.ɵɵnextContext(2);
197
+ const item_r10 = i0.ɵɵnextContext(2);
170
198
  i0.ɵɵadvance();
171
- i0.ɵɵtextInterpolate(item_r9.shortcut);
199
+ i0.ɵɵtextInterpolate(item_r10.shortcut);
172
200
  } }
173
- function ShellComponent_Conditional_20_For_3_Conditional_1_Conditional_0_Conditional_1_Template(rf, ctx) { if (rf & 1) {
174
- const _r10 = i0.ɵɵgetCurrentView();
175
- i0.ɵɵelementStart(0, "div", 60);
176
- i0.ɵɵlistener("click", function ShellComponent_Conditional_20_For_3_Conditional_1_Conditional_0_Conditional_1_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r10); const item_r9 = i0.ɵɵnextContext(); const ctx_r3 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(item_r9.enabled && ctx_r3.onUserMenuItemClick(item_r9.id)); });
201
+ function ShellComponent_Conditional_19_For_3_Conditional_1_Conditional_0_Conditional_1_Template(rf, ctx) { if (rf & 1) {
202
+ const _r11 = i0.ɵɵgetCurrentView();
203
+ i0.ɵɵelementStart(0, "div", 63);
204
+ i0.ɵɵlistener("click", function ShellComponent_Conditional_19_For_3_Conditional_1_Conditional_0_Conditional_1_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r11); const item_r10 = i0.ɵɵnextContext(); const ctx_r3 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(item_r10.enabled && ctx_r3.onUserMenuItemClick(item_r10.id)); });
177
205
  i0.ɵɵelement(1, "i");
178
- i0.ɵɵelementStart(2, "span", 56);
206
+ i0.ɵɵelementStart(2, "span", 59);
179
207
  i0.ɵɵtext(3);
180
208
  i0.ɵɵelementEnd();
181
- i0.ɵɵconditionalCreate(4, ShellComponent_Conditional_20_For_3_Conditional_1_Conditional_0_Conditional_1_Conditional_4_Template, 2, 1, "span", 61);
209
+ i0.ɵɵconditionalCreate(4, ShellComponent_Conditional_19_For_3_Conditional_1_Conditional_0_Conditional_1_Conditional_4_Template, 2, 1, "span", 64);
182
210
  i0.ɵɵelementEnd();
183
211
  } if (rf & 2) {
184
- const item_r9 = i0.ɵɵnextContext();
185
- i0.ɵɵstyleProp("color", item_r9.color || null);
186
- i0.ɵɵclassProp("disabled", !item_r9.enabled)("danger", item_r9.cssClass === "danger");
187
- i0.ɵɵproperty("title", item_r9.tooltip || "");
212
+ const item_r10 = i0.ɵɵnextContext();
213
+ i0.ɵɵstyleProp("color", item_r10.color || null);
214
+ i0.ɵɵclassProp("disabled", !item_r10.enabled)("danger", item_r10.cssClass === "danger");
215
+ i0.ɵɵproperty("title", item_r10.tooltip || "");
188
216
  i0.ɵɵadvance();
189
- i0.ɵɵclassMap(item_r9.icon);
217
+ i0.ɵɵclassMap(item_r10.icon);
190
218
  i0.ɵɵadvance(2);
191
- i0.ɵɵtextInterpolate(item_r9.label);
219
+ i0.ɵɵtextInterpolate(item_r10.label);
192
220
  i0.ɵɵadvance();
193
- i0.ɵɵconditional(item_r9.shortcut ? 4 : -1);
221
+ i0.ɵɵconditional(item_r10.shortcut ? 4 : -1);
194
222
  } }
195
- function ShellComponent_Conditional_20_For_3_Conditional_1_Conditional_0_Template(rf, ctx) { if (rf & 1) {
196
- i0.ɵɵconditionalCreate(0, ShellComponent_Conditional_20_For_3_Conditional_1_Conditional_0_Conditional_0_Template, 7, 8, "div", 53)(1, ShellComponent_Conditional_20_For_3_Conditional_1_Conditional_0_Conditional_1_Template, 5, 11, "div", 54);
223
+ function ShellComponent_Conditional_19_For_3_Conditional_1_Conditional_0_Template(rf, ctx) { if (rf & 1) {
224
+ i0.ɵɵconditionalCreate(0, ShellComponent_Conditional_19_For_3_Conditional_1_Conditional_0_Conditional_0_Template, 7, 8, "div", 56)(1, ShellComponent_Conditional_19_For_3_Conditional_1_Conditional_0_Conditional_1_Template, 5, 11, "div", 57);
197
225
  } if (rf & 2) {
198
226
  i0.ɵɵconditional(ctx.id === "toggle-theme" ? 0 : 1);
199
227
  } }
200
- function ShellComponent_Conditional_20_For_3_Conditional_1_Template(rf, ctx) { if (rf & 1) {
201
- i0.ɵɵconditionalCreate(0, ShellComponent_Conditional_20_For_3_Conditional_1_Conditional_0_Template, 2, 1);
228
+ function ShellComponent_Conditional_19_For_3_Conditional_1_Template(rf, ctx) { if (rf & 1) {
229
+ i0.ɵɵconditionalCreate(0, ShellComponent_Conditional_19_For_3_Conditional_1_Conditional_0_Template, 2, 1);
202
230
  } if (rf & 2) {
203
231
  let tmp_14_0;
204
- const element_r11 = i0.ɵɵnextContext().$implicit;
232
+ const element_r12 = i0.ɵɵnextContext().$implicit;
205
233
  const ctx_r3 = i0.ɵɵnextContext(2);
206
- i0.ɵɵconditional((tmp_14_0 = ctx_r3.asMenuItem(element_r11)) ? 0 : -1, tmp_14_0);
234
+ i0.ɵɵconditional((tmp_14_0 = ctx_r3.asMenuItem(element_r12)) ? 0 : -1, tmp_14_0);
207
235
  } }
208
- function ShellComponent_Conditional_20_For_3_Template(rf, ctx) { if (rf & 1) {
209
- i0.ɵɵconditionalCreate(0, ShellComponent_Conditional_20_For_3_Conditional_0_Template, 1, 0, "div", 52);
210
- i0.ɵɵconditionalCreate(1, ShellComponent_Conditional_20_For_3_Conditional_1_Template, 1, 1);
236
+ function ShellComponent_Conditional_19_For_3_Template(rf, ctx) { if (rf & 1) {
237
+ i0.ɵɵconditionalCreate(0, ShellComponent_Conditional_19_For_3_Conditional_0_Template, 1, 0, "div", 55);
238
+ i0.ɵɵconditionalCreate(1, ShellComponent_Conditional_19_For_3_Conditional_1_Template, 1, 1);
211
239
  } if (rf & 2) {
212
- const element_r11 = ctx.$implicit;
240
+ const element_r12 = ctx.$implicit;
213
241
  const ctx_r3 = i0.ɵɵnextContext(2);
214
- i0.ɵɵconditional(ctx_r3.isMenuDivider(element_r11) ? 0 : -1);
242
+ i0.ɵɵconditional(ctx_r3.isMenuDivider(element_r12) ? 0 : -1);
215
243
  i0.ɵɵadvance();
216
- i0.ɵɵconditional(!ctx_r3.isMenuDivider(element_r11) ? 1 : -1);
244
+ i0.ɵɵconditional(!ctx_r3.isMenuDivider(element_r12) ? 1 : -1);
217
245
  } }
218
- function ShellComponent_Conditional_20_Template(rf, ctx) { if (rf & 1) {
219
- i0.ɵɵelementStart(0, "div", 47);
220
- i0.ɵɵconditionalCreate(1, ShellComponent_Conditional_20_Conditional_1_Template, 6, 2);
221
- i0.ɵɵrepeaterCreate(2, ShellComponent_Conditional_20_For_3_Template, 2, 2, null, null, i0.ɵɵrepeaterTrackByIdentity);
246
+ function ShellComponent_Conditional_19_Template(rf, ctx) { if (rf & 1) {
247
+ i0.ɵɵelementStart(0, "div", 49);
248
+ i0.ɵɵconditionalCreate(1, ShellComponent_Conditional_19_Conditional_1_Template, 7, 3);
249
+ i0.ɵɵrepeaterCreate(2, ShellComponent_Conditional_19_For_3_Template, 2, 2, null, null, i0.ɵɵrepeaterTrackByIdentity);
222
250
  i0.ɵɵelementEnd();
223
251
  } if (rf & 2) {
224
252
  let tmp_3_0;
@@ -231,25 +259,25 @@ function ShellComponent_Conditional_20_Template(rf, ctx) { if (rf & 1) {
231
259
  i0.ɵɵadvance();
232
260
  i0.ɵɵrepeater(ctx_r3.userMenuElements);
233
261
  } }
234
- function ShellComponent_Conditional_21_Template(rf, ctx) { if (rf & 1) {
235
- const _r12 = i0.ɵɵgetCurrentView();
236
- i0.ɵɵelementStart(0, "div", 62);
237
- i0.ɵɵlistener("click", function ShellComponent_Conditional_21_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r12); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.closeSearch()); });
238
- i0.ɵɵelementEnd();
239
- } }
240
- function ShellComponent_Conditional_29_Template(rf, ctx) { if (rf & 1) {
262
+ function ShellComponent_Conditional_20_Template(rf, ctx) { if (rf & 1) {
241
263
  const _r13 = i0.ɵɵgetCurrentView();
242
- i0.ɵɵelementStart(0, "div", 63);
243
- i0.ɵɵlistener("click", function ShellComponent_Conditional_29_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r13); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.closeMobileNav()); });
264
+ i0.ɵɵelementStart(0, "div", 65);
265
+ i0.ɵɵlistener("click", function ShellComponent_Conditional_20_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r13); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.closeSearch()); });
244
266
  i0.ɵɵelementEnd();
245
267
  } }
246
- function ShellComponent_Conditional_36_Template(rf, ctx) { if (rf & 1) {
268
+ function ShellComponent_Conditional_28_Template(rf, ctx) { if (rf & 1) {
247
269
  const _r14 = i0.ɵɵgetCurrentView();
248
- i0.ɵɵelementStart(0, "div", 34)(1, "div", 64);
270
+ i0.ɵɵelementStart(0, "div", 66);
271
+ i0.ɵɵlistener("click", function ShellComponent_Conditional_28_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r14); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.closeMobileNav()); });
272
+ i0.ɵɵelementEnd();
273
+ } }
274
+ function ShellComponent_Conditional_35_Template(rf, ctx) { if (rf & 1) {
275
+ const _r15 = i0.ɵɵgetCurrentView();
276
+ i0.ɵɵelementStart(0, "div", 35)(1, "div", 67);
249
277
  i0.ɵɵtext(2);
250
278
  i0.ɵɵelementEnd();
251
- i0.ɵɵelementStart(3, "mj-app-nav", 65);
252
- i0.ɵɵlistener("navItemClick", function ShellComponent_Conditional_36_Template_mj_app_nav_navItemClick_3_listener($event) { i0.ɵɵrestoreView(_r14); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onNavItemClick($event)); })("navItemDismiss", function ShellComponent_Conditional_36_Template_mj_app_nav_navItemDismiss_3_listener($event) { i0.ɵɵrestoreView(_r14); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onNavItemDismiss($event)); });
279
+ i0.ɵɵelementStart(3, "mj-app-nav", 68);
280
+ i0.ɵɵlistener("navItemClick", function ShellComponent_Conditional_35_Template_mj_app_nav_navItemClick_3_listener($event) { i0.ɵɵrestoreView(_r15); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onNavItemClick($event)); })("navItemDismiss", function ShellComponent_Conditional_35_Template_mj_app_nav_navItemDismiss_3_listener($event) { i0.ɵɵrestoreView(_r15); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onNavItemDismiss($event)); });
253
281
  i0.ɵɵelementEnd()();
254
282
  } if (rf & 2) {
255
283
  const ctx_r3 = i0.ɵɵnextContext();
@@ -258,8 +286,8 @@ function ShellComponent_Conditional_36_Template(rf, ctx) { if (rf & 1) {
258
286
  i0.ɵɵadvance();
259
287
  i0.ɵɵproperty("app", ctx_r3.activeApp);
260
288
  } }
261
- function ShellComponent_Conditional_46_Template(rf, ctx) { if (rf & 1) {
262
- i0.ɵɵelementStart(0, "span", 38);
289
+ function ShellComponent_Conditional_45_Template(rf, ctx) { if (rf & 1) {
290
+ i0.ɵɵelementStart(0, "span", 39);
263
291
  i0.ɵɵtext(1);
264
292
  i0.ɵɵelementEnd();
265
293
  } if (rf & 2) {
@@ -267,25 +295,25 @@ function ShellComponent_Conditional_46_Template(rf, ctx) { if (rf & 1) {
267
295
  i0.ɵɵadvance();
268
296
  i0.ɵɵtextInterpolate1(" ", ctx_r3.unreadNotificationCount > 99 ? "99+" : ctx_r3.unreadNotificationCount, " ");
269
297
  } }
270
- function ShellComponent_Conditional_48_Conditional_2_Template(rf, ctx) { if (rf & 1) {
271
- const _r15 = i0.ɵɵgetCurrentView();
272
- i0.ɵɵelementStart(0, "div", 67)(1, "p", 68);
273
- i0.ɵɵelement(2, "i", 69);
298
+ function ShellComponent_Conditional_47_Conditional_2_Template(rf, ctx) { if (rf & 1) {
299
+ const _r16 = i0.ɵɵgetCurrentView();
300
+ i0.ɵɵelementStart(0, "div", 70)(1, "p", 71);
301
+ i0.ɵɵelement(2, "i", 72);
274
302
  i0.ɵɵtext(3, " Taking longer than expected ");
275
303
  i0.ɵɵelementEnd();
276
- i0.ɵɵelementStart(4, "p", 70);
304
+ i0.ɵɵelementStart(4, "p", 73);
277
305
  i0.ɵɵtext(5, " This can happen after updates or due to cached data issues. ");
278
306
  i0.ɵɵelementEnd();
279
- i0.ɵɵelementStart(6, "button", 71);
280
- i0.ɵɵlistener("click", function ShellComponent_Conditional_48_Conditional_2_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r15); const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.ResetApplication()); });
281
- i0.ɵɵelement(7, "i", 72);
307
+ i0.ɵɵelementStart(6, "button", 74);
308
+ i0.ɵɵlistener("click", function ShellComponent_Conditional_47_Conditional_2_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r16); const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.ResetApplication()); });
309
+ i0.ɵɵelement(7, "i", 75);
282
310
  i0.ɵɵtext(8, " Reset ");
283
311
  i0.ɵɵelementEnd()();
284
312
  } }
285
- function ShellComponent_Conditional_48_Template(rf, ctx) { if (rf & 1) {
286
- i0.ɵɵelementStart(0, "div", 40);
287
- i0.ɵɵelement(1, "mj-loading", 66);
288
- i0.ɵɵconditionalCreate(2, ShellComponent_Conditional_48_Conditional_2_Template, 9, 0, "div", 67);
313
+ function ShellComponent_Conditional_47_Template(rf, ctx) { if (rf & 1) {
314
+ i0.ɵɵelementStart(0, "div", 41);
315
+ i0.ɵɵelement(1, "mj-loading", 69);
316
+ i0.ɵɵconditionalCreate(2, ShellComponent_Conditional_47_Conditional_2_Template, 9, 0, "div", 70);
289
317
  i0.ɵɵelementEnd();
290
318
  } if (rf & 2) {
291
319
  const ctx_r3 = i0.ɵɵnextContext();
@@ -294,10 +322,10 @@ function ShellComponent_Conditional_48_Template(rf, ctx) { if (rf & 1) {
294
322
  i0.ɵɵadvance();
295
323
  i0.ɵɵconditional(ctx_r3.ShowResetOption ? 2 : -1);
296
324
  } }
297
- function ShellComponent_Conditional_52_Template(rf, ctx) { if (rf & 1) {
298
- i0.ɵɵelementStart(0, "div", 43)(1, "div", 73);
299
- i0.ɵɵelement(2, "mj-loading", 74);
300
- i0.ɵɵelementStart(3, "span", 75);
325
+ function ShellComponent_Conditional_51_Template(rf, ctx) { if (rf & 1) {
326
+ i0.ɵɵelementStart(0, "div", 44)(1, "div", 76);
327
+ i0.ɵɵelement(2, "mj-loading", 77);
328
+ i0.ɵɵelementStart(3, "span", 78);
301
329
  i0.ɵɵtext(4);
302
330
  i0.ɵɵelementEnd()()();
303
331
  } if (rf & 2) {
@@ -333,10 +361,10 @@ export class ShellComponent {
333
361
  commandPaletteService;
334
362
  themeService;
335
363
  homePinService;
364
+ fileOpenService;
336
365
  subscriptions = [];
337
366
  urlBasedNavigation = false; // Track if we're loading from a URL
338
367
  initialNavigationComplete = false; // Track if initial navigation has completed
339
- firstUrlSync = true; // Track if this is the first URL sync (for replaceUrl behavior)
340
368
  activeApp = null;
341
369
  loading = true;
342
370
  initialized = false;
@@ -389,6 +417,15 @@ export class ShellComponent {
389
417
  searchableEntities = [];
390
418
  selectedEntity = null;
391
419
  searchInput;
420
+ // Universal search bar
421
+ shellSearchComposite;
422
+ // Instance configuration feature flags
423
+ get ShowSearchBar() {
424
+ return InstanceConfigEngine.Instance.GetBoolean('Shell.SearchBar.Enabled', true);
425
+ }
426
+ get ShowSearchPreview() {
427
+ return InstanceConfigEngine.Instance.GetBoolean('Shell.SearchBar.EnablePreview', true);
428
+ }
392
429
  // Tab container reference for thumbnail capture
393
430
  tabContainerRef;
394
431
  // App access dialog
@@ -410,7 +447,7 @@ export class ShellComponent {
410
447
  return this.appManager.GetNavBarApps('Left of User Menu')
411
448
  .filter(app => !(app.HideNavBarIconWhenActive && UUIDsEqual(app.ID, this.activeApp?.ID)));
412
449
  }
413
- constructor(appManager, workspaceManager, layoutManager, tabService, navigationService, route, router, authBase, cdr, userAvatarService, settingsDialogService, viewContainerRef, titleService, developerModeService, commandPaletteService, themeService, homePinService) {
450
+ constructor(appManager, workspaceManager, layoutManager, tabService, navigationService, route, router, authBase, cdr, userAvatarService, settingsDialogService, viewContainerRef, titleService, developerModeService, commandPaletteService, themeService, homePinService, fileOpenService) {
414
451
  this.appManager = appManager;
415
452
  this.workspaceManager = workspaceManager;
416
453
  this.layoutManager = layoutManager;
@@ -428,6 +465,7 @@ export class ShellComponent {
428
465
  this.commandPaletteService = commandPaletteService;
429
466
  this.themeService = themeService;
430
467
  this.homePinService = homePinService;
468
+ this.fileOpenService = fileOpenService;
431
469
  // Initialize theme immediately so loading UI shows correct colors from the start
432
470
  this.activeTheme = getActiveTheme();
433
471
  // Initialize animation based on theme configuration
@@ -472,7 +510,6 @@ export class ShellComponent {
472
510
  });
473
511
  }
474
512
  catch (error) {
475
- console.error('Failed to initialize shell:', error);
476
513
  this.loading = false;
477
514
  }
478
515
  }
@@ -482,6 +519,10 @@ export class ShellComponent {
482
519
  // Initialize application manager (subscribes to LoggedIn event)
483
520
  this.appManager.Initialize();
484
521
  await StartupManager.Instance.Startup();
522
+ // Initialize instance configuration for feature flags
523
+ await InstanceConfigEngine.Instance.Config(false).catch(() => {
524
+ LogStatus('InstanceConfigEngine initialization skipped (not critical)');
525
+ });
485
526
  // Get current user
486
527
  const md = new Metadata();
487
528
  const user = md.CurrentUser;
@@ -628,12 +669,21 @@ export class ShellComponent {
628
669
  await this.loadSearchableEntities();
629
670
  this.initialized = true;
630
671
  this.waitingForFirstResource = true;
631
- // Trigger initial URL sync: the Configuration BehaviorSubject already emitted
632
- // its value when the shell subscribed (line above), but this.initialized was false
633
- // at that point so syncUrlWithWorkspace() was skipped. Now that we're initialized,
634
- // manually trigger the first URL sync to set the browser URL from workspace state.
672
+ // Decide whether to restore workspace state or honor the current URL.
673
+ // If the user navigated to a specific path (deep link, bookmark, typed URL),
674
+ // that URL takes priority the ResourceResolver will handle tab creation.
675
+ // Only restore workspace state when the URL is bare root (/) or empty.
676
+ const initialUrl = this.router.url.split('?')[0]; // ignore query params for this check
677
+ const isDeepLink = initialUrl.length > 1 && initialUrl !== '/';
635
678
  const initConfig = this.workspaceManager.GetConfiguration();
636
- if (initConfig && initConfig.activeTabId) {
679
+ if (isDeepLink) {
680
+ // User navigated to a specific URL — sync workspace to match the URL,
681
+ // not the other way around. The ResourceResolver will have created a tab
682
+ // for this URL; we just need to activate it.
683
+ await this.syncWorkspaceWithUrl(this.router.url);
684
+ }
685
+ else if (initConfig && initConfig.activeTabId) {
686
+ // Bare root URL — restore last workspace state
637
687
  await this.syncActiveAppWithTab(initConfig);
638
688
  this.syncUrlWithWorkspace(initConfig);
639
689
  }
@@ -760,10 +810,7 @@ export class ShellComponent {
760
810
  // Suppress ResourceResolver for this navigation - we're just syncing the URL
761
811
  // to reflect the current active tab, not requesting a new tab to be opened
762
812
  this.tabService.SuppressNextResolve();
763
- // Replace URL on first sync (initialization), push new history entries after that
764
- const replaceUrl = this.firstUrlSync;
765
- this.firstUrlSync = false;
766
- this.router.navigateByUrl(resourceUrl, { replaceUrl });
813
+ this.router.navigateByUrl(resourceUrl);
767
814
  }
768
815
  }
769
816
  }
@@ -782,12 +829,54 @@ export class ShellComponent {
782
829
  // Activate the matching tab
783
830
  this.workspaceManager.SetActiveTab(matchingTab.id);
784
831
  }
832
+ else if (matchingTab && matchingTab.id === config.activeTabId) {
833
+ // Same tab is already active, but query params may have changed (back/forward within nav item)
834
+ const urlParams = this.extractQueryParamsFromUrl(url);
835
+ const tabParams = (matchingTab.configuration?.['queryParams'] || {});
836
+ if (!this.queryParamsEqual(urlParams, tabParams)) {
837
+ // URL is source of truth during back/forward — update tab config to match.
838
+ this.urlBasedNavigation = true;
839
+ try {
840
+ this.workspaceManager.UpdateTabConfiguration(matchingTab.id, {
841
+ queryParams: Object.keys(urlParams).length > 0 ? urlParams : undefined
842
+ });
843
+ this.navigationService.NotifyQueryParamsChanged(matchingTab.id, urlParams);
844
+ }
845
+ finally {
846
+ this.urlBasedNavigation = false;
847
+ }
848
+ }
849
+ }
785
850
  else if (!matchingTab) {
786
- // No matching tab found - check if this is an app-only URL for an app with zero nav items
787
- // If so, we need to create a new tab for it (the old one was replaced when navigating away)
788
851
  await this.handleMissingTabForUrl(url);
789
852
  }
790
853
  }
854
+ /**
855
+ * Extract query params from a URL string, stripping any fragment (#hash).
856
+ */
857
+ extractQueryParamsFromUrl(url) {
858
+ const fragmentIndex = url.indexOf('#');
859
+ const cleanUrl = fragmentIndex !== -1 ? url.substring(0, fragmentIndex) : url;
860
+ const queryIndex = cleanUrl.indexOf('?');
861
+ if (queryIndex === -1)
862
+ return {};
863
+ const params = new URLSearchParams(cleanUrl.substring(queryIndex + 1));
864
+ const result = {};
865
+ params.forEach((value, key) => { result[key] = value; });
866
+ return result;
867
+ }
868
+ /**
869
+ * Compare two query param records for equality, normalizing encoding differences
870
+ * (URLSearchParams encodes spaces as +, Angular Router uses %20).
871
+ */
872
+ queryParamsEqual(a, b) {
873
+ const keysA = Object.keys(a);
874
+ const keysB = Object.keys(b);
875
+ if (keysA.length !== keysB.length)
876
+ return false;
877
+ return keysA.every(key => decodeURIComponent(a[key]?.replace(/\+/g, ' ') || '') ===
878
+ decodeURIComponent(b[key]?.replace(/\+/g, ' ') || ''));
879
+ }
791
880
  /**
792
881
  * Handle the case where no tab matches the URL during back/forward navigation.
793
882
  * Creates new tabs for resources when the original tab was replaced.
@@ -852,6 +941,36 @@ export class ShellComponent {
852
941
  this.navigationService.OpenReport(reportId, 'Report');
853
942
  return;
854
943
  }
944
+ // Check for app-scoped search URL: /app/:appName/search/:searchInput
945
+ const appSearchMatch = urlPath.match(/^\/app\/([^\/]+)\/search\/(.+)$/);
946
+ if (appSearchMatch) {
947
+ const searchInput = decodeURIComponent(appSearchMatch[2]);
948
+ this.navigationService.OpenSearch(searchInput);
949
+ return;
950
+ }
951
+ // Check for app nav item URL: /app/:appName/:navItemName
952
+ const appNavItemMatch = urlPath.match(/^\/app\/([^\/]+)\/([^\/]+)$/);
953
+ if (appNavItemMatch) {
954
+ const appPath = decodeURIComponent(appNavItemMatch[1]);
955
+ const navItemName = decodeURIComponent(appNavItemMatch[2]);
956
+ const app = this.appManager.GetAppByPath(appPath) || this.appManager.GetAppByName(appPath);
957
+ if (app) {
958
+ // Activate the app and open the nav item
959
+ await this.appManager.SetActiveApp(app.ID);
960
+ const navItems = await app.GetNavItems();
961
+ const navItem = navItems.find(item => item.Label === navItemName);
962
+ if (navItem) {
963
+ // Parse query params to pass as configuration
964
+ const qpObj = {};
965
+ queryParams.forEach((value, key) => { qpObj[key] = value; });
966
+ this.navigationService.OpenNavItem(app.ID, navItem, app.GetColor(), Object.keys(qpObj).length > 0 ? { queryParams: qpObj } : undefined);
967
+ }
968
+ else {
969
+ console.warn('handleMissingTabForUrl: nav item not found:', navItemName, 'in app:', appPath);
970
+ }
971
+ }
972
+ return;
973
+ }
855
974
  // Check for app-only URL: /app/:appName
856
975
  const appOnlyMatch = urlPath.match(/^\/app\/([^\/]+)$/);
857
976
  if (appOnlyMatch) {
@@ -869,6 +988,14 @@ export class ShellComponent {
869
988
  this.workspaceManager.OpenTab(defaultTab, app.GetColor());
870
989
  }
871
990
  }
991
+ else {
992
+ // App has nav items — activate the app and its default nav item
993
+ await this.appManager.SetActiveApp(app.ID);
994
+ const defaultNavItem = navItems.find(item => item.isDefault) || navItems[0];
995
+ if (defaultNavItem) {
996
+ this.navigationService.OpenNavItem(app.ID, defaultNavItem, app.GetColor());
997
+ }
998
+ }
872
999
  }
873
1000
  return;
874
1001
  }
@@ -1123,6 +1250,14 @@ export class ShellComponent {
1123
1250
  const queryParams = config['queryParams'];
1124
1251
  const isAppDefault = config['isAppDefault'];
1125
1252
  const tabAppId = tab.applicationId;
1253
+ // Helper to append query params to a URL, preserving any existing params
1254
+ const appendQP = (url) => {
1255
+ if (!queryParams || Object.keys(queryParams).length === 0)
1256
+ return url;
1257
+ const separator = url.includes('?') ? '&' : '?';
1258
+ const params = new URLSearchParams(queryParams);
1259
+ return `${url}${separator}${params.toString()}`;
1260
+ };
1126
1261
  // Helper function to get app path for URL
1127
1262
  const getAppPath = (appIdOrName) => {
1128
1263
  // First try by ID
@@ -1224,7 +1359,7 @@ export class ShellComponent {
1224
1359
  case 'records':
1225
1360
  // /app/:appName/record/:entityName/:recordId
1226
1361
  if (entityName && recordId) {
1227
- return `/app/${encodeURIComponent(appPath)}/record/${encodeURIComponent(entityName)}/${recordId}`;
1362
+ return appendQP(`/app/${encodeURIComponent(appPath)}/record/${encodeURIComponent(entityName)}/${recordId}`);
1228
1363
  }
1229
1364
  break;
1230
1365
  case 'user views':
@@ -1236,56 +1371,67 @@ export class ShellComponent {
1236
1371
  if (extraFilter) {
1237
1372
  url += `?ExtraFilter=${encodeURIComponent(extraFilter)}`;
1238
1373
  }
1239
- return url;
1374
+ return appendQP(url);
1240
1375
  }
1241
1376
  }
1242
1377
  else if (recordId) {
1243
1378
  // /app/:appName/view/:viewId (saved view)
1244
- return `/app/${encodeURIComponent(appPath)}/view/${recordId}`;
1379
+ return appendQP(`/app/${encodeURIComponent(appPath)}/view/${recordId}`);
1245
1380
  }
1246
1381
  break;
1247
1382
  case 'dashboards':
1248
1383
  // /app/:appName/dashboard/:dashboardId
1249
1384
  if (recordId) {
1250
- return `/app/${encodeURIComponent(appPath)}/dashboard/${recordId}`;
1385
+ return appendQP(`/app/${encodeURIComponent(appPath)}/dashboard/${recordId}`);
1251
1386
  }
1252
1387
  break;
1253
1388
  case 'artifacts':
1254
1389
  // /app/:appName/artifact/:artifactId
1255
1390
  if (recordId) {
1256
- return `/app/${encodeURIComponent(appPath)}/artifact/${recordId}`;
1391
+ return appendQP(`/app/${encodeURIComponent(appPath)}/artifact/${recordId}`);
1257
1392
  }
1258
1393
  break;
1259
1394
  case 'queries':
1260
1395
  // /app/:appName/query/:queryId
1261
1396
  if (recordId) {
1262
- return `/app/${encodeURIComponent(appPath)}/query/${recordId}`;
1397
+ return appendQP(`/app/${encodeURIComponent(appPath)}/query/${recordId}`);
1263
1398
  }
1264
1399
  break;
1265
1400
  case 'reports':
1266
1401
  // /app/:appName/report/:reportId
1267
1402
  if (recordId) {
1268
- return `/app/${encodeURIComponent(appPath)}/report/${recordId}`;
1403
+ return appendQP(`/app/${encodeURIComponent(appPath)}/report/${recordId}`);
1269
1404
  }
1270
1405
  break;
1271
- case 'search results':
1272
- // /app/:appName/search/:searchInput?Entity=...
1406
+ case 'search results': {
1407
+ // /app/:appName/search/:searchInput?minRelevance=...&Entity=...
1273
1408
  const searchInput = config['SearchInput'];
1274
1409
  if (searchInput) {
1275
1410
  let url = `/app/${encodeURIComponent(appPath)}/search/${encodeURIComponent(searchInput)}`;
1411
+ const searchParams = new URLSearchParams();
1276
1412
  if (entityName) {
1277
- url += `?Entity=${encodeURIComponent(entityName)}`;
1413
+ searchParams.set('Entity', entityName);
1414
+ }
1415
+ if (queryParams) {
1416
+ for (const [key, value] of Object.entries(queryParams)) {
1417
+ if (value != null)
1418
+ searchParams.set(key, value);
1419
+ }
1420
+ }
1421
+ if (searchParams.toString()) {
1422
+ url += `?${searchParams.toString()}`;
1278
1423
  }
1279
1424
  return url;
1280
1425
  }
1281
1426
  break;
1427
+ }
1282
1428
  }
1283
1429
  }
1284
1430
  // Fallback to legacy routes (for backward compatibility during transition)
1285
1431
  switch (resourceType) {
1286
1432
  case 'records':
1287
1433
  if (entityName && recordId) {
1288
- return `/resource/record/${encodeURIComponent(entityName)}/${recordId}`;
1434
+ return appendQP(`/resource/record/${encodeURIComponent(entityName)}/${recordId}`);
1289
1435
  }
1290
1436
  break;
1291
1437
  case 'user views':
@@ -1295,26 +1441,26 @@ export class ShellComponent {
1295
1441
  if (extraFilter) {
1296
1442
  url += `?ExtraFilter=${encodeURIComponent(extraFilter)}`;
1297
1443
  }
1298
- return url;
1444
+ return appendQP(url);
1299
1445
  }
1300
1446
  }
1301
1447
  else if (recordId) {
1302
- return `/resource/view/${recordId}`;
1448
+ return appendQP(`/resource/view/${recordId}`);
1303
1449
  }
1304
1450
  break;
1305
1451
  case 'dashboards':
1306
1452
  if (recordId) {
1307
- return `/resource/dashboard/${recordId}`;
1453
+ return appendQP(`/resource/dashboard/${recordId}`);
1308
1454
  }
1309
1455
  break;
1310
1456
  case 'artifacts':
1311
1457
  if (recordId) {
1312
- return `/resource/artifact/${recordId}`;
1458
+ return appendQP(`/resource/artifact/${recordId}`);
1313
1459
  }
1314
1460
  break;
1315
1461
  case 'queries':
1316
1462
  if (recordId) {
1317
- return `/resource/query/${recordId}`;
1463
+ return appendQP(`/resource/query/${recordId}`);
1318
1464
  }
1319
1465
  break;
1320
1466
  }
@@ -1662,7 +1808,7 @@ export class ShellComponent {
1662
1808
  this.workspaceManager.SetActiveTab(defaultNavItemTab.id);
1663
1809
  const resourceUrl = await this.buildResourceUrl(defaultNavItemTab);
1664
1810
  if (resourceUrl) {
1665
- this.router.navigateByUrl(resourceUrl, { replaceUrl: true });
1811
+ this.router.navigateByUrl(resourceUrl);
1666
1812
  }
1667
1813
  }
1668
1814
  else {
@@ -1678,7 +1824,7 @@ export class ShellComponent {
1678
1824
  // but we can also manually trigger it here to ensure immediate update
1679
1825
  const resourceUrl = await this.buildResourceUrl(firstTab);
1680
1826
  if (resourceUrl) {
1681
- this.router.navigateByUrl(resourceUrl, { replaceUrl: true });
1827
+ this.router.navigateByUrl(resourceUrl);
1682
1828
  }
1683
1829
  }
1684
1830
  }
@@ -2331,6 +2477,45 @@ export class ShellComponent {
2331
2477
  }
2332
2478
  }
2333
2479
  // ========================================
2480
+ // UNIVERSAL SEARCH EVENT HANDLERS
2481
+ // ========================================
2482
+ OnGlobalKeydown(event) {
2483
+ const target = event.target;
2484
+ if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable)
2485
+ return;
2486
+ const isMac = navigator.platform.toUpperCase().indexOf('MAC') >= 0;
2487
+ const isCtrlOrCmd = isMac ? event.metaKey : event.ctrlKey;
2488
+ if (isCtrlOrCmd && event.key === 'k') {
2489
+ event.preventDefault();
2490
+ event.stopPropagation();
2491
+ if (this.shellSearchComposite?.Focus) {
2492
+ this.shellSearchComposite.Focus();
2493
+ }
2494
+ }
2495
+ }
2496
+ OnSearchResultSelected(result) {
2497
+ if (result.ResultType === 'storage-file') {
2498
+ if (!this.fileOpenService.OpenPreviewFromSearchResult(result.RawMetadata)) {
2499
+ this.fileOpenService.OpenFileFromSearchResult(result.RawMetadata);
2500
+ }
2501
+ return;
2502
+ }
2503
+ if (!result.EntityName || !result.RecordID)
2504
+ return;
2505
+ // Entity records — open via NavigationService
2506
+ const pkey = new CompositeKey([{ FieldName: 'ID', Value: result.RecordID }]);
2507
+ this.navigationService.OpenEntityRecord(result.EntityName, pkey);
2508
+ }
2509
+ OnSearchSubmitted(query) {
2510
+ if (query && query.trim().length >= 2) {
2511
+ const minRelevance = this.shellSearchComposite?.MinRelevancePercent;
2512
+ this.navigationService.OpenSearch(query, minRelevance ? { minRelevance } : undefined);
2513
+ }
2514
+ }
2515
+ OnSeeAllSearch(query) {
2516
+ this.OnSearchSubmitted(query);
2517
+ }
2518
+ // ========================================
2334
2519
  // NOTIFICATION FUNCTIONALITY
2335
2520
  // ========================================
2336
2521
  /**
@@ -2420,6 +2605,12 @@ export class ShellComponent {
2420
2605
  appName: accessResult.appName,
2421
2606
  appId: accessResult.appId
2422
2607
  };
2608
+ case 'not_authorized':
2609
+ return {
2610
+ type: 'no_access',
2611
+ appName: accessResult.appName,
2612
+ appId: accessResult.appId
2613
+ };
2423
2614
  default:
2424
2615
  // 'accessible' shouldn't reach here, but handle it as a generic error
2425
2616
  return {
@@ -2575,7 +2766,7 @@ export class ShellComponent {
2575
2766
  }
2576
2767
  // Update URL to reflect the new app
2577
2768
  const appPath = app.Path || app.Name;
2578
- this.router.navigateByUrl(`/app/${encodeURIComponent(appPath)}`, { replaceUrl: true });
2769
+ this.router.navigateByUrl(`/app/${encodeURIComponent(appPath)}`);
2579
2770
  }
2580
2771
  /**
2581
2772
  * Redirect to the first available app (fallback)
@@ -2595,93 +2786,91 @@ export class ShellComponent {
2595
2786
  this.cdr.detectChanges();
2596
2787
  }
2597
2788
  }
2598
- static ɵfac = function ShellComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || ShellComponent)(i0.ɵɵdirectiveInject(i1.ApplicationManager), i0.ɵɵdirectiveInject(i1.WorkspaceStateManager), i0.ɵɵdirectiveInject(i1.GoldenLayoutManager), i0.ɵɵdirectiveInject(i1.TabService), i0.ɵɵdirectiveInject(i2.NavigationService), i0.ɵɵdirectiveInject(i3.ActivatedRoute), i0.ɵɵdirectiveInject(i3.Router), i0.ɵɵdirectiveInject(i4.MJAuthBase), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i5.UserAvatarService), i0.ɵɵdirectiveInject(i6.SettingsDialogService), i0.ɵɵdirectiveInject(i0.ViewContainerRef), i0.ɵɵdirectiveInject(i2.TitleService), i0.ɵɵdirectiveInject(i2.DeveloperModeService), i0.ɵɵdirectiveInject(i7.CommandPaletteService), i0.ɵɵdirectiveInject(i2.ThemeService), i0.ɵɵdirectiveInject(i2.HomeAppPinService)); };
2789
+ static ɵfac = function ShellComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || ShellComponent)(i0.ɵɵdirectiveInject(i1.ApplicationManager), i0.ɵɵdirectiveInject(i1.WorkspaceStateManager), i0.ɵɵdirectiveInject(i1.GoldenLayoutManager), i0.ɵɵdirectiveInject(i1.TabService), i0.ɵɵdirectiveInject(i2.NavigationService), i0.ɵɵdirectiveInject(i3.ActivatedRoute), i0.ɵɵdirectiveInject(i3.Router), i0.ɵɵdirectiveInject(i4.MJAuthBase), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i5.UserAvatarService), i0.ɵɵdirectiveInject(i6.SettingsDialogService), i0.ɵɵdirectiveInject(i0.ViewContainerRef), i0.ɵɵdirectiveInject(i2.TitleService), i0.ɵɵdirectiveInject(i2.DeveloperModeService), i0.ɵɵdirectiveInject(i7.CommandPaletteService), i0.ɵɵdirectiveInject(i2.ThemeService), i0.ɵɵdirectiveInject(i2.HomeAppPinService), i0.ɵɵdirectiveInject(i8.FileOpenService)); };
2599
2790
  static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ShellComponent, selectors: [["mj-shell"]], viewQuery: function ShellComponent_Query(rf, ctx) { if (rf & 1) {
2600
- i0.ɵɵviewQuery(_c0, 5)(TabContainerComponent, 5)(_c1, 5);
2791
+ i0.ɵɵviewQuery(_c0, 5)(_c1, 5)(TabContainerComponent, 5)(_c2, 5);
2601
2792
  } if (rf & 2) {
2602
2793
  let _t;
2603
2794
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.searchInput = _t.first);
2795
+ i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.shellSearchComposite = _t.first);
2604
2796
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.tabContainerRef = _t.first);
2605
2797
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.appAccessDialog = _t.first);
2606
2798
  } }, hostBindings: function ShellComponent_HostBindings(rf, ctx) { if (rf & 1) {
2607
- i0.ɵɵlistener("keydown", function ShellComponent_keydown_HostBindingHandler($event) { return ctx.handleGlobalKeyboardShortcuts($event); }, i0.ɵɵresolveDocument);
2608
- } }, standalone: false, decls: 53, vars: 27, consts: [["searchInput", ""], ["appAccessDialog", ""], [1, "shell-container"], [1, "shell-header"], ["title", "MemberJunction", 1, "mj-logo"], ["title", "Menu", 1, "hamburger-btn", 3, "click"], [1, "fa-solid", "fa-bars"], [1, "nav-bar-apps", "left-of-switcher"], [3, "appSelected", "activeApp", "isViewingSystemTab", "loadingAppId"], [1, "desktop-nav", 3, "app"], [1, "spacer"], [1, "header-actions"], ["title", "Search", 1, "icon-btn", "desktop-only", "search-toggle-btn", 3, "click"], [1, "fa-solid", "fa-search"], ["title", "Notifications", 1, "icon-btn", "desktop-only", "notification-btn", 3, "click"], [1, "fa-solid", "fa-bell"], [1, "notification-badge"], [1, "nav-bar-apps", "left-of-user-menu"], [1, "user-menu"], [1, "avatar-btn", 3, "click"], ["alt", "User avatar", 1, "avatar-img", 3, "src"], [1, "icon-fallback"], [1, "user-context-menu", 3, "menu-fade", "menu-slide"], [1, "search-popup-overlay"], [1, "search-popup"], [1, "search-popup-content", 3, "click"], ["TextField", "Name", "ValueField", "ID", 1, "search-entity-dropdown", 3, "ngModelChange", "Data", "ngModel"], ["type", "text", "placeholder", "Search...", 1, "mj-input", "search-input", 3, "keydown.enter"], ["title", "Search", 1, "search-submit-btn", 3, "click"], [1, "mobile-nav-overlay"], [1, "mobile-nav-drawer"], [1, "mobile-nav-header"], [1, "close-btn", 3, "click"], [1, "fa-solid", "fa-xmark"], [1, "mobile-nav-content"], [1, "mobile-nav-footer"], ["title", "Search", 1, "mobile-nav-action", 3, "click"], ["title", "Notifications", 1, "mobile-nav-action", 3, "click"], [1, "notification-badge-mobile"], [3, "firstResourceLoadComplete", "layoutInitError"], [1, "shell-loading"], [3, "result"], [3, "AppSelected"], [1, "pin-progress-backdrop"], [1, "nav-bar-app-btn", 3, "active", "title", "--app-color"], [1, "nav-bar-app-btn", 3, "click", "dblclick", "title"], [1, "desktop-nav", 3, "navItemClick", "navItemDismiss", "app"], [1, "user-context-menu"], [1, "user-menu-header"], [1, "user-info"], [1, "user-name"], [1, "user-email"], [1, "user-menu-divider"], [1, "user-menu-item", "theme-toggle-item", 3, "title"], [1, "user-menu-item", 3, "disabled", "danger", "color", "title"], [1, "user-menu-item", "theme-toggle-item", 3, "click", "title"], [1, "menu-label"], [1, "theme-toggle-track"], [1, "theme-toggle-thumb"], [1, "theme-toggle-icon"], [1, "user-menu-item", 3, "click", "title"], [1, "menu-shortcut"], [1, "search-popup-overlay", 3, "click"], [1, "mobile-nav-overlay", 3, "click"], [1, "mobile-nav-section-title"], [3, "navItemClick", "navItemDismiss", "app"], ["size", "large", 3, "text", "textColor", "logoColor", "logoGradient", "animation"], [1, "loading-reset-panel"], [1, "loading-reset-message"], [1, "fa-regular", "fa-clock"], [1, "loading-reset-hint"], [1, "loading-reset-btn", 3, "click"], [1, "fa-solid", "fa-arrows-rotate"], [1, "pin-progress-modal"], ["size", "small", 3, "showText"], [1, "pin-progress-text"]], template: function ShellComponent_Template(rf, ctx) { if (rf & 1) {
2799
+ i0.ɵɵlistener("keydown", function ShellComponent_keydown_HostBindingHandler($event) { return ctx.OnGlobalKeydown($event); }, i0.ɵɵresolveDocument);
2800
+ } }, standalone: false, decls: 52, vars: 28, consts: [["searchInput", ""], ["appAccessDialog", ""], ["shellSearchComposite", ""], [1, "shell-container"], [1, "shell-header"], ["title", "MemberJunction", 1, "mj-logo"], ["title", "Menu", 1, "hamburger-btn", 3, "click"], [1, "fa-solid", "fa-bars"], [1, "nav-bar-apps", "left-of-switcher"], [3, "appSelected", "activeApp", "isViewingSystemTab", "loadingAppId"], [1, "desktop-nav", 3, "app"], [1, "shell-search-bar", "desktop-only"], [1, "spacer"], [1, "header-actions"], ["title", "Notifications", 1, "icon-btn", "desktop-only", "notification-btn", 3, "click"], [1, "fa-solid", "fa-bell"], [1, "notification-badge"], [1, "nav-bar-apps", "left-of-user-menu"], [1, "user-menu"], [1, "avatar-btn", 3, "click"], ["alt", "User avatar", 1, "avatar-img", 3, "src"], [1, "icon-fallback"], [1, "user-context-menu", 3, "menu-fade", "menu-slide"], [1, "search-popup-overlay"], [1, "search-popup"], [1, "search-popup-content", 3, "click"], ["TextField", "Name", "ValueField", "ID", 1, "search-entity-dropdown", 3, "ngModelChange", "Data", "ngModel"], ["type", "text", "placeholder", "Search...", 1, "mj-input", "search-input", 3, "keydown.enter"], ["title", "Search", 1, "search-submit-btn", 3, "click"], [1, "fa-solid", "fa-search"], [1, "mobile-nav-overlay"], [1, "mobile-nav-drawer"], [1, "mobile-nav-header"], [1, "close-btn", 3, "click"], [1, "fa-solid", "fa-xmark"], [1, "mobile-nav-content"], [1, "mobile-nav-footer"], ["title", "Search", 1, "mobile-nav-action", 3, "click"], ["title", "Notifications", 1, "mobile-nav-action", 3, "click"], [1, "notification-badge-mobile"], [3, "firstResourceLoadComplete", "layoutInitError"], [1, "shell-loading"], [3, "result"], [3, "AppSelected"], [1, "pin-progress-backdrop"], [1, "nav-bar-app-btn", 3, "active", "title", "--app-color"], [1, "nav-bar-app-btn", 3, "click", "dblclick", "title"], [1, "desktop-nav", 3, "navItemClick", "navItemDismiss", "app"], ["Placeholder", "Search everything...", 3, "ResultSelected", "SearchSubmitted", "SeeAllRequested", "ShowShortcutHint", "EnablePreview", "EnableRecent", "MaxPreviewResults"], [1, "user-context-menu"], [1, "user-menu-header"], [1, "user-info"], [1, "user-name"], [1, "user-email"], [1, "user-subtitle"], [1, "user-menu-divider"], [1, "user-menu-item", "theme-toggle-item", 3, "title"], [1, "user-menu-item", 3, "disabled", "danger", "color", "title"], [1, "user-menu-item", "theme-toggle-item", 3, "click", "title"], [1, "menu-label"], [1, "theme-toggle-track"], [1, "theme-toggle-thumb"], [1, "theme-toggle-icon"], [1, "user-menu-item", 3, "click", "title"], [1, "menu-shortcut"], [1, "search-popup-overlay", 3, "click"], [1, "mobile-nav-overlay", 3, "click"], [1, "mobile-nav-section-title"], [3, "navItemClick", "navItemDismiss", "app"], ["size", "large", 3, "text", "textColor", "logoColor", "logoGradient", "animation"], [1, "loading-reset-panel"], [1, "loading-reset-message"], [1, "fa-regular", "fa-clock"], [1, "loading-reset-hint"], [1, "loading-reset-btn", 3, "click"], [1, "fa-solid", "fa-arrows-rotate"], [1, "pin-progress-modal"], ["size", "small", 3, "showText"], [1, "pin-progress-text"]], template: function ShellComponent_Template(rf, ctx) { if (rf & 1) {
2609
2801
  const _r1 = i0.ɵɵgetCurrentView();
2610
- i0.ɵɵelementStart(0, "div", 2)(1, "header", 3);
2611
- i0.ɵɵelement(2, "div", 4);
2612
- i0.ɵɵelementStart(3, "button", 5);
2802
+ i0.ɵɵelementStart(0, "div", 3)(1, "header", 4);
2803
+ i0.ɵɵelement(2, "div", 5);
2804
+ i0.ɵɵelementStart(3, "button", 6);
2613
2805
  i0.ɵɵlistener("click", function ShellComponent_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.toggleMobileNav()); });
2614
- i0.ɵɵelement(4, "i", 6);
2806
+ i0.ɵɵelement(4, "i", 7);
2615
2807
  i0.ɵɵelementEnd();
2616
- i0.ɵɵconditionalCreate(5, ShellComponent_Conditional_5_Template, 3, 0, "div", 7);
2617
- i0.ɵɵelementStart(6, "mj-app-switcher", 8);
2808
+ i0.ɵɵconditionalCreate(5, ShellComponent_Conditional_5_Template, 3, 0, "div", 8);
2809
+ i0.ɵɵelementStart(6, "mj-app-switcher", 9);
2618
2810
  i0.ɵɵlistener("appSelected", function ShellComponent_Template_mj_app_switcher_appSelected_6_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onAppSwitch($event)); });
2619
2811
  i0.ɵɵelementEnd();
2620
- i0.ɵɵconditionalCreate(7, ShellComponent_Conditional_7_Template, 1, 1, "mj-app-nav", 9);
2621
- i0.ɵɵelement(8, "div", 10);
2622
- i0.ɵɵelementStart(9, "div", 11)(10, "button", 12);
2623
- i0.ɵɵlistener("click", function ShellComponent_Template_button_click_10_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.toggleSearch()); });
2624
- i0.ɵɵelement(11, "i", 13);
2812
+ i0.ɵɵconditionalCreate(7, ShellComponent_Conditional_7_Template, 1, 1, "mj-app-nav", 10);
2813
+ i0.ɵɵconditionalCreate(8, ShellComponent_Conditional_8_Template, 3, 4, "div", 11);
2814
+ i0.ɵɵelement(9, "div", 12);
2815
+ i0.ɵɵelementStart(10, "div", 13)(11, "button", 14);
2816
+ i0.ɵɵlistener("click", function ShellComponent_Template_button_click_11_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.showNotifications()); });
2817
+ i0.ɵɵelement(12, "i", 15);
2818
+ i0.ɵɵconditionalCreate(13, ShellComponent_Conditional_13_Template, 2, 1, "span", 16);
2625
2819
  i0.ɵɵelementEnd();
2626
- i0.ɵɵelementStart(12, "button", 14);
2627
- i0.ɵɵlistener("click", function ShellComponent_Template_button_click_12_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.showNotifications()); });
2628
- i0.ɵɵelement(13, "i", 15);
2629
- i0.ɵɵconditionalCreate(14, ShellComponent_Conditional_14_Template, 2, 1, "span", 16);
2820
+ i0.ɵɵconditionalCreate(14, ShellComponent_Conditional_14_Template, 3, 0, "div", 17);
2821
+ i0.ɵɵelementStart(15, "div", 18)(16, "button", 19);
2822
+ i0.ɵɵlistener("click", function ShellComponent_Template_button_click_16_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.toggleUserMenu($event)); });
2823
+ i0.ɵɵconditionalCreate(17, ShellComponent_Conditional_17_Template, 1, 1, "img", 20)(18, ShellComponent_Conditional_18_Template, 2, 2, "div", 21);
2630
2824
  i0.ɵɵelementEnd();
2631
- i0.ɵɵconditionalCreate(15, ShellComponent_Conditional_15_Template, 3, 0, "div", 17);
2632
- i0.ɵɵelementStart(16, "div", 18)(17, "button", 19);
2633
- i0.ɵɵlistener("click", function ShellComponent_Template_button_click_17_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.toggleUserMenu($event)); });
2634
- i0.ɵɵconditionalCreate(18, ShellComponent_Conditional_18_Template, 1, 1, "img", 20)(19, ShellComponent_Conditional_19_Template, 2, 2, "div", 21);
2635
- i0.ɵɵelementEnd();
2636
- i0.ɵɵconditionalCreate(20, ShellComponent_Conditional_20_Template, 4, 5, "div", 22);
2825
+ i0.ɵɵconditionalCreate(19, ShellComponent_Conditional_19_Template, 4, 5, "div", 22);
2637
2826
  i0.ɵɵelementEnd()()();
2638
- i0.ɵɵconditionalCreate(21, ShellComponent_Conditional_21_Template, 1, 0, "div", 23);
2639
- i0.ɵɵelementStart(22, "div", 24)(23, "div", 25);
2640
- i0.ɵɵlistener("click", function ShellComponent_Template_div_click_23_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView($event.stopPropagation()); });
2641
- i0.ɵɵelementStart(24, "mj-dropdown", 26);
2642
- i0.ɵɵtwoWayListener("ngModelChange", function ShellComponent_Template_mj_dropdown_ngModelChange_24_listener($event) { i0.ɵɵrestoreView(_r1); i0.ɵɵtwoWayBindingSet(ctx.selectedEntity, $event) || (ctx.selectedEntity = $event); return i0.ɵɵresetView($event); });
2827
+ i0.ɵɵconditionalCreate(20, ShellComponent_Conditional_20_Template, 1, 0, "div", 23);
2828
+ i0.ɵɵelementStart(21, "div", 24)(22, "div", 25);
2829
+ i0.ɵɵlistener("click", function ShellComponent_Template_div_click_22_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView($event.stopPropagation()); });
2830
+ i0.ɵɵelementStart(23, "mj-dropdown", 26);
2831
+ i0.ɵɵtwoWayListener("ngModelChange", function ShellComponent_Template_mj_dropdown_ngModelChange_23_listener($event) { i0.ɵɵrestoreView(_r1); i0.ɵɵtwoWayBindingSet(ctx.selectedEntity, $event) || (ctx.selectedEntity = $event); return i0.ɵɵresetView($event); });
2643
2832
  i0.ɵɵelementEnd();
2644
- i0.ɵɵelementStart(25, "input", 27, 0);
2645
- i0.ɵɵlistener("keydown.enter", function ShellComponent_Template_input_keydown_enter_25_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onSearch($event)); });
2833
+ i0.ɵɵelementStart(24, "input", 27, 0);
2834
+ i0.ɵɵlistener("keydown.enter", function ShellComponent_Template_input_keydown_enter_24_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onSearch($event)); });
2646
2835
  i0.ɵɵelementEnd();
2647
- i0.ɵɵelementStart(27, "button", 28);
2648
- i0.ɵɵlistener("click", function ShellComponent_Template_button_click_27_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onSearch($event)); });
2649
- i0.ɵɵelement(28, "i", 13);
2836
+ i0.ɵɵelementStart(26, "button", 28);
2837
+ i0.ɵɵlistener("click", function ShellComponent_Template_button_click_26_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onSearch($event)); });
2838
+ i0.ɵɵelement(27, "i", 29);
2650
2839
  i0.ɵɵelementEnd()()();
2651
- i0.ɵɵconditionalCreate(29, ShellComponent_Conditional_29_Template, 1, 0, "div", 29);
2652
- i0.ɵɵelementStart(30, "div", 30)(31, "div", 31)(32, "span");
2653
- i0.ɵɵtext(33, "Navigation");
2840
+ i0.ɵɵconditionalCreate(28, ShellComponent_Conditional_28_Template, 1, 0, "div", 30);
2841
+ i0.ɵɵelementStart(29, "div", 31)(30, "div", 32)(31, "span");
2842
+ i0.ɵɵtext(32, "Navigation");
2654
2843
  i0.ɵɵelementEnd();
2655
- i0.ɵɵelementStart(34, "button", 32);
2656
- i0.ɵɵlistener("click", function ShellComponent_Template_button_click_34_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.closeMobileNav()); });
2657
- i0.ɵɵelement(35, "i", 33);
2844
+ i0.ɵɵelementStart(33, "button", 33);
2845
+ i0.ɵɵlistener("click", function ShellComponent_Template_button_click_33_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.closeMobileNav()); });
2846
+ i0.ɵɵelement(34, "i", 34);
2658
2847
  i0.ɵɵelementEnd()();
2659
- i0.ɵɵconditionalCreate(36, ShellComponent_Conditional_36_Template, 4, 2, "div", 34);
2660
- i0.ɵɵelementStart(37, "div", 35)(38, "button", 36);
2661
- i0.ɵɵlistener("click", function ShellComponent_Template_button_click_38_listener() { i0.ɵɵrestoreView(_r1); ctx.toggleSearch(); return i0.ɵɵresetView(ctx.closeMobileNav()); });
2662
- i0.ɵɵelement(39, "i", 13);
2663
- i0.ɵɵelementStart(40, "span");
2664
- i0.ɵɵtext(41, "Search");
2848
+ i0.ɵɵconditionalCreate(35, ShellComponent_Conditional_35_Template, 4, 2, "div", 35);
2849
+ i0.ɵɵelementStart(36, "div", 36)(37, "button", 37);
2850
+ i0.ɵɵlistener("click", function ShellComponent_Template_button_click_37_listener() { i0.ɵɵrestoreView(_r1); ctx.toggleSearch(); return i0.ɵɵresetView(ctx.closeMobileNav()); });
2851
+ i0.ɵɵelement(38, "i", 29);
2852
+ i0.ɵɵelementStart(39, "span");
2853
+ i0.ɵɵtext(40, "Search");
2665
2854
  i0.ɵɵelementEnd()();
2666
- i0.ɵɵelementStart(42, "button", 37);
2667
- i0.ɵɵlistener("click", function ShellComponent_Template_button_click_42_listener() { i0.ɵɵrestoreView(_r1); ctx.showNotifications(); return i0.ɵɵresetView(ctx.closeMobileNav()); });
2668
- i0.ɵɵelement(43, "i", 15);
2669
- i0.ɵɵelementStart(44, "span");
2670
- i0.ɵɵtext(45, "Notifications");
2855
+ i0.ɵɵelementStart(41, "button", 38);
2856
+ i0.ɵɵlistener("click", function ShellComponent_Template_button_click_41_listener() { i0.ɵɵrestoreView(_r1); ctx.showNotifications(); return i0.ɵɵresetView(ctx.closeMobileNav()); });
2857
+ i0.ɵɵelement(42, "i", 15);
2858
+ i0.ɵɵelementStart(43, "span");
2859
+ i0.ɵɵtext(44, "Notifications");
2671
2860
  i0.ɵɵelementEnd();
2672
- i0.ɵɵconditionalCreate(46, ShellComponent_Conditional_46_Template, 2, 1, "span", 38);
2861
+ i0.ɵɵconditionalCreate(45, ShellComponent_Conditional_45_Template, 2, 1, "span", 39);
2673
2862
  i0.ɵɵelementEnd()()();
2674
- i0.ɵɵelementStart(47, "mj-tab-container", 39);
2675
- i0.ɵɵlistener("firstResourceLoadComplete", function ShellComponent_Template_mj_tab_container_firstResourceLoadComplete_47_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onFirstResourceLoadComplete()); })("layoutInitError", function ShellComponent_Template_mj_tab_container_layoutInitError_47_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.handleLayoutError()); });
2863
+ i0.ɵɵelementStart(46, "mj-tab-container", 40);
2864
+ i0.ɵɵlistener("firstResourceLoadComplete", function ShellComponent_Template_mj_tab_container_firstResourceLoadComplete_46_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onFirstResourceLoadComplete()); })("layoutInitError", function ShellComponent_Template_mj_tab_container_layoutInitError_46_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.handleLayoutError()); });
2676
2865
  i0.ɵɵelementEnd()();
2677
- i0.ɵɵconditionalCreate(48, ShellComponent_Conditional_48_Template, 3, 6, "div", 40);
2678
- i0.ɵɵelementStart(49, "mj-app-access-dialog", 41, 1);
2679
- i0.ɵɵlistener("result", function ShellComponent_Template_mj_app_access_dialog_result_49_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onAppAccessDialogResult($event)); });
2866
+ i0.ɵɵconditionalCreate(47, ShellComponent_Conditional_47_Template, 3, 6, "div", 41);
2867
+ i0.ɵɵelementStart(48, "mj-app-access-dialog", 42, 1);
2868
+ i0.ɵɵlistener("result", function ShellComponent_Template_mj_app_access_dialog_result_48_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onAppAccessDialogResult($event)); });
2680
2869
  i0.ɵɵelementEnd();
2681
- i0.ɵɵelementStart(51, "mj-command-palette", 42);
2682
- i0.ɵɵlistener("AppSelected", function ShellComponent_Template_mj_command_palette_AppSelected_51_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onAppSwitch($event)); });
2870
+ i0.ɵɵelementStart(50, "mj-command-palette", 43);
2871
+ i0.ɵɵlistener("AppSelected", function ShellComponent_Template_mj_command_palette_AppSelected_50_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onAppSwitch($event)); });
2683
2872
  i0.ɵɵelementEnd();
2684
- i0.ɵɵconditionalCreate(52, ShellComponent_Conditional_52_Template, 5, 2, "div", 43);
2873
+ i0.ɵɵconditionalCreate(51, ShellComponent_Conditional_51_Template, 5, 2, "div", 44);
2685
2874
  } if (rf & 2) {
2686
2875
  i0.ɵɵclassProp("hidden", ctx.loading)("tabs-visible", ctx.tabBarVisible);
2687
2876
  i0.ɵɵadvance(5);
@@ -2690,43 +2879,48 @@ export class ShellComponent {
2690
2879
  i0.ɵɵproperty("activeApp", ctx.activeApp)("isViewingSystemTab", ctx.isViewingSystemTab)("loadingAppId", ctx.loadingAppId);
2691
2880
  i0.ɵɵadvance();
2692
2881
  i0.ɵɵconditional(ctx.activeApp ? 7 : -1);
2693
- i0.ɵɵadvance(7);
2694
- i0.ɵɵconditional(ctx.unreadNotificationCount > 0 ? 14 : -1);
2695
2882
  i0.ɵɵadvance();
2696
- i0.ɵɵconditional(ctx.leftOfUserMenuApps.length > 0 ? 15 : -1);
2883
+ i0.ɵɵconditional(ctx.ShowSearchBar ? 8 : -1);
2884
+ i0.ɵɵadvance(5);
2885
+ i0.ɵɵconditional(ctx.unreadNotificationCount > 0 ? 13 : -1);
2886
+ i0.ɵɵadvance();
2887
+ i0.ɵɵconditional(ctx.leftOfUserMenuApps.length > 0 ? 14 : -1);
2697
2888
  i0.ɵɵadvance(3);
2698
- i0.ɵɵconditional(ctx.userImageURL ? 18 : 19);
2889
+ i0.ɵɵconditional(ctx.userImageURL ? 17 : 18);
2699
2890
  i0.ɵɵadvance(2);
2700
- i0.ɵɵconditional(ctx.userMenuVisible ? 20 : -1);
2891
+ i0.ɵɵconditional(ctx.userMenuVisible ? 19 : -1);
2701
2892
  i0.ɵɵadvance();
2702
- i0.ɵɵconditional(ctx.isSearchOpen ? 21 : -1);
2893
+ i0.ɵɵconditional(ctx.isSearchOpen ? 20 : -1);
2703
2894
  i0.ɵɵadvance();
2704
2895
  i0.ɵɵclassProp("open", ctx.isSearchOpen);
2705
2896
  i0.ɵɵadvance(2);
2706
2897
  i0.ɵɵproperty("Data", ctx.searchableEntities);
2707
2898
  i0.ɵɵtwoWayProperty("ngModel", ctx.selectedEntity);
2708
2899
  i0.ɵɵadvance(5);
2709
- i0.ɵɵconditional(ctx.mobileNavOpen ? 29 : -1);
2900
+ i0.ɵɵconditional(ctx.mobileNavOpen ? 28 : -1);
2710
2901
  i0.ɵɵadvance();
2711
2902
  i0.ɵɵclassProp("open", ctx.mobileNavOpen);
2712
2903
  i0.ɵɵadvance(6);
2713
- i0.ɵɵconditional(ctx.activeApp ? 36 : -1);
2904
+ i0.ɵɵconditional(ctx.activeApp ? 35 : -1);
2714
2905
  i0.ɵɵadvance(10);
2715
- i0.ɵɵconditional(ctx.unreadNotificationCount > 0 ? 46 : -1);
2906
+ i0.ɵɵconditional(ctx.unreadNotificationCount > 0 ? 45 : -1);
2716
2907
  i0.ɵɵadvance();
2717
2908
  i0.ɵɵclassProp("hide-tab-bar", !ctx.tabBarVisible);
2718
2909
  i0.ɵɵadvance();
2719
- i0.ɵɵconditional(ctx.loading ? 48 : -1);
2910
+ i0.ɵɵconditional(ctx.loading ? 47 : -1);
2720
2911
  i0.ɵɵadvance(4);
2721
- i0.ɵɵconditional(ctx.PinProgressVisible ? 52 : -1);
2722
- } }, dependencies: [i8.NgControlStatus, i8.NgModel, i9.MJDropdownComponent, i10.LoadingComponent, i11.AppSwitcherComponent, i12.AppNavComponent, i13.TabContainerComponent, i14.AppAccessDialogComponent, i15.CommandPaletteComponent], styles: ["[_nghost-%COMP%] {\n display: block;\n height: 100vh;\n width: 100%;\n overflow: hidden;\n}\n\n\n\n.mj-logo[_ngcontent-%COMP%] {\n width: 32px;\n height: 18px;\n background-image: var(--mj-logo-mark);\n background-repeat: no-repeat;\n background-position: center;\n background-size: contain;\n flex-shrink: 0;\n}\n\n.shell-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100vh;\n width: 100%;\n overflow: hidden;\n}\n\n\n\n\n.shell-container.hidden[_ngcontent-%COMP%] {\n visibility: hidden;\n position: absolute;\n pointer-events: none;\n}\n\nmj-tab-container[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n transition: all 0.2s ease-in-out;\n}\n\n\n\nmj-tab-container.hide-tab-bar[_ngcontent-%COMP%] .lm_header {\n display: none;\n}\n\n\n\nmj-tab-container[_ngcontent-%COMP%]:not(.hide-tab-bar) .lm_header {\n opacity: 1;\n max-height: 40px;\n transition: opacity 0.2s ease-in-out, max-height 0.2s ease-in-out;\n}\n\n\n\nmj-tab-container.hide-tab-bar[_ngcontent-%COMP%] .lm_content {\n height: 100% !important;\n}\n\n\n\nmj-tab-container[_ngcontent-%COMP%] .lm_stack {\n transition: all 0.2s ease-in-out;\n}\n\n.shell-header[_ngcontent-%COMP%] {\n height: 60px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n display: flex;\n align-items: center;\n padding: 0 16px;\n gap: 16px;\n box-shadow: var(--mj-shadow-sm);\n flex-shrink: 0;\n}\n\n\n\n.nav-bar-apps[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.nav-bar-apps.left-of-switcher[_ngcontent-%COMP%] {\n \n\n \n\n}\n\n.nav-bar-apps.left-of-user-menu[_ngcontent-%COMP%] {\n margin-right: 8px;\n}\n\n.nav-bar-app-btn[_ngcontent-%COMP%] {\n --app-color: var(--mj-text-muted);\n width: 40px;\n height: 40px;\n border-radius: 10px;\n border: none;\n background: transparent;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-secondary);\n font-size: 18px;\n transition: all 0.15s ease;\n position: relative;\n}\n\n.nav-bar-app-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--app-color) 15%, transparent);\n color: var(--app-color);\n}\n\n.nav-bar-app-btn.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--app-color) 20%, transparent);\n color: var(--app-color);\n}\n\n.nav-bar-app-btn.active[_ngcontent-%COMP%]::after {\n content: '';\n position: absolute;\n bottom: 6px;\n left: 50%;\n transform: translateX(-50%);\n width: 16px;\n height: 3px;\n background: var(--app-color);\n border-radius: 2px;\n}\n\n.nav-bar-app-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n transition: transform 0.15s ease;\n margin-top: 2px; \n\n}\n\n.nav-bar-app-btn[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n transform: scale(1.1);\n}\n\n.spacer[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.header-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.icon-btn[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n border-radius: 50%;\n border: none;\n background: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 18px;\n transition: background 0.15s;\n}\n\n.icon-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n\n\n.notification-btn[_ngcontent-%COMP%] {\n position: relative;\n}\n\n.notification-badge[_ngcontent-%COMP%] {\n position: absolute;\n top: 4px;\n right: 4px;\n min-width: 16px;\n height: 16px;\n padding: 0 4px;\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n font-size: 10px;\n font-weight: 600;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n}\n\n.user-menu[_ngcontent-%COMP%] {\n position: relative;\n}\n\n.user-menu[_ngcontent-%COMP%] .avatar-btn[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n border-radius: 50%;\n border: none;\n background: transparent;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: box-shadow 0.15s, transform 0.15s;\n padding: 0;\n overflow: hidden;\n}\n\n.user-menu[_ngcontent-%COMP%] .avatar-btn[_ngcontent-%COMP%]:hover {\n transform: scale(1.05);\n}\n\n\n\n.user-menu[_ngcontent-%COMP%] .avatar-btn[_ngcontent-%COMP%] .icon-fallback[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n border-radius: 50%;\n border: 2px solid var(--mj-border-default);\n background: var(--mj-bg-surface-hover);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: border-color 0.15s;\n}\n\n.user-menu[_ngcontent-%COMP%] .avatar-btn[_ngcontent-%COMP%]:hover .icon-fallback[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n}\n\n.user-menu[_ngcontent-%COMP%] .avatar-btn[_ngcontent-%COMP%] .icon-fallback[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 16px;\n}\n\n\n\n.user-menu[_ngcontent-%COMP%] .avatar-btn[_ngcontent-%COMP%] .avatar-img[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n border-radius: 50%;\n object-fit: cover;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);\n}\n\n.user-menu[_ngcontent-%COMP%] .avatar-btn[_ngcontent-%COMP%]:hover .avatar-img[_ngcontent-%COMP%] {\n box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);\n}\n\n\n\n.user-menu-header[_ngcontent-%COMP%] {\n padding: 12px 16px;\n background: var(--mj-bg-surface-sunken);\n}\n\n.user-menu-header[_ngcontent-%COMP%] .user-info[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.user-menu-header[_ngcontent-%COMP%] .user-name[_ngcontent-%COMP%] {\n font-weight: 600;\n font-size: 14px;\n color: var(--mj-text-primary);\n}\n\n.user-menu-header[_ngcontent-%COMP%] .user-email[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n\n\n.user-context-menu[_ngcontent-%COMP%] {\n position: absolute;\n top: 100%;\n right: 0;\n margin-top: 8px;\n background: var(--mj-bg-surface-elevated);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n box-shadow: var(--mj-shadow-lg);\n min-width: 180px;\n z-index: 10000;\n overflow: hidden;\n}\n\n.user-menu-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px;\n cursor: pointer;\n font-size: 14px;\n color: var(--mj-text-primary);\n transition: background 0.15s;\n}\n\n.user-menu-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n width: 18px;\n text-align: center;\n color: var(--mj-text-muted);\n font-size: 14px;\n}\n\n.user-menu-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.user-menu-item.danger[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.user-menu-item.danger[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.user-menu-item.danger[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface-elevated));\n}\n\n.user-menu-divider[_ngcontent-%COMP%] {\n height: 1px;\n background: var(--mj-border-default);\n margin: 4px 0;\n}\n\n\n\n.user-menu-item.disabled[_ngcontent-%COMP%] {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.user-menu-item.disabled[_ngcontent-%COMP%]:hover {\n background: transparent;\n}\n\n\n\n.theme-toggle-item[_ngcontent-%COMP%] {\n cursor: pointer;\n}\n\n.theme-toggle-track[_ngcontent-%COMP%] {\n position: relative;\n width: 40px;\n height: 22px;\n border-radius: 11px;\n background: var(--mj-bg-surface-active);\n margin-left: auto;\n transition: background 0.2s ease;\n flex-shrink: 0;\n}\n\n.theme-toggle-track.dark[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n}\n\n.theme-toggle-thumb[_ngcontent-%COMP%] {\n position: absolute;\n top: 2px;\n left: 2px;\n width: 18px;\n height: 18px;\n border-radius: 50%;\n background: var(--mj-bg-surface);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: transform 0.2s ease;\n}\n\n.theme-toggle-track.dark[_ngcontent-%COMP%] .theme-toggle-thumb[_ngcontent-%COMP%] {\n transform: translateX(18px);\n}\n\n.theme-toggle-icon[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--mj-text-muted);\n}\n\n.theme-toggle-track.dark[_ngcontent-%COMP%] .theme-toggle-icon[_ngcontent-%COMP%] {\n color: var(--mj-text-inverse);\n}\n\n\n\n.user-menu-item[_ngcontent-%COMP%] .menu-shortcut[_ngcontent-%COMP%] {\n margin-left: auto;\n font-size: 11px;\n color: var(--mj-text-disabled);\n font-family: monospace;\n}\n\n\n\n.user-context-menu.menu-fade[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_menuFadeIn 0.15s ease-out;\n}\n\n.user-context-menu.menu-slide[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_menuSlideIn 0.2s ease-out;\n}\n\n@keyframes _ngcontent-%COMP%_menuFadeIn {\n from {\n opacity: 0;\n transform: translateY(-8px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n@keyframes _ngcontent-%COMP%_menuSlideIn {\n from {\n opacity: 0;\n transform: translateY(-16px) scale(0.95);\n }\n to {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n}\n\n.shell-loading[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100vh;\n padding-bottom: 15vh;\n background: var(--mj-bg-page);\n}\n\n\n\n.loading-reset-panel[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--mj-space-3);\n margin-top: var(--mj-space-10);\n padding: var(--mj-space-8);\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-md);\n max-width: 420px;\n animation: _ngcontent-%COMP%_resetPanelFadeIn 0.4s ease-out;\n}\n\n.loading-reset-message[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n margin: 0;\n font-size: var(--mj-text-base);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n}\n\n.loading-reset-message[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: var(--mj-text-lg);\n color: var(--mj-status-warning);\n}\n\n.loading-reset-hint[_ngcontent-%COMP%] {\n margin: 0;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-secondary);\n text-align: center;\n line-height: var(--mj-leading-relaxed);\n}\n\n.loading-reset-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: var(--mj-space-2);\n margin-top: var(--mj-space-3);\n padding: var(--mj-space-3) var(--mj-space-6);\n font-size: var(--mj-text-base);\n font-weight: var(--mj-font-medium);\n font-family: var(--mj-font-family);\n color: var(--mj-text-inverse);\n background: var(--mj-brand-primary);\n border: 1px solid var(--mj-brand-primary);\n border-radius: var(--mj-radius-md);\n cursor: pointer;\n transition: var(--mj-transition-colors);\n}\n\n.loading-reset-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary-hover);\n color: var(--mj-text-inverse);\n border-color: var(--mj-brand-primary-hover);\n box-shadow: var(--mj-shadow-md);\n}\n\n.loading-reset-btn[_ngcontent-%COMP%]:active {\n background: var(--mj-brand-primary-active);\n color: var(--mj-text-inverse);\n transform: scale(0.98);\n}\n\n.loading-reset-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n}\n\n@keyframes _ngcontent-%COMP%_resetPanelFadeIn {\n from {\n opacity: 0;\n transform: translateY(12px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n\n\n.hamburger-btn[_ngcontent-%COMP%] {\n display: none;\n width: 40px;\n height: 40px;\n border-radius: 8px;\n border: none;\n background: none;\n cursor: pointer;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-secondary);\n font-size: 20px;\n transition: background 0.15s;\n}\n.hamburger-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n\n\n.mobile-nav-overlay[_ngcontent-%COMP%] {\n display: none;\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n z-index: 9998;\n}\n\n\n\n.mobile-nav-drawer[_ngcontent-%COMP%] {\n display: none;\n position: fixed;\n top: 0;\n left: 0;\n bottom: 0;\n width: 280px;\n max-width: 85vw;\n background: var(--mj-bg-surface);\n box-shadow: var(--mj-shadow-xl);\n z-index: 9999;\n flex-direction: column;\n transform: translateX(-100%);\n transition: transform 0.3s ease;\n}\n.mobile-nav-drawer.open[_ngcontent-%COMP%] {\n transform: translateX(0);\n}\n\n.mobile-nav-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n}\n.mobile-nav-header[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-weight: 600;\n font-size: 16px;\n color: var(--mj-text-primary);\n}\n.mobile-nav-header[_ngcontent-%COMP%] .close-btn[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n border-radius: 50%;\n border: none;\n background: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 18px;\n transition: background 0.15s;\n}\n.mobile-nav-header[_ngcontent-%COMP%] .close-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-active);\n}\n\n.mobile-nav-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 16px 0;\n}\n\n.mobile-nav-section-title[_ngcontent-%COMP%] {\n padding: 8px 20px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-disabled);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.mobile-nav-footer[_ngcontent-%COMP%] {\n border-top: 1px solid var(--mj-border-default);\n padding: 12px 16px;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.mobile-nav-action[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px;\n border: none;\n background: none;\n cursor: pointer;\n border-radius: 8px;\n color: var(--mj-text-secondary);\n font-size: 14px;\n font-weight: 500;\n transition: background 0.15s;\n width: 100%;\n text-align: left;\n}\n.mobile-nav-action[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n.mobile-nav-action[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n width: 20px;\n text-align: center;\n}\n\n\n\n@media (max-width: 768px) {\n .hamburger-btn[_ngcontent-%COMP%] {\n display: flex;\n }\n\n .desktop-nav[_ngcontent-%COMP%] {\n display: none !important;\n }\n\n .desktop-only[_ngcontent-%COMP%] {\n display: none !important;\n }\n\n .mobile-nav-overlay[_ngcontent-%COMP%] {\n display: block;\n }\n\n .mobile-nav-drawer[_ngcontent-%COMP%] {\n display: flex;\n }\n\n .shell-header[_ngcontent-%COMP%] {\n padding: 0 12px;\n gap: 8px;\n }\n}\n\n\n\n .settings-fullscreen-window {\n \n\n box-shadow: none !important;\n border: none !important;\n}\n\n .settings-fullscreen-window .k-window-titlebar {\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n padding: 12px 16px;\n}\n\n .settings-fullscreen-window .k-window-title {\n font-size: 18px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n .settings-fullscreen-window .k-window-titlebar-actions {\n gap: 4px;\n}\n\n .settings-fullscreen-window .k-window-titlebar-action {\n width: 32px;\n height: 32px;\n border-radius: 6px;\n}\n\n .settings-fullscreen-window .k-window-titlebar-action:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n .settings-fullscreen-window .k-window-content {\n padding: 0;\n overflow: auto;\n background: var(--mj-bg-page);\n}\n\n\n\n .settings-fullscreen-window .k-window-titlebar-action[title=\"Minimize\"], \n .settings-fullscreen-window .k-window-titlebar-action[title=\"Maximize\"], \n .settings-fullscreen-window .k-window-titlebar-action .k-i-window-minimize, \n .settings-fullscreen-window .k-window-titlebar-action .k-i-window-maximize, \n .settings-fullscreen-window .k-window-titlebar-action .k-i-window {\n display: none !important;\n}\n\n\n\n\n\n\n.search-popup-overlay[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.3);\n z-index: 9999;\n animation: _ngcontent-%COMP%_fadeIn 0.15s ease;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n.search-popup[_ngcontent-%COMP%] {\n position: fixed;\n top: 60px; \n\n right: 16px;\n width: 480px;\n max-width: calc(100vw - 32px);\n background: var(--mj-bg-surface-elevated);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-xl);\n z-index: 10000;\n opacity: 0;\n transform: translateY(-10px);\n pointer-events: none;\n transition: opacity 0.2s ease, transform 0.2s ease;\n}\n\n.search-popup.open[_ngcontent-%COMP%] {\n opacity: 1;\n transform: translateY(0);\n pointer-events: all;\n}\n\n.search-popup-content[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px;\n}\n\n.search-entity-dropdown[_ngcontent-%COMP%] {\n min-width: 140px;\n max-width: 180px;\n flex-shrink: 0;\n}\n\n.search-input[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n height: 40px;\n padding: 8px 12px;\n font-size: 14px;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n outline: none;\n display: block !important;\n box-sizing: border-box;\n}\n\n.search-input[_ngcontent-%COMP%]:focus {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.search-submit-btn[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n border-radius: 8px;\n border: none;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 16px;\n transition: background 0.15s;\n flex-shrink: 0;\n}\n\n.search-submit-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary-hover);\n}\n\n.search-submit-btn[_ngcontent-%COMP%]:active {\n background: var(--mj-brand-primary-hover);\n}\n\n\n\n.notification-badge-mobile[_ngcontent-%COMP%] {\n position: absolute;\n top: 8px;\n right: 8px;\n min-width: 18px;\n height: 18px;\n padding: 0 5px;\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n font-size: 11px;\n font-weight: 600;\n border-radius: 9px;\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n}\n\n\n\n@media (max-width: 768px) {\n .search-popup[_ngcontent-%COMP%] {\n top: 60px;\n left: 16px;\n right: 16px;\n width: auto;\n max-width: none;\n }\n\n .search-popup-content[_ngcontent-%COMP%] {\n flex-wrap: wrap;\n }\n\n .search-entity-dropdown[_ngcontent-%COMP%] {\n width: 100%;\n }\n\n .search-input[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n }\n}\n\n\n\n\n\n.pin-progress-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: color-mix(in srgb, var(--mj-text-primary) 40%, transparent);\n z-index: 100000;\n display: flex;\n align-items: center;\n justify-content: center;\n animation: _ngcontent-%COMP%_pinBackdropIn 0.2s ease;\n}\n\n@keyframes _ngcontent-%COMP%_pinBackdropIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n.pin-progress-modal[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border-radius: var(--mj-radius-xl);\n padding: 28px 40px;\n display: flex;\n align-items: center;\n gap: 16px;\n box-shadow: 0 16px 48px color-mix(in srgb, var(--mj-text-primary) 30%, transparent);\n animation: _ngcontent-%COMP%_pinModalIn 0.25s ease;\n}\n\n@keyframes _ngcontent-%COMP%_pinModalIn {\n from { opacity: 0; transform: scale(0.9) translateY(8px); }\n to { opacity: 1; transform: scale(1) translateY(0); }\n}\n\n.pin-progress-text[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-medium);\n color: var(--mj-text-secondary);\n white-space: nowrap;\n}"] });
2912
+ i0.ɵɵconditional(ctx.PinProgressVisible ? 51 : -1);
2913
+ } }, dependencies: [i9.NgControlStatus, i9.NgModel, i10.MJDropdownComponent, i11.LoadingComponent, i12.SearchCompositeComponent, i13.AppSwitcherComponent, i14.AppNavComponent, i15.TabContainerComponent, i16.AppAccessDialogComponent, i17.CommandPaletteComponent], styles: ["[_nghost-%COMP%] {\n display: block;\n height: 100vh;\n width: 100%;\n overflow: hidden;\n}\n\n\n\n.mj-logo[_ngcontent-%COMP%] {\n width: 32px;\n height: 18px;\n background-image: var(--mj-logo-mark);\n background-repeat: no-repeat;\n background-position: center;\n background-size: contain;\n flex-shrink: 0;\n}\n\n.shell-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100vh;\n width: 100%;\n overflow: hidden;\n}\n\n\n\n\n.shell-container.hidden[_ngcontent-%COMP%] {\n visibility: hidden;\n position: absolute;\n pointer-events: none;\n}\n\nmj-tab-container[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n transition: all 0.2s ease-in-out;\n}\n\n\n\nmj-tab-container.hide-tab-bar[_ngcontent-%COMP%] .lm_header {\n display: none;\n}\n\n\n\nmj-tab-container[_ngcontent-%COMP%]:not(.hide-tab-bar) .lm_header {\n opacity: 1;\n max-height: 40px;\n transition: opacity 0.2s ease-in-out, max-height 0.2s ease-in-out;\n}\n\n\n\nmj-tab-container.hide-tab-bar[_ngcontent-%COMP%] .lm_content {\n height: 100% !important;\n}\n\n\n\nmj-tab-container[_ngcontent-%COMP%] .lm_stack {\n transition: all 0.2s ease-in-out;\n}\n\n.shell-header[_ngcontent-%COMP%] {\n height: 60px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n display: flex;\n align-items: center;\n padding: 0 16px;\n gap: 16px;\n box-shadow: var(--mj-shadow-sm);\n flex-shrink: 0;\n \n\n\n position: relative;\n z-index: 500;\n}\n\n\n\n.nav-bar-apps[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.nav-bar-apps.left-of-switcher[_ngcontent-%COMP%] {\n \n\n \n\n}\n\n.nav-bar-apps.left-of-user-menu[_ngcontent-%COMP%] {\n margin-right: 8px;\n}\n\n.nav-bar-app-btn[_ngcontent-%COMP%] {\n --app-color: var(--mj-text-muted);\n width: 40px;\n height: 40px;\n border-radius: 10px;\n border: none;\n background: transparent;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-secondary);\n font-size: 18px;\n transition: all 0.15s ease;\n position: relative;\n}\n\n.nav-bar-app-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--app-color) 15%, transparent);\n color: var(--app-color);\n}\n\n.nav-bar-app-btn.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--app-color) 20%, transparent);\n color: var(--app-color);\n}\n\n.nav-bar-app-btn.active[_ngcontent-%COMP%]::after {\n content: '';\n position: absolute;\n bottom: 6px;\n left: 50%;\n transform: translateX(-50%);\n width: 16px;\n height: 3px;\n background: var(--app-color);\n border-radius: 2px;\n}\n\n.nav-bar-app-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n transition: transform 0.15s ease;\n margin-top: 2px; \n\n}\n\n.nav-bar-app-btn[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n transform: scale(1.1);\n}\n\n.spacer[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.header-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.icon-btn[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n border-radius: 50%;\n border: none;\n background: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 18px;\n transition: background 0.15s;\n}\n\n.icon-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n\n\n.notification-btn[_ngcontent-%COMP%] {\n position: relative;\n}\n\n.notification-badge[_ngcontent-%COMP%] {\n position: absolute;\n top: 4px;\n right: 4px;\n min-width: 16px;\n height: 16px;\n padding: 0 4px;\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n font-size: 10px;\n font-weight: 600;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n}\n\n.user-menu[_ngcontent-%COMP%] {\n position: relative;\n}\n\n.user-menu[_ngcontent-%COMP%] .avatar-btn[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n border-radius: 50%;\n border: none;\n background: transparent;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: box-shadow 0.15s, transform 0.15s;\n padding: 0;\n overflow: hidden;\n}\n\n.user-menu[_ngcontent-%COMP%] .avatar-btn[_ngcontent-%COMP%]:hover {\n transform: scale(1.05);\n}\n\n\n\n.user-menu[_ngcontent-%COMP%] .avatar-btn[_ngcontent-%COMP%] .icon-fallback[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n border-radius: 50%;\n border: 2px solid var(--mj-border-default);\n background: var(--mj-bg-surface-hover);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: border-color 0.15s;\n}\n\n.user-menu[_ngcontent-%COMP%] .avatar-btn[_ngcontent-%COMP%]:hover .icon-fallback[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n}\n\n.user-menu[_ngcontent-%COMP%] .avatar-btn[_ngcontent-%COMP%] .icon-fallback[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 16px;\n}\n\n\n\n.user-menu[_ngcontent-%COMP%] .avatar-btn[_ngcontent-%COMP%] .avatar-img[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n border-radius: 50%;\n object-fit: cover;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);\n}\n\n.user-menu[_ngcontent-%COMP%] .avatar-btn[_ngcontent-%COMP%]:hover .avatar-img[_ngcontent-%COMP%] {\n box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);\n}\n\n\n\n.user-menu-header[_ngcontent-%COMP%] {\n padding: 12px 16px;\n background: var(--mj-bg-surface-sunken);\n}\n\n.user-menu-header[_ngcontent-%COMP%] .user-info[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.user-menu-header[_ngcontent-%COMP%] .user-name[_ngcontent-%COMP%] {\n font-weight: 600;\n font-size: 14px;\n color: var(--mj-text-primary);\n}\n\n.user-menu-header[_ngcontent-%COMP%] .user-email[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.user-menu-header[_ngcontent-%COMP%] .user-subtitle[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n font-style: italic;\n}\n\n\n\n.user-context-menu[_ngcontent-%COMP%] {\n position: absolute;\n top: 100%;\n right: 0;\n margin-top: 8px;\n background: var(--mj-bg-surface-elevated);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n box-shadow: var(--mj-shadow-lg);\n min-width: 180px;\n z-index: 10000;\n overflow: hidden;\n}\n\n.user-menu-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px;\n cursor: pointer;\n font-size: 14px;\n color: var(--mj-text-primary);\n transition: background 0.15s;\n}\n\n.user-menu-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n width: 18px;\n text-align: center;\n color: var(--mj-text-muted);\n font-size: 14px;\n}\n\n.user-menu-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.user-menu-item.danger[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.user-menu-item.danger[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.user-menu-item.danger[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface-elevated));\n}\n\n.user-menu-divider[_ngcontent-%COMP%] {\n height: 1px;\n background: var(--mj-border-default);\n margin: 4px 0;\n}\n\n\n\n.user-menu-item.disabled[_ngcontent-%COMP%] {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.user-menu-item.disabled[_ngcontent-%COMP%]:hover {\n background: transparent;\n}\n\n\n\n.theme-toggle-item[_ngcontent-%COMP%] {\n cursor: pointer;\n}\n\n.theme-toggle-track[_ngcontent-%COMP%] {\n position: relative;\n width: 40px;\n height: 22px;\n border-radius: 11px;\n background: var(--mj-bg-surface-active);\n margin-left: auto;\n transition: background 0.2s ease;\n flex-shrink: 0;\n}\n\n.theme-toggle-track.dark[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n}\n\n.theme-toggle-thumb[_ngcontent-%COMP%] {\n position: absolute;\n top: 2px;\n left: 2px;\n width: 18px;\n height: 18px;\n border-radius: 50%;\n background: var(--mj-bg-surface);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: transform 0.2s ease;\n}\n\n.theme-toggle-track.dark[_ngcontent-%COMP%] .theme-toggle-thumb[_ngcontent-%COMP%] {\n transform: translateX(18px);\n}\n\n.theme-toggle-icon[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--mj-text-muted);\n}\n\n.theme-toggle-track.dark[_ngcontent-%COMP%] .theme-toggle-icon[_ngcontent-%COMP%] {\n color: var(--mj-text-inverse);\n}\n\n\n\n.user-menu-item[_ngcontent-%COMP%] .menu-shortcut[_ngcontent-%COMP%] {\n margin-left: auto;\n font-size: 11px;\n color: var(--mj-text-disabled);\n font-family: monospace;\n}\n\n\n\n.user-context-menu.menu-fade[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_menuFadeIn 0.15s ease-out;\n}\n\n.user-context-menu.menu-slide[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_menuSlideIn 0.2s ease-out;\n}\n\n@keyframes _ngcontent-%COMP%_menuFadeIn {\n from {\n opacity: 0;\n transform: translateY(-8px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n@keyframes _ngcontent-%COMP%_menuSlideIn {\n from {\n opacity: 0;\n transform: translateY(-16px) scale(0.95);\n }\n to {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n}\n\n.shell-loading[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100vh;\n padding-bottom: 15vh;\n background: var(--mj-bg-page);\n}\n\n\n\n.loading-reset-panel[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--mj-space-3);\n margin-top: var(--mj-space-10);\n padding: var(--mj-space-8);\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-md);\n max-width: 420px;\n animation: _ngcontent-%COMP%_resetPanelFadeIn 0.4s ease-out;\n}\n\n.loading-reset-message[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n margin: 0;\n font-size: var(--mj-text-base);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n}\n\n.loading-reset-message[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: var(--mj-text-lg);\n color: var(--mj-status-warning);\n}\n\n.loading-reset-hint[_ngcontent-%COMP%] {\n margin: 0;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-secondary);\n text-align: center;\n line-height: var(--mj-leading-relaxed);\n}\n\n.loading-reset-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: var(--mj-space-2);\n margin-top: var(--mj-space-3);\n padding: var(--mj-space-3) var(--mj-space-6);\n font-size: var(--mj-text-base);\n font-weight: var(--mj-font-medium);\n font-family: var(--mj-font-family);\n color: var(--mj-text-inverse);\n background: var(--mj-brand-primary);\n border: 1px solid var(--mj-brand-primary);\n border-radius: var(--mj-radius-md);\n cursor: pointer;\n transition: var(--mj-transition-colors);\n}\n\n.loading-reset-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary-hover);\n color: var(--mj-text-inverse);\n border-color: var(--mj-brand-primary-hover);\n box-shadow: var(--mj-shadow-md);\n}\n\n.loading-reset-btn[_ngcontent-%COMP%]:active {\n background: var(--mj-brand-primary-active);\n color: var(--mj-text-inverse);\n transform: scale(0.98);\n}\n\n.loading-reset-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n}\n\n@keyframes _ngcontent-%COMP%_resetPanelFadeIn {\n from {\n opacity: 0;\n transform: translateY(12px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n\n\n.hamburger-btn[_ngcontent-%COMP%] {\n display: none;\n width: 40px;\n height: 40px;\n border-radius: 8px;\n border: none;\n background: none;\n cursor: pointer;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-secondary);\n font-size: 20px;\n transition: background 0.15s;\n}\n.hamburger-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n\n\n.mobile-nav-overlay[_ngcontent-%COMP%] {\n display: none;\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n z-index: 9998;\n}\n\n\n\n.mobile-nav-drawer[_ngcontent-%COMP%] {\n display: none;\n position: fixed;\n top: 0;\n left: 0;\n bottom: 0;\n width: 280px;\n max-width: 85vw;\n background: var(--mj-bg-surface);\n box-shadow: var(--mj-shadow-xl);\n z-index: 9999;\n flex-direction: column;\n transform: translateX(-100%);\n transition: transform 0.3s ease;\n}\n.mobile-nav-drawer.open[_ngcontent-%COMP%] {\n transform: translateX(0);\n}\n\n.mobile-nav-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n}\n.mobile-nav-header[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-weight: 600;\n font-size: 16px;\n color: var(--mj-text-primary);\n}\n.mobile-nav-header[_ngcontent-%COMP%] .close-btn[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n border-radius: 50%;\n border: none;\n background: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 18px;\n transition: background 0.15s;\n}\n.mobile-nav-header[_ngcontent-%COMP%] .close-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-active);\n}\n\n.mobile-nav-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 16px 0;\n}\n\n.mobile-nav-section-title[_ngcontent-%COMP%] {\n padding: 8px 20px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-disabled);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.mobile-nav-footer[_ngcontent-%COMP%] {\n border-top: 1px solid var(--mj-border-default);\n padding: 12px 16px;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.mobile-nav-action[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px;\n border: none;\n background: none;\n cursor: pointer;\n border-radius: 8px;\n color: var(--mj-text-secondary);\n font-size: 14px;\n font-weight: 500;\n transition: background 0.15s;\n width: 100%;\n text-align: left;\n}\n.mobile-nav-action[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n.mobile-nav-action[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n width: 20px;\n text-align: center;\n}\n\n\n\n@media (max-width: 768px) {\n .hamburger-btn[_ngcontent-%COMP%] {\n display: flex;\n }\n\n .desktop-nav[_ngcontent-%COMP%] {\n display: none !important;\n }\n\n .desktop-only[_ngcontent-%COMP%] {\n display: none !important;\n }\n\n .mobile-nav-overlay[_ngcontent-%COMP%] {\n display: block;\n }\n\n .mobile-nav-drawer[_ngcontent-%COMP%] {\n display: flex;\n }\n\n .shell-header[_ngcontent-%COMP%] {\n padding: 0 12px;\n gap: 8px;\n }\n}\n\n\n\n .settings-fullscreen-window {\n \n\n box-shadow: none !important;\n border: none !important;\n}\n\n .settings-fullscreen-window .k-window-titlebar {\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n padding: 12px 16px;\n}\n\n .settings-fullscreen-window .k-window-title {\n font-size: 18px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n .settings-fullscreen-window .k-window-titlebar-actions {\n gap: 4px;\n}\n\n .settings-fullscreen-window .k-window-titlebar-action {\n width: 32px;\n height: 32px;\n border-radius: 6px;\n}\n\n .settings-fullscreen-window .k-window-titlebar-action:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n .settings-fullscreen-window .k-window-content {\n padding: 0;\n overflow: auto;\n background: var(--mj-bg-page);\n}\n\n\n\n .settings-fullscreen-window .k-window-titlebar-action[title=\"Minimize\"], \n .settings-fullscreen-window .k-window-titlebar-action[title=\"Maximize\"], \n .settings-fullscreen-window .k-window-titlebar-action .k-i-window-minimize, \n .settings-fullscreen-window .k-window-titlebar-action .k-i-window-maximize, \n .settings-fullscreen-window .k-window-titlebar-action .k-i-window {\n display: none !important;\n}\n\n\n\n\n\n.shell-search-bar[_ngcontent-%COMP%] {\n flex: 0 1 420px;\n min-width: 200px;\n max-width: 520px;\n margin: 0 12px;\n position: relative;\n z-index: 99999;\n}\n@media (max-width: 768px) {\n .shell-search-bar[_ngcontent-%COMP%] { display: none; }\n}\n\n\n\n\n\n\n.search-popup-overlay[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.3);\n z-index: 9999;\n animation: _ngcontent-%COMP%_fadeIn 0.15s ease;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n.search-popup[_ngcontent-%COMP%] {\n position: fixed;\n top: 60px; \n\n right: 16px;\n width: 480px;\n max-width: calc(100vw - 32px);\n background: var(--mj-bg-surface-elevated);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-xl);\n z-index: 10000;\n opacity: 0;\n transform: translateY(-10px);\n pointer-events: none;\n transition: opacity 0.2s ease, transform 0.2s ease;\n}\n\n.search-popup.open[_ngcontent-%COMP%] {\n opacity: 1;\n transform: translateY(0);\n pointer-events: all;\n}\n\n.search-popup-content[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px;\n}\n\n.search-entity-dropdown[_ngcontent-%COMP%] {\n min-width: 140px;\n max-width: 180px;\n flex-shrink: 0;\n}\n\n.search-input[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n height: 40px;\n padding: 8px 12px;\n font-size: 14px;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n outline: none;\n display: block !important;\n box-sizing: border-box;\n}\n\n.search-input[_ngcontent-%COMP%]:focus {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.search-submit-btn[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n border-radius: 8px;\n border: none;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 16px;\n transition: background 0.15s;\n flex-shrink: 0;\n}\n\n.search-submit-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary-hover);\n}\n\n.search-submit-btn[_ngcontent-%COMP%]:active {\n background: var(--mj-brand-primary-hover);\n}\n\n\n\n.notification-badge-mobile[_ngcontent-%COMP%] {\n position: absolute;\n top: 8px;\n right: 8px;\n min-width: 18px;\n height: 18px;\n padding: 0 5px;\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n font-size: 11px;\n font-weight: 600;\n border-radius: 9px;\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n}\n\n\n\n@media (max-width: 768px) {\n .search-popup[_ngcontent-%COMP%] {\n top: 60px;\n left: 16px;\n right: 16px;\n width: auto;\n max-width: none;\n }\n\n .search-popup-content[_ngcontent-%COMP%] {\n flex-wrap: wrap;\n }\n\n .search-entity-dropdown[_ngcontent-%COMP%] {\n width: 100%;\n }\n\n .search-input[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n }\n}\n\n\n\n\n\n.pin-progress-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: color-mix(in srgb, var(--mj-text-primary) 40%, transparent);\n z-index: 100000;\n display: flex;\n align-items: center;\n justify-content: center;\n animation: _ngcontent-%COMP%_pinBackdropIn 0.2s ease;\n}\n\n@keyframes _ngcontent-%COMP%_pinBackdropIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n.pin-progress-modal[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border-radius: var(--mj-radius-xl);\n padding: 28px 40px;\n display: flex;\n align-items: center;\n gap: 16px;\n box-shadow: 0 16px 48px color-mix(in srgb, var(--mj-text-primary) 30%, transparent);\n animation: _ngcontent-%COMP%_pinModalIn 0.25s ease;\n}\n\n@keyframes _ngcontent-%COMP%_pinModalIn {\n from { opacity: 0; transform: scale(0.9) translateY(8px); }\n to { opacity: 1; transform: scale(1) translateY(0); }\n}\n\n.pin-progress-text[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-medium);\n color: var(--mj-text-secondary);\n white-space: nowrap;\n}"] });
2723
2914
  }
2724
2915
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ShellComponent, [{
2725
2916
  type: Component,
2726
- args: [{ standalone: false, selector: 'mj-shell', template: "<div class=\"shell-container\" [class.hidden]=\"loading\" [class.tabs-visible]=\"tabBarVisible\">\n <!-- Header -->\n <header class=\"shell-header\">\n <!-- MJ Logo -->\n <div class=\"mj-logo\" title=\"MemberJunction\"></div>\n\n <!-- Mobile Hamburger Button -->\n <button class=\"hamburger-btn\" (click)=\"toggleMobileNav()\" title=\"Menu\">\n <i class=\"fa-solid fa-bars\"></i>\n </button>\n\n <!-- Nav Bar Apps: Left of App Switcher -->\n @if (leftOfSwitcherApps.length > 0) {\n <div class=\"nav-bar-apps left-of-switcher\">\n @for (app of leftOfSwitcherApps; track app) {\n <button\n class=\"nav-bar-app-btn\"\n [class.active]=\"IsActiveApp(app)\"\n [title]=\"app.Name\"\n [style.--app-color]=\"app.GetColor()\"\n (click)=\"onNavBarAppClick(app, $event)\"\n (dblclick)=\"onNavBarAppDblClick(app, $event)\">\n <i [class]=\"app.Icon\"></i>\n </button>\n }\n </div>\n }\n\n <!-- App Switcher -->\n <mj-app-switcher\n [activeApp]=\"activeApp\"\n [isViewingSystemTab]=\"isViewingSystemTab\"\n [loadingAppId]=\"loadingAppId\"\n (appSelected)=\"onAppSwitch($event)\">\n </mj-app-switcher>\n\n <!-- App Navigation (desktop only) -->\n @if (activeApp) {\n <mj-app-nav\n class=\"desktop-nav\"\n [app]=\"activeApp\"\n (navItemClick)=\"onNavItemClick($event)\"\n (navItemDismiss)=\"onNavItemDismiss($event)\">\n </mj-app-nav>\n }\n\n <!-- Spacer -->\n <div class=\"spacer\"></div>\n\n <!-- Actions (search, notifications, user menu) -->\n <div class=\"header-actions\">\n <button class=\"icon-btn desktop-only search-toggle-btn\" title=\"Search\" (click)=\"toggleSearch()\">\n <i class=\"fa-solid fa-search\"></i>\n </button>\n <button class=\"icon-btn desktop-only notification-btn\" title=\"Notifications\" (click)=\"showNotifications()\">\n <i class=\"fa-solid fa-bell\"></i>\n @if (unreadNotificationCount > 0) {\n <span class=\"notification-badge\">\n {{ unreadNotificationCount > 99 ? '99+' : unreadNotificationCount }}\n </span>\n }\n </button>\n\n <!-- Nav Bar Apps: Left of User Menu -->\n @if (leftOfUserMenuApps.length > 0) {\n <div class=\"nav-bar-apps left-of-user-menu\">\n @for (app of leftOfUserMenuApps; track app) {\n <button\n class=\"nav-bar-app-btn\"\n [class.active]=\"IsActiveApp(app)\"\n [title]=\"app.Name\"\n [style.--app-color]=\"app.GetColor()\"\n (click)=\"onNavBarAppClick(app, $event)\"\n (dblclick)=\"onNavBarAppDblClick(app, $event)\">\n <i [class]=\"app.Icon\"></i>\n </button>\n }\n </div>\n }\n\n <div class=\"user-menu\">\n <button class=\"avatar-btn\" (click)=\"toggleUserMenu($event)\">\n @if (userImageURL) {\n <img [src]=\"userImageURL\" alt=\"User avatar\" class=\"avatar-img\" />\n } @else {\n <div class=\"icon-fallback\">\n <i [class]=\"userIconClass || 'fa-solid fa-user'\"></i>\n </div>\n }\n </button>\n <!-- User Context Menu (Dynamic) -->\n @if (userMenuVisible) {\n <div class=\"user-context-menu\"\n [class.menu-fade]=\"getUserMenuOptions()?.animationStyle === 'fade'\"\n [class.menu-slide]=\"getUserMenuOptions()?.animationStyle === 'slide'\">\n <!-- User Header -->\n @if (getUserMenuOptions()?.showUserName) {\n <div class=\"user-menu-header\">\n <div class=\"user-info\">\n <span class=\"user-name\">{{ getUserDisplayInfo()?.name || userName }}</span>\n @if (getUserMenuOptions()?.showUserEmail && getUserDisplayInfo()?.email) {\n <span class=\"user-email\">\n {{ getUserDisplayInfo()?.email }}\n </span>\n }\n </div>\n </div>\n <div class=\"user-menu-divider\"></div>\n }\n <!-- Dynamic Menu Items -->\n @for (element of userMenuElements; track element) {\n <!-- Divider -->\n @if (isMenuDivider(element)) {\n <div class=\"user-menu-divider\"></div>\n }\n <!-- Menu Item -->\n @if (!isMenuDivider(element)) {\n @if (asMenuItem(element); as item) {\n @if (item.id === 'toggle-theme') {\n <div class=\"user-menu-item theme-toggle-item\"\n [title]=\"item.tooltip || ''\"\n (click)=\"onUserMenuItemClick(item.id)\">\n <i [class]=\"item.icon\"></i>\n <span class=\"menu-label\">{{ item.label }}</span>\n <div class=\"theme-toggle-track\" [class.dark]=\"IsDarkMode\">\n <div class=\"theme-toggle-thumb\">\n <i [class]=\"IsDarkMode ? 'fa-solid fa-moon' : 'fa-solid fa-sun'\" class=\"theme-toggle-icon\"></i>\n </div>\n </div>\n </div>\n } @else {\n <div class=\"user-menu-item\"\n [class.disabled]=\"!item.enabled\"\n [class.danger]=\"item.cssClass === 'danger'\"\n [style.color]=\"item.color || null\"\n [title]=\"item.tooltip || ''\"\n (click)=\"item.enabled && onUserMenuItemClick(item.id)\">\n <i [class]=\"item.icon\"></i>\n <span class=\"menu-label\">{{ item.label }}</span>\n @if (item.shortcut) {\n <span class=\"menu-shortcut\">{{ item.shortcut }}</span>\n }\n </div>\n }\n }\n }\n }\n </div>\n }\n </div>\n </div>\n </header>\n\n <!-- Search Popup -->\n @if (isSearchOpen) {\n <div class=\"search-popup-overlay\" (click)=\"closeSearch()\"></div>\n }\n <div class=\"search-popup\" [class.open]=\"isSearchOpen\">\n <div class=\"search-popup-content\" (click)=\"$event.stopPropagation()\">\n <mj-dropdown\n [Data]=\"searchableEntities\"\n TextField=\"Name\"\n ValueField=\"ID\"\n class=\"search-entity-dropdown\"\n [(ngModel)]=\"selectedEntity\">\n </mj-dropdown>\n <input\n type=\"text\"\n #searchInput\n placeholder=\"Search...\"\n class=\"mj-input search-input\"\n (keydown.enter)=\"onSearch($event)\"\n />\n <button class=\"search-submit-btn\" (click)=\"onSearch($event)\" title=\"Search\">\n <i class=\"fa-solid fa-search\"></i>\n </button>\n </div>\n </div>\n\n <!-- Mobile Navigation Drawer -->\n @if (mobileNavOpen) {\n <div class=\"mobile-nav-overlay\" (click)=\"closeMobileNav()\"></div>\n }\n <div class=\"mobile-nav-drawer\" [class.open]=\"mobileNavOpen\">\n <div class=\"mobile-nav-header\">\n <span>Navigation</span>\n <button class=\"close-btn\" (click)=\"closeMobileNav()\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n @if (activeApp) {\n <div class=\"mobile-nav-content\">\n <div class=\"mobile-nav-section-title\">{{ activeApp.Name }}</div>\n <mj-app-nav\n [app]=\"activeApp\"\n (navItemClick)=\"onNavItemClick($event)\"\n (navItemDismiss)=\"onNavItemDismiss($event)\">\n </mj-app-nav>\n </div>\n }\n <div class=\"mobile-nav-footer\">\n <button class=\"mobile-nav-action\" title=\"Search\" (click)=\"toggleSearch(); closeMobileNav()\">\n <i class=\"fa-solid fa-search\"></i>\n <span>Search</span>\n </button>\n <button class=\"mobile-nav-action\" title=\"Notifications\" (click)=\"showNotifications(); closeMobileNav()\">\n <i class=\"fa-solid fa-bell\"></i>\n <span>Notifications</span>\n @if (unreadNotificationCount > 0) {\n <span class=\"notification-badge-mobile\">\n {{ unreadNotificationCount > 99 ? '99+' : unreadNotificationCount }}\n </span>\n }\n </button>\n </div>\n </div>\n\n <!-- Tab Container - with dynamic tab bar visibility -->\n <mj-tab-container\n [class.hide-tab-bar]=\"!tabBarVisible\"\n (firstResourceLoadComplete)=\"onFirstResourceLoadComplete()\"\n (layoutInitError)=\"handleLayoutError()\">\n </mj-tab-container>\n</div>\n\n<!-- Loading State -->\n@if (loading) {\n <div class=\"shell-loading\">\n <mj-loading\n [text]=\"currentLoadingText\"\n [textColor]=\"currentLoadingTextColor\"\n [logoColor]=\"currentLoadingColor\"\n [logoGradient]=\"currentLoadingGradient\"\n [animation]=\"currentLoadingAnimation\"\n size=\"large\">\n </mj-loading>\n @if (ShowResetOption) {\n <div class=\"loading-reset-panel\">\n <p class=\"loading-reset-message\">\n <i class=\"fa-regular fa-clock\"></i>\n Taking longer than expected\n </p>\n <p class=\"loading-reset-hint\">\n This can happen after updates or due to cached data issues.\n </p>\n <button class=\"loading-reset-btn\" (click)=\"ResetApplication()\">\n <i class=\"fa-solid fa-arrows-rotate\"></i>\n Reset\n </button>\n </div>\n }\n </div>\n}\n\n<!-- App Access Error Dialog -->\n<mj-app-access-dialog\n #appAccessDialog\n (result)=\"onAppAccessDialogResult($event)\">\n</mj-app-access-dialog>\n\n<!-- Command Palette -->\n<mj-command-palette (AppSelected)=\"onAppSwitch($event)\"></mj-command-palette>\n\n<!-- Pin Progress Overlay -->\n@if (PinProgressVisible) {\n <div class=\"pin-progress-backdrop\">\n <div class=\"pin-progress-modal\">\n <mj-loading [showText]=\"false\" size=\"small\"></mj-loading>\n <span class=\"pin-progress-text\">{{ PinProgressText }}</span>\n </div>\n </div>\n}\n", styles: [":host {\n display: block;\n height: 100vh;\n width: 100%;\n overflow: hidden;\n}\n\n/* MJ Logo - uses design token for theme switching & white-labeling */\n.mj-logo {\n width: 32px;\n height: 18px;\n background-image: var(--mj-logo-mark);\n background-repeat: no-repeat;\n background-position: center;\n background-size: contain;\n flex-shrink: 0;\n}\n\n.shell-container {\n display: flex;\n flex-direction: column;\n height: 100vh;\n width: 100%;\n overflow: hidden;\n}\n\n/* Hide shell container while loading - allows tab container to render and load\n first resource in background while shell loading indicator is visible */\n.shell-container.hidden {\n visibility: hidden;\n position: absolute;\n pointer-events: none;\n}\n\nmj-tab-container {\n flex: 1;\n min-height: 0;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n transition: all 0.2s ease-in-out;\n}\n\n/* Hide Golden Layout tab headers when only one tab */\nmj-tab-container.hide-tab-bar ::ng-deep .lm_header {\n display: none;\n}\n\n/* Show tab headers when multiple tabs */\nmj-tab-container:not(.hide-tab-bar) ::ng-deep .lm_header {\n opacity: 1;\n max-height: 40px;\n transition: opacity 0.2s ease-in-out, max-height 0.2s ease-in-out;\n}\n\n/* Adjust content area height when tabs hidden */\nmj-tab-container.hide-tab-bar ::ng-deep .lm_content {\n height: 100% !important;\n}\n\n/* Ensure smooth transitions */\nmj-tab-container ::ng-deep .lm_stack {\n transition: all 0.2s ease-in-out;\n}\n\n.shell-header {\n height: 60px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n display: flex;\n align-items: center;\n padding: 0 16px;\n gap: 16px;\n box-shadow: var(--mj-shadow-sm);\n flex-shrink: 0;\n}\n\n/* Nav Bar Apps - permanent app icons in the header */\n.nav-bar-apps {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.nav-bar-apps.left-of-switcher {\n /* No extra margin - header gap handles spacing */\n /* This prevents the app switcher from shifting when icons are hidden */\n}\n\n.nav-bar-apps.left-of-user-menu {\n margin-right: 8px;\n}\n\n.nav-bar-app-btn {\n --app-color: var(--mj-text-muted);\n width: 40px;\n height: 40px;\n border-radius: 10px;\n border: none;\n background: transparent;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-secondary);\n font-size: 18px;\n transition: all 0.15s ease;\n position: relative;\n}\n\n.nav-bar-app-btn:hover {\n background: color-mix(in srgb, var(--app-color) 15%, transparent);\n color: var(--app-color);\n}\n\n.nav-bar-app-btn.active {\n background: color-mix(in srgb, var(--app-color) 20%, transparent);\n color: var(--app-color);\n}\n\n.nav-bar-app-btn.active::after {\n content: '';\n position: absolute;\n bottom: 6px;\n left: 50%;\n transform: translateX(-50%);\n width: 16px;\n height: 3px;\n background: var(--app-color);\n border-radius: 2px;\n}\n\n.nav-bar-app-btn i {\n transition: transform 0.15s ease;\n margin-top: 2px; /* Align with app switcher icon */\n}\n\n.nav-bar-app-btn:hover i {\n transform: scale(1.1);\n}\n\n.spacer {\n flex: 1;\n}\n\n.header-actions {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.icon-btn {\n width: 40px;\n height: 40px;\n border-radius: 50%;\n border: none;\n background: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 18px;\n transition: background 0.15s;\n}\n\n.icon-btn:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n/* Notification button with badge */\n.notification-btn {\n position: relative;\n}\n\n.notification-badge {\n position: absolute;\n top: 4px;\n right: 4px;\n min-width: 16px;\n height: 16px;\n padding: 0 4px;\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n font-size: 10px;\n font-weight: 600;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n}\n\n.user-menu {\n position: relative;\n}\n\n.user-menu .avatar-btn {\n width: 36px;\n height: 36px;\n border-radius: 50%;\n border: none;\n background: transparent;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: box-shadow 0.15s, transform 0.15s;\n padding: 0;\n overflow: hidden;\n}\n\n.user-menu .avatar-btn:hover {\n transform: scale(1.05);\n}\n\n/* Icon fallback styling - shows gray circle with icon */\n.user-menu .avatar-btn .icon-fallback {\n width: 100%;\n height: 100%;\n border-radius: 50%;\n border: 2px solid var(--mj-border-default);\n background: var(--mj-bg-surface-hover);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: border-color 0.15s;\n}\n\n.user-menu .avatar-btn:hover .icon-fallback {\n border-color: var(--mj-brand-primary);\n}\n\n.user-menu .avatar-btn .icon-fallback i {\n color: var(--mj-text-muted);\n font-size: 16px;\n}\n\n/* Avatar image - replaces the gray circle entirely */\n.user-menu .avatar-btn .avatar-img {\n width: 100%;\n height: 100%;\n border-radius: 50%;\n object-fit: cover;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);\n}\n\n.user-menu .avatar-btn:hover .avatar-img {\n box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);\n}\n\n/* User Menu Header */\n.user-menu-header {\n padding: 12px 16px;\n background: var(--mj-bg-surface-sunken);\n}\n\n.user-menu-header .user-info {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.user-menu-header .user-name {\n font-weight: 600;\n font-size: 14px;\n color: var(--mj-text-primary);\n}\n\n.user-menu-header .user-email {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n/* User Context Menu */\n.user-context-menu {\n position: absolute;\n top: 100%;\n right: 0;\n margin-top: 8px;\n background: var(--mj-bg-surface-elevated);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n box-shadow: var(--mj-shadow-lg);\n min-width: 180px;\n z-index: 10000;\n overflow: hidden;\n}\n\n.user-menu-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px;\n cursor: pointer;\n font-size: 14px;\n color: var(--mj-text-primary);\n transition: background 0.15s;\n}\n\n.user-menu-item i {\n width: 18px;\n text-align: center;\n color: var(--mj-text-muted);\n font-size: 14px;\n}\n\n.user-menu-item:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.user-menu-item.danger {\n color: var(--mj-status-error);\n}\n\n.user-menu-item.danger i {\n color: var(--mj-status-error);\n}\n\n.user-menu-item.danger:hover {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface-elevated));\n}\n\n.user-menu-divider {\n height: 1px;\n background: var(--mj-border-default);\n margin: 4px 0;\n}\n\n/* Menu item disabled state */\n.user-menu-item.disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.user-menu-item.disabled:hover {\n background: transparent;\n}\n\n/* Theme Toggle Switch */\n.theme-toggle-item {\n cursor: pointer;\n}\n\n.theme-toggle-track {\n position: relative;\n width: 40px;\n height: 22px;\n border-radius: 11px;\n background: var(--mj-bg-surface-active);\n margin-left: auto;\n transition: background 0.2s ease;\n flex-shrink: 0;\n}\n\n.theme-toggle-track.dark {\n background: var(--mj-brand-primary);\n}\n\n.theme-toggle-thumb {\n position: absolute;\n top: 2px;\n left: 2px;\n width: 18px;\n height: 18px;\n border-radius: 50%;\n background: var(--mj-bg-surface);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: transform 0.2s ease;\n}\n\n.theme-toggle-track.dark .theme-toggle-thumb {\n transform: translateX(18px);\n}\n\n.theme-toggle-icon {\n font-size: 10px;\n color: var(--mj-text-muted);\n}\n\n.theme-toggle-track.dark .theme-toggle-icon {\n color: var(--mj-text-inverse);\n}\n\n/* Menu shortcut hint */\n.user-menu-item .menu-shortcut {\n margin-left: auto;\n font-size: 11px;\n color: var(--mj-text-disabled);\n font-family: monospace;\n}\n\n/* Menu animations */\n.user-context-menu.menu-fade {\n animation: menuFadeIn 0.15s ease-out;\n}\n\n.user-context-menu.menu-slide {\n animation: menuSlideIn 0.2s ease-out;\n}\n\n@keyframes menuFadeIn {\n from {\n opacity: 0;\n transform: translateY(-8px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n@keyframes menuSlideIn {\n from {\n opacity: 0;\n transform: translateY(-16px) scale(0.95);\n }\n to {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n}\n\n.shell-loading {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100vh;\n padding-bottom: 15vh;\n background: var(--mj-bg-page);\n}\n\n/* Loading Recovery Reset Panel */\n.loading-reset-panel {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--mj-space-3);\n margin-top: var(--mj-space-10);\n padding: var(--mj-space-8);\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-md);\n max-width: 420px;\n animation: resetPanelFadeIn 0.4s ease-out;\n}\n\n.loading-reset-message {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n margin: 0;\n font-size: var(--mj-text-base);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n}\n\n.loading-reset-message i {\n font-size: var(--mj-text-lg);\n color: var(--mj-status-warning);\n}\n\n.loading-reset-hint {\n margin: 0;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-secondary);\n text-align: center;\n line-height: var(--mj-leading-relaxed);\n}\n\n.loading-reset-btn {\n display: inline-flex;\n align-items: center;\n gap: var(--mj-space-2);\n margin-top: var(--mj-space-3);\n padding: var(--mj-space-3) var(--mj-space-6);\n font-size: var(--mj-text-base);\n font-weight: var(--mj-font-medium);\n font-family: var(--mj-font-family);\n color: var(--mj-text-inverse);\n background: var(--mj-brand-primary);\n border: 1px solid var(--mj-brand-primary);\n border-radius: var(--mj-radius-md);\n cursor: pointer;\n transition: var(--mj-transition-colors);\n}\n\n.loading-reset-btn:hover {\n background: var(--mj-brand-primary-hover);\n color: var(--mj-text-inverse);\n border-color: var(--mj-brand-primary-hover);\n box-shadow: var(--mj-shadow-md);\n}\n\n.loading-reset-btn:active {\n background: var(--mj-brand-primary-active);\n color: var(--mj-text-inverse);\n transform: scale(0.98);\n}\n\n.loading-reset-btn i {\n font-size: var(--mj-text-sm);\n}\n\n@keyframes resetPanelFadeIn {\n from {\n opacity: 0;\n transform: translateY(12px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n/* Hamburger button - hidden on desktop */\n.hamburger-btn {\n display: none;\n width: 40px;\n height: 40px;\n border-radius: 8px;\n border: none;\n background: none;\n cursor: pointer;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-secondary);\n font-size: 20px;\n transition: background 0.15s;\n}\n.hamburger-btn:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n/* Mobile Navigation Overlay */\n.mobile-nav-overlay {\n display: none;\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n z-index: 9998;\n}\n\n/* Mobile Navigation Drawer */\n.mobile-nav-drawer {\n display: none;\n position: fixed;\n top: 0;\n left: 0;\n bottom: 0;\n width: 280px;\n max-width: 85vw;\n background: var(--mj-bg-surface);\n box-shadow: var(--mj-shadow-xl);\n z-index: 9999;\n flex-direction: column;\n transform: translateX(-100%);\n transition: transform 0.3s ease;\n}\n.mobile-nav-drawer.open {\n transform: translateX(0);\n}\n\n.mobile-nav-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n}\n.mobile-nav-header span {\n font-weight: 600;\n font-size: 16px;\n color: var(--mj-text-primary);\n}\n.mobile-nav-header .close-btn {\n width: 36px;\n height: 36px;\n border-radius: 50%;\n border: none;\n background: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 18px;\n transition: background 0.15s;\n}\n.mobile-nav-header .close-btn:hover {\n background: var(--mj-bg-surface-active);\n}\n\n.mobile-nav-content {\n flex: 1;\n overflow-y: auto;\n padding: 16px 0;\n}\n\n.mobile-nav-section-title {\n padding: 8px 20px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-disabled);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.mobile-nav-footer {\n border-top: 1px solid var(--mj-border-default);\n padding: 12px 16px;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.mobile-nav-action {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px;\n border: none;\n background: none;\n cursor: pointer;\n border-radius: 8px;\n color: var(--mj-text-secondary);\n font-size: 14px;\n font-weight: 500;\n transition: background 0.15s;\n width: 100%;\n text-align: left;\n}\n.mobile-nav-action:hover {\n background: var(--mj-bg-surface-hover);\n}\n.mobile-nav-action i {\n font-size: 16px;\n width: 20px;\n text-align: center;\n}\n\n/* Mobile Responsive Styles */\n@media (max-width: 768px) {\n .hamburger-btn {\n display: flex;\n }\n\n .desktop-nav {\n display: none !important;\n }\n\n .desktop-only {\n display: none !important;\n }\n\n .mobile-nav-overlay {\n display: block;\n }\n\n .mobile-nav-drawer {\n display: flex;\n }\n\n .shell-header {\n padding: 0 12px;\n gap: 8px;\n }\n}\n\n/* Settings Full-Screen Window Styles */\n::ng-deep .settings-fullscreen-window {\n /* Remove window chrome for full-screen feel */\n box-shadow: none !important;\n border: none !important;\n}\n\n::ng-deep .settings-fullscreen-window .k-window-titlebar {\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n padding: 12px 16px;\n}\n\n::ng-deep .settings-fullscreen-window .k-window-title {\n font-size: 18px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n::ng-deep .settings-fullscreen-window .k-window-titlebar-actions {\n gap: 4px;\n}\n\n::ng-deep .settings-fullscreen-window .k-window-titlebar-action {\n width: 32px;\n height: 32px;\n border-radius: 6px;\n}\n\n::ng-deep .settings-fullscreen-window .k-window-titlebar-action:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n::ng-deep .settings-fullscreen-window .k-window-content {\n padding: 0;\n overflow: auto;\n background: var(--mj-bg-page);\n}\n\n/* Hide minimize/maximize buttons - only show close */\n::ng-deep .settings-fullscreen-window .k-window-titlebar-action[title=\"Minimize\"],\n::ng-deep .settings-fullscreen-window .k-window-titlebar-action[title=\"Maximize\"],\n::ng-deep .settings-fullscreen-window .k-window-titlebar-action .k-i-window-minimize,\n::ng-deep .settings-fullscreen-window .k-window-titlebar-action .k-i-window-maximize,\n::ng-deep .settings-fullscreen-window .k-window-titlebar-action .k-i-window {\n display: none !important;\n}\n\n/* ========================================\n SEARCH POPUP\n ======================================== */\n\n.search-popup-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.3);\n z-index: 9999;\n animation: fadeIn 0.15s ease;\n}\n\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n.search-popup {\n position: fixed;\n top: 60px; /* Below header */\n right: 16px;\n width: 480px;\n max-width: calc(100vw - 32px);\n background: var(--mj-bg-surface-elevated);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-xl);\n z-index: 10000;\n opacity: 0;\n transform: translateY(-10px);\n pointer-events: none;\n transition: opacity 0.2s ease, transform 0.2s ease;\n}\n\n.search-popup.open {\n opacity: 1;\n transform: translateY(0);\n pointer-events: all;\n}\n\n.search-popup-content {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px;\n}\n\n.search-entity-dropdown {\n min-width: 140px;\n max-width: 180px;\n flex-shrink: 0;\n}\n\n.search-input {\n flex: 1;\n min-width: 0;\n height: 40px;\n padding: 8px 12px;\n font-size: 14px;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n outline: none;\n display: block !important;\n box-sizing: border-box;\n}\n\n.search-input:focus {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.search-submit-btn {\n width: 40px;\n height: 40px;\n border-radius: 8px;\n border: none;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 16px;\n transition: background 0.15s;\n flex-shrink: 0;\n}\n\n.search-submit-btn:hover {\n background: var(--mj-brand-primary-hover);\n}\n\n.search-submit-btn:active {\n background: var(--mj-brand-primary-hover);\n}\n\n/* Mobile notification badge */\n.notification-badge-mobile {\n position: absolute;\n top: 8px;\n right: 8px;\n min-width: 18px;\n height: 18px;\n padding: 0 5px;\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n font-size: 11px;\n font-weight: 600;\n border-radius: 9px;\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n}\n\n/* Mobile-specific search popup adjustments */\n@media (max-width: 768px) {\n .search-popup {\n top: 60px;\n left: 16px;\n right: 16px;\n width: auto;\n max-width: none;\n }\n\n .search-popup-content {\n flex-wrap: wrap;\n }\n\n .search-entity-dropdown {\n width: 100%;\n }\n\n .search-input {\n flex: 1;\n min-width: 0;\n }\n}\n\n/* ========================================\n PIN PROGRESS OVERLAY\n ======================================== */\n.pin-progress-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: color-mix(in srgb, var(--mj-text-primary) 40%, transparent);\n z-index: 100000;\n display: flex;\n align-items: center;\n justify-content: center;\n animation: pinBackdropIn 0.2s ease;\n}\n\n@keyframes pinBackdropIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n.pin-progress-modal {\n background: var(--mj-bg-surface);\n border-radius: var(--mj-radius-xl);\n padding: 28px 40px;\n display: flex;\n align-items: center;\n gap: 16px;\n box-shadow: 0 16px 48px color-mix(in srgb, var(--mj-text-primary) 30%, transparent);\n animation: pinModalIn 0.25s ease;\n}\n\n@keyframes pinModalIn {\n from { opacity: 0; transform: scale(0.9) translateY(8px); }\n to { opacity: 1; transform: scale(1) translateY(0); }\n}\n\n.pin-progress-text {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-medium);\n color: var(--mj-text-secondary);\n white-space: nowrap;\n}"] }]
2727
- }], () => [{ type: i1.ApplicationManager }, { type: i1.WorkspaceStateManager }, { type: i1.GoldenLayoutManager }, { type: i1.TabService }, { type: i2.NavigationService }, { type: i3.ActivatedRoute }, { type: i3.Router }, { type: i4.MJAuthBase }, { type: i0.ChangeDetectorRef }, { type: i5.UserAvatarService }, { type: i6.SettingsDialogService }, { type: i0.ViewContainerRef }, { type: i2.TitleService }, { type: i2.DeveloperModeService }, { type: i7.CommandPaletteService }, { type: i2.ThemeService }, { type: i2.HomeAppPinService }], { searchInput: [{
2917
+ args: [{ standalone: false, selector: 'mj-shell', template: "<div class=\"shell-container\" [class.hidden]=\"loading\" [class.tabs-visible]=\"tabBarVisible\">\n <!-- Header -->\n <header class=\"shell-header\">\n <!-- MJ Logo -->\n <div class=\"mj-logo\" title=\"MemberJunction\"></div>\n\n <!-- Mobile Hamburger Button -->\n <button class=\"hamburger-btn\" (click)=\"toggleMobileNav()\" title=\"Menu\">\n <i class=\"fa-solid fa-bars\"></i>\n </button>\n\n <!-- Nav Bar Apps: Left of App Switcher -->\n @if (leftOfSwitcherApps.length > 0) {\n <div class=\"nav-bar-apps left-of-switcher\">\n @for (app of leftOfSwitcherApps; track app) {\n <button\n class=\"nav-bar-app-btn\"\n [class.active]=\"IsActiveApp(app)\"\n [title]=\"app.Name\"\n [style.--app-color]=\"app.GetColor()\"\n (click)=\"onNavBarAppClick(app, $event)\"\n (dblclick)=\"onNavBarAppDblClick(app, $event)\">\n <i [class]=\"app.Icon\"></i>\n </button>\n }\n </div>\n }\n\n <!-- App Switcher -->\n <mj-app-switcher\n [activeApp]=\"activeApp\"\n [isViewingSystemTab]=\"isViewingSystemTab\"\n [loadingAppId]=\"loadingAppId\"\n (appSelected)=\"onAppSwitch($event)\">\n </mj-app-switcher>\n\n <!-- App Navigation (desktop only) -->\n @if (activeApp) {\n <mj-app-nav\n class=\"desktop-nav\"\n [app]=\"activeApp\"\n (navItemClick)=\"onNavItemClick($event)\"\n (navItemDismiss)=\"onNavItemDismiss($event)\">\n </mj-app-nav>\n }\n\n <!-- Universal Search Bar -->\n @if (ShowSearchBar) {\n <div class=\"shell-search-bar desktop-only\">\n <mj-search-composite\n #shellSearchComposite\n Placeholder=\"Search everything...\"\n [ShowShortcutHint]=\"true\"\n [EnablePreview]=\"ShowSearchPreview\"\n [EnableRecent]=\"true\"\n [MaxPreviewResults]=\"8\"\n (ResultSelected)=\"OnSearchResultSelected($event)\"\n (SearchSubmitted)=\"OnSearchSubmitted($event)\"\n (SeeAllRequested)=\"OnSeeAllSearch($event)\">\n </mj-search-composite>\n </div>\n }\n <!-- Spacer -->\n <div class=\"spacer\"></div>\n <!-- Actions (notifications, user menu) -->\n <div class=\"header-actions\">\n <button class=\"icon-btn desktop-only notification-btn\" title=\"Notifications\" (click)=\"showNotifications()\">\n <i class=\"fa-solid fa-bell\"></i>\n @if (unreadNotificationCount > 0) {\n <span class=\"notification-badge\">\n {{ unreadNotificationCount > 99 ? '99+' : unreadNotificationCount }}\n </span>\n }\n </button>\n\n <!-- Nav Bar Apps: Left of User Menu -->\n @if (leftOfUserMenuApps.length > 0) {\n <div class=\"nav-bar-apps left-of-user-menu\">\n @for (app of leftOfUserMenuApps; track app) {\n <button\n class=\"nav-bar-app-btn\"\n [class.active]=\"IsActiveApp(app)\"\n [title]=\"app.Name\"\n [style.--app-color]=\"app.GetColor()\"\n (click)=\"onNavBarAppClick(app, $event)\"\n (dblclick)=\"onNavBarAppDblClick(app, $event)\">\n <i [class]=\"app.Icon\"></i>\n </button>\n }\n </div>\n }\n\n <div class=\"user-menu\">\n <button class=\"avatar-btn\" (click)=\"toggleUserMenu($event)\">\n @if (userImageURL) {\n <img [src]=\"userImageURL\" alt=\"User avatar\" class=\"avatar-img\" />\n } @else {\n <div class=\"icon-fallback\">\n <i [class]=\"userIconClass || 'fa-solid fa-user'\"></i>\n </div>\n }\n </button>\n <!-- User Context Menu (Dynamic) -->\n @if (userMenuVisible) {\n <div class=\"user-context-menu\"\n [class.menu-fade]=\"getUserMenuOptions()?.animationStyle === 'fade'\"\n [class.menu-slide]=\"getUserMenuOptions()?.animationStyle === 'slide'\">\n <!-- User Header -->\n @if (getUserMenuOptions()?.showUserName) {\n <div class=\"user-menu-header\">\n <div class=\"user-info\">\n <span class=\"user-name\">{{ getUserDisplayInfo()?.name || userName }}</span>\n @if (getUserMenuOptions()?.showUserEmail && getUserDisplayInfo()?.email) {\n <span class=\"user-email\">\n {{ getUserDisplayInfo()?.email }}\n </span>\n }\n @if (getUserDisplayInfo()?.subtitle) {\n <span class=\"user-subtitle\">{{ getUserDisplayInfo()?.subtitle }}</span>\n }\n </div>\n </div>\n <div class=\"user-menu-divider\"></div>\n }\n <!-- Dynamic Menu Items -->\n @for (element of userMenuElements; track element) {\n <!-- Divider -->\n @if (isMenuDivider(element)) {\n <div class=\"user-menu-divider\"></div>\n }\n <!-- Menu Item -->\n @if (!isMenuDivider(element)) {\n @if (asMenuItem(element); as item) {\n @if (item.id === 'toggle-theme') {\n <div class=\"user-menu-item theme-toggle-item\"\n [title]=\"item.tooltip || ''\"\n (click)=\"onUserMenuItemClick(item.id)\">\n <i [class]=\"item.icon\"></i>\n <span class=\"menu-label\">{{ item.label }}</span>\n <div class=\"theme-toggle-track\" [class.dark]=\"IsDarkMode\">\n <div class=\"theme-toggle-thumb\">\n <i [class]=\"IsDarkMode ? 'fa-solid fa-moon' : 'fa-solid fa-sun'\" class=\"theme-toggle-icon\"></i>\n </div>\n </div>\n </div>\n } @else {\n <div class=\"user-menu-item\"\n [class.disabled]=\"!item.enabled\"\n [class.danger]=\"item.cssClass === 'danger'\"\n [style.color]=\"item.color || null\"\n [title]=\"item.tooltip || ''\"\n (click)=\"item.enabled && onUserMenuItemClick(item.id)\">\n <i [class]=\"item.icon\"></i>\n <span class=\"menu-label\">{{ item.label }}</span>\n @if (item.shortcut) {\n <span class=\"menu-shortcut\">{{ item.shortcut }}</span>\n }\n </div>\n }\n }\n }\n }\n </div>\n }\n </div>\n </div>\n </header>\n\n <!-- Search Popup -->\n @if (isSearchOpen) {\n <div class=\"search-popup-overlay\" (click)=\"closeSearch()\"></div>\n }\n <div class=\"search-popup\" [class.open]=\"isSearchOpen\">\n <div class=\"search-popup-content\" (click)=\"$event.stopPropagation()\">\n <mj-dropdown\n [Data]=\"searchableEntities\"\n TextField=\"Name\"\n ValueField=\"ID\"\n class=\"search-entity-dropdown\"\n [(ngModel)]=\"selectedEntity\">\n </mj-dropdown>\n <input\n type=\"text\"\n #searchInput\n placeholder=\"Search...\"\n class=\"mj-input search-input\"\n (keydown.enter)=\"onSearch($event)\"\n />\n <button class=\"search-submit-btn\" (click)=\"onSearch($event)\" title=\"Search\">\n <i class=\"fa-solid fa-search\"></i>\n </button>\n </div>\n </div>\n\n <!-- Mobile Navigation Drawer -->\n @if (mobileNavOpen) {\n <div class=\"mobile-nav-overlay\" (click)=\"closeMobileNav()\"></div>\n }\n <div class=\"mobile-nav-drawer\" [class.open]=\"mobileNavOpen\">\n <div class=\"mobile-nav-header\">\n <span>Navigation</span>\n <button class=\"close-btn\" (click)=\"closeMobileNav()\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n @if (activeApp) {\n <div class=\"mobile-nav-content\">\n <div class=\"mobile-nav-section-title\">{{ activeApp.Name }}</div>\n <mj-app-nav\n [app]=\"activeApp\"\n (navItemClick)=\"onNavItemClick($event)\"\n (navItemDismiss)=\"onNavItemDismiss($event)\">\n </mj-app-nav>\n </div>\n }\n <div class=\"mobile-nav-footer\">\n <button class=\"mobile-nav-action\" title=\"Search\" (click)=\"toggleSearch(); closeMobileNav()\">\n <i class=\"fa-solid fa-search\"></i>\n <span>Search</span>\n </button>\n <button class=\"mobile-nav-action\" title=\"Notifications\" (click)=\"showNotifications(); closeMobileNav()\">\n <i class=\"fa-solid fa-bell\"></i>\n <span>Notifications</span>\n @if (unreadNotificationCount > 0) {\n <span class=\"notification-badge-mobile\">\n {{ unreadNotificationCount > 99 ? '99+' : unreadNotificationCount }}\n </span>\n }\n </button>\n </div>\n </div>\n\n <!-- Tab Container - with dynamic tab bar visibility -->\n <mj-tab-container\n [class.hide-tab-bar]=\"!tabBarVisible\"\n (firstResourceLoadComplete)=\"onFirstResourceLoadComplete()\"\n (layoutInitError)=\"handleLayoutError()\">\n </mj-tab-container>\n</div>\n\n<!-- Loading State -->\n@if (loading) {\n <div class=\"shell-loading\">\n <mj-loading\n [text]=\"currentLoadingText\"\n [textColor]=\"currentLoadingTextColor\"\n [logoColor]=\"currentLoadingColor\"\n [logoGradient]=\"currentLoadingGradient\"\n [animation]=\"currentLoadingAnimation\"\n size=\"large\">\n </mj-loading>\n @if (ShowResetOption) {\n <div class=\"loading-reset-panel\">\n <p class=\"loading-reset-message\">\n <i class=\"fa-regular fa-clock\"></i>\n Taking longer than expected\n </p>\n <p class=\"loading-reset-hint\">\n This can happen after updates or due to cached data issues.\n </p>\n <button class=\"loading-reset-btn\" (click)=\"ResetApplication()\">\n <i class=\"fa-solid fa-arrows-rotate\"></i>\n Reset\n </button>\n </div>\n }\n </div>\n}\n\n<!-- App Access Error Dialog -->\n<mj-app-access-dialog\n #appAccessDialog\n (result)=\"onAppAccessDialogResult($event)\">\n</mj-app-access-dialog>\n\n<!-- Command Palette -->\n<mj-command-palette (AppSelected)=\"onAppSwitch($event)\"></mj-command-palette>\n\n<!-- Pin Progress Overlay -->\n@if (PinProgressVisible) {\n <div class=\"pin-progress-backdrop\">\n <div class=\"pin-progress-modal\">\n <mj-loading [showText]=\"false\" size=\"small\"></mj-loading>\n <span class=\"pin-progress-text\">{{ PinProgressText }}</span>\n </div>\n </div>\n}\n", styles: [":host {\n display: block;\n height: 100vh;\n width: 100%;\n overflow: hidden;\n}\n\n/* MJ Logo - uses design token for theme switching & white-labeling */\n.mj-logo {\n width: 32px;\n height: 18px;\n background-image: var(--mj-logo-mark);\n background-repeat: no-repeat;\n background-position: center;\n background-size: contain;\n flex-shrink: 0;\n}\n\n.shell-container {\n display: flex;\n flex-direction: column;\n height: 100vh;\n width: 100%;\n overflow: hidden;\n}\n\n/* Hide shell container while loading - allows tab container to render and load\n first resource in background while shell loading indicator is visible */\n.shell-container.hidden {\n visibility: hidden;\n position: absolute;\n pointer-events: none;\n}\n\nmj-tab-container {\n flex: 1;\n min-height: 0;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n transition: all 0.2s ease-in-out;\n}\n\n/* Hide Golden Layout tab headers when only one tab */\nmj-tab-container.hide-tab-bar ::ng-deep .lm_header {\n display: none;\n}\n\n/* Show tab headers when multiple tabs */\nmj-tab-container:not(.hide-tab-bar) ::ng-deep .lm_header {\n opacity: 1;\n max-height: 40px;\n transition: opacity 0.2s ease-in-out, max-height 0.2s ease-in-out;\n}\n\n/* Adjust content area height when tabs hidden */\nmj-tab-container.hide-tab-bar ::ng-deep .lm_content {\n height: 100% !important;\n}\n\n/* Ensure smooth transitions */\nmj-tab-container ::ng-deep .lm_stack {\n transition: all 0.2s ease-in-out;\n}\n\n.shell-header {\n height: 60px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n display: flex;\n align-items: center;\n padding: 0 16px;\n gap: 16px;\n box-shadow: var(--mj-shadow-sm);\n flex-shrink: 0;\n /* Creates a stacking context so children (search bar z-index: 99999, dropdown)\n are contained within this level. Modal overlays (z-index: 1000+) sit above. */\n position: relative;\n z-index: 500;\n}\n\n/* Nav Bar Apps - permanent app icons in the header */\n.nav-bar-apps {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.nav-bar-apps.left-of-switcher {\n /* No extra margin - header gap handles spacing */\n /* This prevents the app switcher from shifting when icons are hidden */\n}\n\n.nav-bar-apps.left-of-user-menu {\n margin-right: 8px;\n}\n\n.nav-bar-app-btn {\n --app-color: var(--mj-text-muted);\n width: 40px;\n height: 40px;\n border-radius: 10px;\n border: none;\n background: transparent;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-secondary);\n font-size: 18px;\n transition: all 0.15s ease;\n position: relative;\n}\n\n.nav-bar-app-btn:hover {\n background: color-mix(in srgb, var(--app-color) 15%, transparent);\n color: var(--app-color);\n}\n\n.nav-bar-app-btn.active {\n background: color-mix(in srgb, var(--app-color) 20%, transparent);\n color: var(--app-color);\n}\n\n.nav-bar-app-btn.active::after {\n content: '';\n position: absolute;\n bottom: 6px;\n left: 50%;\n transform: translateX(-50%);\n width: 16px;\n height: 3px;\n background: var(--app-color);\n border-radius: 2px;\n}\n\n.nav-bar-app-btn i {\n transition: transform 0.15s ease;\n margin-top: 2px; /* Align with app switcher icon */\n}\n\n.nav-bar-app-btn:hover i {\n transform: scale(1.1);\n}\n\n.spacer {\n flex: 1;\n}\n\n.header-actions {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.icon-btn {\n width: 40px;\n height: 40px;\n border-radius: 50%;\n border: none;\n background: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 18px;\n transition: background 0.15s;\n}\n\n.icon-btn:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n/* Notification button with badge */\n.notification-btn {\n position: relative;\n}\n\n.notification-badge {\n position: absolute;\n top: 4px;\n right: 4px;\n min-width: 16px;\n height: 16px;\n padding: 0 4px;\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n font-size: 10px;\n font-weight: 600;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n}\n\n.user-menu {\n position: relative;\n}\n\n.user-menu .avatar-btn {\n width: 36px;\n height: 36px;\n border-radius: 50%;\n border: none;\n background: transparent;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: box-shadow 0.15s, transform 0.15s;\n padding: 0;\n overflow: hidden;\n}\n\n.user-menu .avatar-btn:hover {\n transform: scale(1.05);\n}\n\n/* Icon fallback styling - shows gray circle with icon */\n.user-menu .avatar-btn .icon-fallback {\n width: 100%;\n height: 100%;\n border-radius: 50%;\n border: 2px solid var(--mj-border-default);\n background: var(--mj-bg-surface-hover);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: border-color 0.15s;\n}\n\n.user-menu .avatar-btn:hover .icon-fallback {\n border-color: var(--mj-brand-primary);\n}\n\n.user-menu .avatar-btn .icon-fallback i {\n color: var(--mj-text-muted);\n font-size: 16px;\n}\n\n/* Avatar image - replaces the gray circle entirely */\n.user-menu .avatar-btn .avatar-img {\n width: 100%;\n height: 100%;\n border-radius: 50%;\n object-fit: cover;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);\n}\n\n.user-menu .avatar-btn:hover .avatar-img {\n box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);\n}\n\n/* User Menu Header */\n.user-menu-header {\n padding: 12px 16px;\n background: var(--mj-bg-surface-sunken);\n}\n\n.user-menu-header .user-info {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.user-menu-header .user-name {\n font-weight: 600;\n font-size: 14px;\n color: var(--mj-text-primary);\n}\n\n.user-menu-header .user-email {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.user-menu-header .user-subtitle {\n font-size: 11px;\n color: var(--mj-text-muted);\n font-style: italic;\n}\n\n/* User Context Menu */\n.user-context-menu {\n position: absolute;\n top: 100%;\n right: 0;\n margin-top: 8px;\n background: var(--mj-bg-surface-elevated);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n box-shadow: var(--mj-shadow-lg);\n min-width: 180px;\n z-index: 10000;\n overflow: hidden;\n}\n\n.user-menu-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px;\n cursor: pointer;\n font-size: 14px;\n color: var(--mj-text-primary);\n transition: background 0.15s;\n}\n\n.user-menu-item i {\n width: 18px;\n text-align: center;\n color: var(--mj-text-muted);\n font-size: 14px;\n}\n\n.user-menu-item:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.user-menu-item.danger {\n color: var(--mj-status-error);\n}\n\n.user-menu-item.danger i {\n color: var(--mj-status-error);\n}\n\n.user-menu-item.danger:hover {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface-elevated));\n}\n\n.user-menu-divider {\n height: 1px;\n background: var(--mj-border-default);\n margin: 4px 0;\n}\n\n/* Menu item disabled state */\n.user-menu-item.disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.user-menu-item.disabled:hover {\n background: transparent;\n}\n\n/* Theme Toggle Switch */\n.theme-toggle-item {\n cursor: pointer;\n}\n\n.theme-toggle-track {\n position: relative;\n width: 40px;\n height: 22px;\n border-radius: 11px;\n background: var(--mj-bg-surface-active);\n margin-left: auto;\n transition: background 0.2s ease;\n flex-shrink: 0;\n}\n\n.theme-toggle-track.dark {\n background: var(--mj-brand-primary);\n}\n\n.theme-toggle-thumb {\n position: absolute;\n top: 2px;\n left: 2px;\n width: 18px;\n height: 18px;\n border-radius: 50%;\n background: var(--mj-bg-surface);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: transform 0.2s ease;\n}\n\n.theme-toggle-track.dark .theme-toggle-thumb {\n transform: translateX(18px);\n}\n\n.theme-toggle-icon {\n font-size: 10px;\n color: var(--mj-text-muted);\n}\n\n.theme-toggle-track.dark .theme-toggle-icon {\n color: var(--mj-text-inverse);\n}\n\n/* Menu shortcut hint */\n.user-menu-item .menu-shortcut {\n margin-left: auto;\n font-size: 11px;\n color: var(--mj-text-disabled);\n font-family: monospace;\n}\n\n/* Menu animations */\n.user-context-menu.menu-fade {\n animation: menuFadeIn 0.15s ease-out;\n}\n\n.user-context-menu.menu-slide {\n animation: menuSlideIn 0.2s ease-out;\n}\n\n@keyframes menuFadeIn {\n from {\n opacity: 0;\n transform: translateY(-8px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n@keyframes menuSlideIn {\n from {\n opacity: 0;\n transform: translateY(-16px) scale(0.95);\n }\n to {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n}\n\n.shell-loading {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100vh;\n padding-bottom: 15vh;\n background: var(--mj-bg-page);\n}\n\n/* Loading Recovery Reset Panel */\n.loading-reset-panel {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--mj-space-3);\n margin-top: var(--mj-space-10);\n padding: var(--mj-space-8);\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-md);\n max-width: 420px;\n animation: resetPanelFadeIn 0.4s ease-out;\n}\n\n.loading-reset-message {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n margin: 0;\n font-size: var(--mj-text-base);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n}\n\n.loading-reset-message i {\n font-size: var(--mj-text-lg);\n color: var(--mj-status-warning);\n}\n\n.loading-reset-hint {\n margin: 0;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-secondary);\n text-align: center;\n line-height: var(--mj-leading-relaxed);\n}\n\n.loading-reset-btn {\n display: inline-flex;\n align-items: center;\n gap: var(--mj-space-2);\n margin-top: var(--mj-space-3);\n padding: var(--mj-space-3) var(--mj-space-6);\n font-size: var(--mj-text-base);\n font-weight: var(--mj-font-medium);\n font-family: var(--mj-font-family);\n color: var(--mj-text-inverse);\n background: var(--mj-brand-primary);\n border: 1px solid var(--mj-brand-primary);\n border-radius: var(--mj-radius-md);\n cursor: pointer;\n transition: var(--mj-transition-colors);\n}\n\n.loading-reset-btn:hover {\n background: var(--mj-brand-primary-hover);\n color: var(--mj-text-inverse);\n border-color: var(--mj-brand-primary-hover);\n box-shadow: var(--mj-shadow-md);\n}\n\n.loading-reset-btn:active {\n background: var(--mj-brand-primary-active);\n color: var(--mj-text-inverse);\n transform: scale(0.98);\n}\n\n.loading-reset-btn i {\n font-size: var(--mj-text-sm);\n}\n\n@keyframes resetPanelFadeIn {\n from {\n opacity: 0;\n transform: translateY(12px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n/* Hamburger button - hidden on desktop */\n.hamburger-btn {\n display: none;\n width: 40px;\n height: 40px;\n border-radius: 8px;\n border: none;\n background: none;\n cursor: pointer;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-secondary);\n font-size: 20px;\n transition: background 0.15s;\n}\n.hamburger-btn:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n/* Mobile Navigation Overlay */\n.mobile-nav-overlay {\n display: none;\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n z-index: 9998;\n}\n\n/* Mobile Navigation Drawer */\n.mobile-nav-drawer {\n display: none;\n position: fixed;\n top: 0;\n left: 0;\n bottom: 0;\n width: 280px;\n max-width: 85vw;\n background: var(--mj-bg-surface);\n box-shadow: var(--mj-shadow-xl);\n z-index: 9999;\n flex-direction: column;\n transform: translateX(-100%);\n transition: transform 0.3s ease;\n}\n.mobile-nav-drawer.open {\n transform: translateX(0);\n}\n\n.mobile-nav-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n}\n.mobile-nav-header span {\n font-weight: 600;\n font-size: 16px;\n color: var(--mj-text-primary);\n}\n.mobile-nav-header .close-btn {\n width: 36px;\n height: 36px;\n border-radius: 50%;\n border: none;\n background: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 18px;\n transition: background 0.15s;\n}\n.mobile-nav-header .close-btn:hover {\n background: var(--mj-bg-surface-active);\n}\n\n.mobile-nav-content {\n flex: 1;\n overflow-y: auto;\n padding: 16px 0;\n}\n\n.mobile-nav-section-title {\n padding: 8px 20px;\n font-size: 12px;\n font-weight: 600;\n color: var(--mj-text-disabled);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.mobile-nav-footer {\n border-top: 1px solid var(--mj-border-default);\n padding: 12px 16px;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.mobile-nav-action {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px;\n border: none;\n background: none;\n cursor: pointer;\n border-radius: 8px;\n color: var(--mj-text-secondary);\n font-size: 14px;\n font-weight: 500;\n transition: background 0.15s;\n width: 100%;\n text-align: left;\n}\n.mobile-nav-action:hover {\n background: var(--mj-bg-surface-hover);\n}\n.mobile-nav-action i {\n font-size: 16px;\n width: 20px;\n text-align: center;\n}\n\n/* Mobile Responsive Styles */\n@media (max-width: 768px) {\n .hamburger-btn {\n display: flex;\n }\n\n .desktop-nav {\n display: none !important;\n }\n\n .desktop-only {\n display: none !important;\n }\n\n .mobile-nav-overlay {\n display: block;\n }\n\n .mobile-nav-drawer {\n display: flex;\n }\n\n .shell-header {\n padding: 0 12px;\n gap: 8px;\n }\n}\n\n/* Settings Full-Screen Window Styles */\n::ng-deep .settings-fullscreen-window {\n /* Remove window chrome for full-screen feel */\n box-shadow: none !important;\n border: none !important;\n}\n\n::ng-deep .settings-fullscreen-window .k-window-titlebar {\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n padding: 12px 16px;\n}\n\n::ng-deep .settings-fullscreen-window .k-window-title {\n font-size: 18px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n::ng-deep .settings-fullscreen-window .k-window-titlebar-actions {\n gap: 4px;\n}\n\n::ng-deep .settings-fullscreen-window .k-window-titlebar-action {\n width: 32px;\n height: 32px;\n border-radius: 6px;\n}\n\n::ng-deep .settings-fullscreen-window .k-window-titlebar-action:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n::ng-deep .settings-fullscreen-window .k-window-content {\n padding: 0;\n overflow: auto;\n background: var(--mj-bg-page);\n}\n\n/* Hide minimize/maximize buttons - only show close */\n::ng-deep .settings-fullscreen-window .k-window-titlebar-action[title=\"Minimize\"],\n::ng-deep .settings-fullscreen-window .k-window-titlebar-action[title=\"Maximize\"],\n::ng-deep .settings-fullscreen-window .k-window-titlebar-action .k-i-window-minimize,\n::ng-deep .settings-fullscreen-window .k-window-titlebar-action .k-i-window-maximize,\n::ng-deep .settings-fullscreen-window .k-window-titlebar-action .k-i-window {\n display: none !important;\n}\n\n/* ========================================\n UNIVERSAL SEARCH BAR\n ======================================== */\n.shell-search-bar {\n flex: 0 1 420px;\n min-width: 200px;\n max-width: 520px;\n margin: 0 12px;\n position: relative;\n z-index: 99999;\n}\n@media (max-width: 768px) {\n .shell-search-bar { display: none; }\n}\n\n/* ========================================\n SEARCH POPUP\n ======================================== */\n\n.search-popup-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.3);\n z-index: 9999;\n animation: fadeIn 0.15s ease;\n}\n\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n.search-popup {\n position: fixed;\n top: 60px; /* Below header */\n right: 16px;\n width: 480px;\n max-width: calc(100vw - 32px);\n background: var(--mj-bg-surface-elevated);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-xl);\n z-index: 10000;\n opacity: 0;\n transform: translateY(-10px);\n pointer-events: none;\n transition: opacity 0.2s ease, transform 0.2s ease;\n}\n\n.search-popup.open {\n opacity: 1;\n transform: translateY(0);\n pointer-events: all;\n}\n\n.search-popup-content {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px;\n}\n\n.search-entity-dropdown {\n min-width: 140px;\n max-width: 180px;\n flex-shrink: 0;\n}\n\n.search-input {\n flex: 1;\n min-width: 0;\n height: 40px;\n padding: 8px 12px;\n font-size: 14px;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n outline: none;\n display: block !important;\n box-sizing: border-box;\n}\n\n.search-input:focus {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.search-submit-btn {\n width: 40px;\n height: 40px;\n border-radius: 8px;\n border: none;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 16px;\n transition: background 0.15s;\n flex-shrink: 0;\n}\n\n.search-submit-btn:hover {\n background: var(--mj-brand-primary-hover);\n}\n\n.search-submit-btn:active {\n background: var(--mj-brand-primary-hover);\n}\n\n/* Mobile notification badge */\n.notification-badge-mobile {\n position: absolute;\n top: 8px;\n right: 8px;\n min-width: 18px;\n height: 18px;\n padding: 0 5px;\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n font-size: 11px;\n font-weight: 600;\n border-radius: 9px;\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n}\n\n/* Mobile-specific search popup adjustments */\n@media (max-width: 768px) {\n .search-popup {\n top: 60px;\n left: 16px;\n right: 16px;\n width: auto;\n max-width: none;\n }\n\n .search-popup-content {\n flex-wrap: wrap;\n }\n\n .search-entity-dropdown {\n width: 100%;\n }\n\n .search-input {\n flex: 1;\n min-width: 0;\n }\n}\n\n/* ========================================\n PIN PROGRESS OVERLAY\n ======================================== */\n.pin-progress-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: color-mix(in srgb, var(--mj-text-primary) 40%, transparent);\n z-index: 100000;\n display: flex;\n align-items: center;\n justify-content: center;\n animation: pinBackdropIn 0.2s ease;\n}\n\n@keyframes pinBackdropIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n.pin-progress-modal {\n background: var(--mj-bg-surface);\n border-radius: var(--mj-radius-xl);\n padding: 28px 40px;\n display: flex;\n align-items: center;\n gap: 16px;\n box-shadow: 0 16px 48px color-mix(in srgb, var(--mj-text-primary) 30%, transparent);\n animation: pinModalIn 0.25s ease;\n}\n\n@keyframes pinModalIn {\n from { opacity: 0; transform: scale(0.9) translateY(8px); }\n to { opacity: 1; transform: scale(1) translateY(0); }\n}\n\n.pin-progress-text {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-medium);\n color: var(--mj-text-secondary);\n white-space: nowrap;\n}"] }]
2918
+ }], () => [{ type: i1.ApplicationManager }, { type: i1.WorkspaceStateManager }, { type: i1.GoldenLayoutManager }, { type: i1.TabService }, { type: i2.NavigationService }, { type: i3.ActivatedRoute }, { type: i3.Router }, { type: i4.MJAuthBase }, { type: i0.ChangeDetectorRef }, { type: i5.UserAvatarService }, { type: i6.SettingsDialogService }, { type: i0.ViewContainerRef }, { type: i2.TitleService }, { type: i2.DeveloperModeService }, { type: i7.CommandPaletteService }, { type: i2.ThemeService }, { type: i2.HomeAppPinService }, { type: i8.FileOpenService }], { searchInput: [{
2728
2919
  type: ViewChild,
2729
2920
  args: ['searchInput']
2921
+ }], shellSearchComposite: [{
2922
+ type: ViewChild,
2923
+ args: ['shellSearchComposite']
2730
2924
  }], tabContainerRef: [{
2731
2925
  type: ViewChild,
2732
2926
  args: [TabContainerComponent]
@@ -2736,6 +2930,9 @@ export class ShellComponent {
2736
2930
  }], handleGlobalKeyboardShortcuts: [{
2737
2931
  type: HostListener,
2738
2932
  args: ['document:keydown', ['$event']]
2933
+ }], OnGlobalKeydown: [{
2934
+ type: HostListener,
2935
+ args: ['document:keydown', ['$event']]
2739
2936
  }] }); })();
2740
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ShellComponent, { className: "ShellComponent", filePath: "src/lib/shell/shell.component.ts", lineNumber: 46 }); })();
2937
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ShellComponent, { className: "ShellComponent", filePath: "src/lib/shell/shell.component.ts", lineNumber: 47 }); })();
2741
2938
  //# sourceMappingURL=shell.component.js.map