@memberjunction/ng-explorer-core 5.38.0 → 5.40.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.
- package/dist/app-routing.module.d.ts.map +1 -1
- package/dist/app-routing.module.js +13 -13
- package/dist/app-routing.module.js.map +1 -1
- package/dist/generated/lazy-feature-config.d.ts +1 -1
- package/dist/generated/lazy-feature-config.d.ts.map +1 -1
- package/dist/generated/lazy-feature-config.js +3 -2
- package/dist/generated/lazy-feature-config.js.map +1 -1
- package/dist/lib/guards/app-lock-guard.service.d.ts +26 -0
- package/dist/lib/guards/app-lock-guard.service.d.ts.map +1 -0
- package/dist/lib/guards/app-lock-guard.service.js +55 -0
- package/dist/lib/guards/app-lock-guard.service.js.map +1 -0
- package/dist/lib/resource-wrappers/chat-conversations-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/chat-conversations-resource.component.js +40 -27
- package/dist/lib/resource-wrappers/chat-conversations-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/view-resource.component.d.ts +6 -5
- package/dist/lib/resource-wrappers/view-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/view-resource.component.js +19 -24
- package/dist/lib/resource-wrappers/view-resource.component.js.map +1 -1
- package/dist/lib/shell/components/tabs/tab-container.component.d.ts.map +1 -1
- package/dist/lib/shell/components/tabs/tab-container.component.js +9 -0
- package/dist/lib/shell/components/tabs/tab-container.component.js.map +1 -1
- package/dist/lib/shell/shell.component.d.ts +24 -6
- package/dist/lib/shell/shell.component.d.ts.map +1 -1
- package/dist/lib/shell/shell.component.js +360 -191
- package/dist/lib/shell/shell.component.js.map +1 -1
- package/dist/lib/single-record/single-record.component.d.ts +31 -75
- package/dist/lib/single-record/single-record.component.d.ts.map +1 -1
- package/dist/lib/single-record/single-record.component.js +60 -471
- package/dist/lib/single-record/single-record.component.js.map +1 -1
- package/dist/lib/single-search-result/single-search-result.component.d.ts +3 -8
- package/dist/lib/single-search-result/single-search-result.component.d.ts.map +1 -1
- package/dist/lib/single-search-result/single-search-result.component.js +19 -68
- package/dist/lib/single-search-result/single-search-result.component.js.map +1 -1
- package/dist/public-api.d.ts +1 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +1 -0
- package/dist/public-api.js.map +1 -1
- package/package.json +46 -46
- package/dist/lib/__tests__/form-resolver.service.test.d.ts +0 -2
- package/dist/lib/__tests__/form-resolver.service.test.d.ts.map +0 -1
- package/dist/lib/__tests__/form-resolver.service.test.js +0 -258
- package/dist/lib/__tests__/form-resolver.service.test.js.map +0 -1
- package/dist/lib/services/form-resolver.service.d.ts +0 -139
- package/dist/lib/services/form-resolver.service.d.ts.map +0 -1
- package/dist/lib/services/form-resolver.service.js +0 -235
- package/dist/lib/services/form-resolver.service.js.map +0 -1
|
@@ -37,9 +37,10 @@ import * as i21 from "../command-palette/command-palette.component";
|
|
|
37
37
|
const _c0 = ["searchInput"];
|
|
38
38
|
const _c1 = ["shellSearchComposite"];
|
|
39
39
|
const _c2 = ["appAccessDialog"];
|
|
40
|
+
const _forTrack0 = ($index, $item) => $item.ID;
|
|
40
41
|
function ShellComponent_Conditional_5_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
41
42
|
const _r2 = i0.ɵɵgetCurrentView();
|
|
42
|
-
i0.ɵɵelementStart(0, "button",
|
|
43
|
+
i0.ɵɵelementStart(0, "button", 47);
|
|
43
44
|
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)); });
|
|
44
45
|
i0.ɵɵelement(1, "i");
|
|
45
46
|
i0.ɵɵelementEnd();
|
|
@@ -54,34 +55,128 @@ function ShellComponent_Conditional_5_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
|
54
55
|
} }
|
|
55
56
|
function ShellComponent_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
56
57
|
i0.ɵɵelementStart(0, "div", 8);
|
|
57
|
-
i0.ɵɵrepeaterCreate(1, ShellComponent_Conditional_5_For_2_Template, 2, 7, "button",
|
|
58
|
+
i0.ɵɵrepeaterCreate(1, ShellComponent_Conditional_5_For_2_Template, 2, 7, "button", 46, i0.ɵɵrepeaterTrackByIdentity);
|
|
58
59
|
i0.ɵɵelementEnd();
|
|
59
60
|
} if (rf & 2) {
|
|
60
61
|
const ctx_r3 = i0.ɵɵnextContext();
|
|
61
62
|
i0.ɵɵadvance();
|
|
62
63
|
i0.ɵɵrepeater(ctx_r3.leftOfSwitcherApps);
|
|
63
64
|
} }
|
|
64
|
-
function
|
|
65
|
+
function ShellComponent_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
65
66
|
const _r5 = i0.ɵɵgetCurrentView();
|
|
66
|
-
i0.ɵɵelementStart(0, "mj-app-
|
|
67
|
-
i0.ɵɵlistener("
|
|
67
|
+
i0.ɵɵelementStart(0, "mj-app-switcher", 48);
|
|
68
|
+
i0.ɵɵlistener("appSelected", function ShellComponent_Conditional_6_Template_mj_app_switcher_appSelected_0_listener($event) { i0.ɵɵrestoreView(_r5); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onAppSwitch($event)); });
|
|
69
|
+
i0.ɵɵelementEnd();
|
|
70
|
+
} if (rf & 2) {
|
|
71
|
+
const ctx_r3 = i0.ɵɵnextContext();
|
|
72
|
+
i0.ɵɵproperty("activeApp", ctx_r3.activeApp)("isViewingSystemTab", ctx_r3.isViewingSystemTab)("loadingAppId", ctx_r3.loadingAppId);
|
|
73
|
+
} }
|
|
74
|
+
function ShellComponent_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
75
|
+
const _r6 = i0.ɵɵgetCurrentView();
|
|
76
|
+
i0.ɵɵelementStart(0, "mj-app-nav", 49);
|
|
77
|
+
i0.ɵɵlistener("navItemClick", function ShellComponent_Conditional_7_Template_mj_app_nav_navItemClick_0_listener($event) { i0.ɵɵrestoreView(_r6); 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(_r6); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onNavItemDismiss($event)); });
|
|
68
78
|
i0.ɵɵelementEnd();
|
|
69
79
|
} if (rf & 2) {
|
|
70
80
|
const ctx_r3 = i0.ɵɵnextContext();
|
|
71
81
|
i0.ɵɵproperty("app", ctx_r3.activeApp);
|
|
72
82
|
} }
|
|
73
83
|
function ShellComponent_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
74
|
-
const
|
|
75
|
-
i0.ɵɵelementStart(0, "div", 11)(1, "mj-search-composite",
|
|
76
|
-
i0.ɵɵlistener("ResultSelected", function ShellComponent_Conditional_8_Template_mj_search_composite_ResultSelected_1_listener($event) { i0.ɵɵrestoreView(
|
|
84
|
+
const _r7 = i0.ɵɵgetCurrentView();
|
|
85
|
+
i0.ɵɵelementStart(0, "div", 11)(1, "mj-search-composite", 50, 2);
|
|
86
|
+
i0.ɵɵlistener("ResultSelected", function ShellComponent_Conditional_8_Template_mj_search_composite_ResultSelected_1_listener($event) { i0.ɵɵrestoreView(_r7); 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(_r7); 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(_r7); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.OnSeeAllSearch($event)); });
|
|
77
87
|
i0.ɵɵelementEnd()();
|
|
78
88
|
} if (rf & 2) {
|
|
79
89
|
const ctx_r3 = i0.ɵɵnextContext();
|
|
80
90
|
i0.ɵɵadvance();
|
|
81
91
|
i0.ɵɵproperty("ShowShortcutHint", true)("EnablePreview", ctx_r3.ShowSearchPreview)("EnableRecent", true)("MaxPreviewResults", 8);
|
|
82
92
|
} }
|
|
83
|
-
function
|
|
84
|
-
i0.ɵɵelementStart(0, "span",
|
|
93
|
+
function ShellComponent_Conditional_11_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
94
|
+
i0.ɵɵelementStart(0, "span", 53);
|
|
95
|
+
i0.ɵɵtext(1);
|
|
96
|
+
i0.ɵɵelementEnd();
|
|
97
|
+
} if (rf & 2) {
|
|
98
|
+
const ctx_r3 = i0.ɵɵnextContext(2);
|
|
99
|
+
i0.ɵɵadvance();
|
|
100
|
+
i0.ɵɵtextInterpolate(ctx_r3.activityRunningCount);
|
|
101
|
+
} }
|
|
102
|
+
function ShellComponent_Conditional_11_Conditional_4_For_8_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
103
|
+
i0.ɵɵelementStart(0, "div", 65);
|
|
104
|
+
i0.ɵɵtext(1);
|
|
105
|
+
i0.ɵɵelementEnd();
|
|
106
|
+
} if (rf & 2) {
|
|
107
|
+
const a_r10 = i0.ɵɵnextContext().$implicit;
|
|
108
|
+
i0.ɵɵadvance();
|
|
109
|
+
i0.ɵɵtextInterpolate(a_r10.Detail);
|
|
110
|
+
} }
|
|
111
|
+
function ShellComponent_Conditional_11_Conditional_4_For_8_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
112
|
+
i0.ɵɵelementStart(0, "div", 66);
|
|
113
|
+
i0.ɵɵelement(1, "div", 67);
|
|
114
|
+
i0.ɵɵelementEnd();
|
|
115
|
+
} if (rf & 2) {
|
|
116
|
+
const a_r10 = i0.ɵɵnextContext().$implicit;
|
|
117
|
+
i0.ɵɵadvance();
|
|
118
|
+
i0.ɵɵstyleProp("width", a_r10.Progress, "%");
|
|
119
|
+
} }
|
|
120
|
+
function ShellComponent_Conditional_11_Conditional_4_For_8_Template(rf, ctx) { if (rf & 1) {
|
|
121
|
+
i0.ɵɵelementStart(0, "div", 61);
|
|
122
|
+
i0.ɵɵelement(1, "i", 62);
|
|
123
|
+
i0.ɵɵelementStart(2, "div", 63)(3, "div", 64);
|
|
124
|
+
i0.ɵɵtext(4);
|
|
125
|
+
i0.ɵɵelementEnd();
|
|
126
|
+
i0.ɵɵconditionalCreate(5, ShellComponent_Conditional_11_Conditional_4_For_8_Conditional_5_Template, 2, 1, "div", 65);
|
|
127
|
+
i0.ɵɵconditionalCreate(6, ShellComponent_Conditional_11_Conditional_4_For_8_Conditional_6_Template, 2, 2, "div", 66);
|
|
128
|
+
i0.ɵɵelementEnd()();
|
|
129
|
+
} if (rf & 2) {
|
|
130
|
+
const a_r10 = ctx.$implicit;
|
|
131
|
+
i0.ɵɵclassProp("is-error", a_r10.Status === "error");
|
|
132
|
+
i0.ɵɵadvance();
|
|
133
|
+
i0.ɵɵclassMap(a_r10.Status === "running" ? "fa-solid fa-spinner fa-spin" : a_r10.Status === "error" ? "fa-solid fa-circle-exclamation" : "fa-solid fa-circle-check");
|
|
134
|
+
i0.ɵɵadvance(3);
|
|
135
|
+
i0.ɵɵtextInterpolate(a_r10.Label);
|
|
136
|
+
i0.ɵɵadvance();
|
|
137
|
+
i0.ɵɵconditional(a_r10.Detail ? 5 : -1);
|
|
138
|
+
i0.ɵɵadvance();
|
|
139
|
+
i0.ɵɵconditional(a_r10.Status === "running" && a_r10.Progress != null ? 6 : -1);
|
|
140
|
+
} }
|
|
141
|
+
function ShellComponent_Conditional_11_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
142
|
+
const _r9 = i0.ɵɵgetCurrentView();
|
|
143
|
+
i0.ɵɵelementStart(0, "div", 55);
|
|
144
|
+
i0.ɵɵlistener("click", function ShellComponent_Conditional_11_Conditional_4_Template_div_click_0_listener($event) { i0.ɵɵrestoreView(_r9); return i0.ɵɵresetView($event.stopPropagation()); });
|
|
145
|
+
i0.ɵɵelementStart(1, "div", 56)(2, "span");
|
|
146
|
+
i0.ɵɵtext(3, "Activity");
|
|
147
|
+
i0.ɵɵelementEnd();
|
|
148
|
+
i0.ɵɵelementStart(4, "button", 57);
|
|
149
|
+
i0.ɵɵlistener("click", function ShellComponent_Conditional_11_Conditional_4_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r9); const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.clearFinishedActivity()); });
|
|
150
|
+
i0.ɵɵelement(5, "i", 58);
|
|
151
|
+
i0.ɵɵelementEnd()();
|
|
152
|
+
i0.ɵɵelementStart(6, "div", 59);
|
|
153
|
+
i0.ɵɵrepeaterCreate(7, ShellComponent_Conditional_11_Conditional_4_For_8_Template, 7, 7, "div", 60, _forTrack0);
|
|
154
|
+
i0.ɵɵelementEnd()();
|
|
155
|
+
} if (rf & 2) {
|
|
156
|
+
const ctx_r3 = i0.ɵɵnextContext(2);
|
|
157
|
+
i0.ɵɵadvance(7);
|
|
158
|
+
i0.ɵɵrepeater(ctx_r3.activityItems);
|
|
159
|
+
} }
|
|
160
|
+
function ShellComponent_Conditional_11_Template(rf, ctx) { if (rf & 1) {
|
|
161
|
+
const _r8 = i0.ɵɵgetCurrentView();
|
|
162
|
+
i0.ɵɵelementStart(0, "div", 14)(1, "button", 51);
|
|
163
|
+
i0.ɵɵlistener("click", function ShellComponent_Conditional_11_Template_button_click_1_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.toggleActivity($event)); });
|
|
164
|
+
i0.ɵɵelement(2, "i", 52);
|
|
165
|
+
i0.ɵɵconditionalCreate(3, ShellComponent_Conditional_11_Conditional_3_Template, 2, 1, "span", 53);
|
|
166
|
+
i0.ɵɵelementEnd();
|
|
167
|
+
i0.ɵɵconditionalCreate(4, ShellComponent_Conditional_11_Conditional_4_Template, 9, 0, "div", 54);
|
|
168
|
+
i0.ɵɵelementEnd();
|
|
169
|
+
} if (rf & 2) {
|
|
170
|
+
const ctx_r3 = i0.ɵɵnextContext();
|
|
171
|
+
i0.ɵɵadvance(2);
|
|
172
|
+
i0.ɵɵclassProp("activity-pulse", ctx_r3.activityRunningCount > 0);
|
|
173
|
+
i0.ɵɵadvance();
|
|
174
|
+
i0.ɵɵconditional(ctx_r3.activityRunningCount > 0 ? 3 : -1);
|
|
175
|
+
i0.ɵɵadvance();
|
|
176
|
+
i0.ɵɵconditional(ctx_r3.activityOpen ? 4 : -1);
|
|
177
|
+
} }
|
|
178
|
+
function ShellComponent_Conditional_14_Template(rf, ctx) { if (rf & 1) {
|
|
179
|
+
i0.ɵɵelementStart(0, "span", 17);
|
|
85
180
|
i0.ɵɵtext(1);
|
|
86
181
|
i0.ɵɵelementEnd();
|
|
87
182
|
} if (rf & 2) {
|
|
@@ -89,38 +184,38 @@ function ShellComponent_Conditional_13_Template(rf, ctx) { if (rf & 1) {
|
|
|
89
184
|
i0.ɵɵadvance();
|
|
90
185
|
i0.ɵɵtextInterpolate1(" ", ctx_r3.unreadNotificationCount > 99 ? "99+" : ctx_r3.unreadNotificationCount, " ");
|
|
91
186
|
} }
|
|
92
|
-
function
|
|
93
|
-
const
|
|
94
|
-
i0.ɵɵelementStart(0, "button",
|
|
95
|
-
i0.ɵɵlistener("click", function
|
|
187
|
+
function ShellComponent_Conditional_15_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
188
|
+
const _r11 = i0.ɵɵgetCurrentView();
|
|
189
|
+
i0.ɵɵelementStart(0, "button", 47);
|
|
190
|
+
i0.ɵɵlistener("click", function ShellComponent_Conditional_15_For_2_Template_button_click_0_listener($event) { const app_r12 = i0.ɵɵrestoreView(_r11).$implicit; const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.onNavBarAppClick(app_r12, $event)); })("dblclick", function ShellComponent_Conditional_15_For_2_Template_button_dblclick_0_listener($event) { const app_r12 = i0.ɵɵrestoreView(_r11).$implicit; const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.onNavBarAppDblClick(app_r12, $event)); });
|
|
96
191
|
i0.ɵɵelement(1, "i");
|
|
97
192
|
i0.ɵɵelementEnd();
|
|
98
193
|
} if (rf & 2) {
|
|
99
|
-
const
|
|
194
|
+
const app_r12 = ctx.$implicit;
|
|
100
195
|
const ctx_r3 = i0.ɵɵnextContext(2);
|
|
101
|
-
i0.ɵɵstyleProp("--app-color",
|
|
102
|
-
i0.ɵɵclassProp("active", ctx_r3.IsActiveApp(
|
|
103
|
-
i0.ɵɵproperty("title",
|
|
196
|
+
i0.ɵɵstyleProp("--app-color", app_r12.GetColor());
|
|
197
|
+
i0.ɵɵclassProp("active", ctx_r3.IsActiveApp(app_r12));
|
|
198
|
+
i0.ɵɵproperty("title", app_r12.Name);
|
|
104
199
|
i0.ɵɵadvance();
|
|
105
|
-
i0.ɵɵclassMap(
|
|
200
|
+
i0.ɵɵclassMap(app_r12.Icon);
|
|
106
201
|
} }
|
|
107
|
-
function
|
|
108
|
-
i0.ɵɵelementStart(0, "div",
|
|
109
|
-
i0.ɵɵrepeaterCreate(1,
|
|
202
|
+
function ShellComponent_Conditional_15_Template(rf, ctx) { if (rf & 1) {
|
|
203
|
+
i0.ɵɵelementStart(0, "div", 18);
|
|
204
|
+
i0.ɵɵrepeaterCreate(1, ShellComponent_Conditional_15_For_2_Template, 2, 7, "button", 46, i0.ɵɵrepeaterTrackByIdentity);
|
|
110
205
|
i0.ɵɵelementEnd();
|
|
111
206
|
} if (rf & 2) {
|
|
112
207
|
const ctx_r3 = i0.ɵɵnextContext();
|
|
113
208
|
i0.ɵɵadvance();
|
|
114
209
|
i0.ɵɵrepeater(ctx_r3.leftOfUserMenuApps);
|
|
115
210
|
} }
|
|
116
|
-
function
|
|
117
|
-
i0.ɵɵelement(0, "img",
|
|
211
|
+
function ShellComponent_Conditional_18_Template(rf, ctx) { if (rf & 1) {
|
|
212
|
+
i0.ɵɵelement(0, "img", 21);
|
|
118
213
|
} if (rf & 2) {
|
|
119
214
|
const ctx_r3 = i0.ɵɵnextContext();
|
|
120
215
|
i0.ɵɵproperty("src", ctx_r3.userImageURL, i0.ɵɵsanitizeUrl);
|
|
121
216
|
} }
|
|
122
|
-
function
|
|
123
|
-
i0.ɵɵelementStart(0, "div",
|
|
217
|
+
function ShellComponent_Conditional_19_Template(rf, ctx) { if (rf & 1) {
|
|
218
|
+
i0.ɵɵelementStart(0, "div", 22);
|
|
124
219
|
i0.ɵɵelement(1, "i");
|
|
125
220
|
i0.ɵɵelementEnd();
|
|
126
221
|
} if (rf & 2) {
|
|
@@ -128,8 +223,8 @@ function ShellComponent_Conditional_18_Template(rf, ctx) { if (rf & 1) {
|
|
|
128
223
|
i0.ɵɵadvance();
|
|
129
224
|
i0.ɵɵclassMap(ctx_r3.userIconClass || "fa-solid fa-user");
|
|
130
225
|
} }
|
|
131
|
-
function
|
|
132
|
-
i0.ɵɵelementStart(0, "span",
|
|
226
|
+
function ShellComponent_Conditional_20_Conditional_1_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
227
|
+
i0.ɵɵelementStart(0, "span", 72);
|
|
133
228
|
i0.ɵɵtext(1);
|
|
134
229
|
i0.ɵɵelementEnd();
|
|
135
230
|
} if (rf & 2) {
|
|
@@ -138,8 +233,8 @@ function ShellComponent_Conditional_19_Conditional_1_Conditional_4_Template(rf,
|
|
|
138
233
|
i0.ɵɵadvance();
|
|
139
234
|
i0.ɵɵtextInterpolate1(" ", (tmp_5_0 = ctx_r3.getUserDisplayInfo()) == null ? null : tmp_5_0.email, " ");
|
|
140
235
|
} }
|
|
141
|
-
function
|
|
142
|
-
i0.ɵɵelementStart(0, "span",
|
|
236
|
+
function ShellComponent_Conditional_20_Conditional_1_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
237
|
+
i0.ɵɵelementStart(0, "span", 73);
|
|
143
238
|
i0.ɵɵtext(1);
|
|
144
239
|
i0.ɵɵelementEnd();
|
|
145
240
|
} if (rf & 2) {
|
|
@@ -148,14 +243,14 @@ function ShellComponent_Conditional_19_Conditional_1_Conditional_5_Template(rf,
|
|
|
148
243
|
i0.ɵɵadvance();
|
|
149
244
|
i0.ɵɵtextInterpolate((tmp_5_0 = ctx_r3.getUserDisplayInfo()) == null ? null : tmp_5_0.subtitle);
|
|
150
245
|
} }
|
|
151
|
-
function
|
|
152
|
-
i0.ɵɵelementStart(0, "div",
|
|
246
|
+
function ShellComponent_Conditional_20_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
247
|
+
i0.ɵɵelementStart(0, "div", 69)(1, "div", 70)(2, "span", 71);
|
|
153
248
|
i0.ɵɵtext(3);
|
|
154
249
|
i0.ɵɵelementEnd();
|
|
155
|
-
i0.ɵɵconditionalCreate(4,
|
|
156
|
-
i0.ɵɵconditionalCreate(5,
|
|
250
|
+
i0.ɵɵconditionalCreate(4, ShellComponent_Conditional_20_Conditional_1_Conditional_4_Template, 2, 1, "span", 72);
|
|
251
|
+
i0.ɵɵconditionalCreate(5, ShellComponent_Conditional_20_Conditional_1_Conditional_5_Template, 2, 1, "span", 73);
|
|
157
252
|
i0.ɵɵelementEnd()();
|
|
158
|
-
i0.ɵɵelement(6, "div",
|
|
253
|
+
i0.ɵɵelement(6, "div", 74);
|
|
159
254
|
} if (rf & 2) {
|
|
160
255
|
let tmp_4_0;
|
|
161
256
|
let tmp_5_0;
|
|
@@ -168,91 +263,91 @@ function ShellComponent_Conditional_19_Conditional_1_Template(rf, ctx) { if (rf
|
|
|
168
263
|
i0.ɵɵadvance();
|
|
169
264
|
i0.ɵɵconditional(((tmp_6_0 = ctx_r3.getUserDisplayInfo()) == null ? null : tmp_6_0.subtitle) ? 5 : -1);
|
|
170
265
|
} }
|
|
171
|
-
function
|
|
172
|
-
i0.ɵɵelement(0, "div",
|
|
266
|
+
function ShellComponent_Conditional_20_For_3_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
267
|
+
i0.ɵɵelement(0, "div", 74);
|
|
173
268
|
} }
|
|
174
|
-
function
|
|
175
|
-
const
|
|
176
|
-
i0.ɵɵelementStart(0, "div",
|
|
177
|
-
i0.ɵɵlistener("click", function
|
|
269
|
+
function ShellComponent_Conditional_20_For_3_Conditional_1_Conditional_0_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
270
|
+
const _r13 = i0.ɵɵgetCurrentView();
|
|
271
|
+
i0.ɵɵelementStart(0, "div", 77);
|
|
272
|
+
i0.ɵɵlistener("click", function ShellComponent_Conditional_20_For_3_Conditional_1_Conditional_0_Conditional_0_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r13); const item_r14 = i0.ɵɵnextContext(); const ctx_r3 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r3.onUserMenuItemClick(item_r14.id)); });
|
|
178
273
|
i0.ɵɵelement(1, "i");
|
|
179
|
-
i0.ɵɵelementStart(2, "span",
|
|
274
|
+
i0.ɵɵelementStart(2, "span", 78);
|
|
180
275
|
i0.ɵɵtext(3);
|
|
181
276
|
i0.ɵɵelementEnd();
|
|
182
|
-
i0.ɵɵelementStart(4, "div",
|
|
183
|
-
i0.ɵɵelement(6, "i",
|
|
277
|
+
i0.ɵɵelementStart(4, "div", 79)(5, "div", 80);
|
|
278
|
+
i0.ɵɵelement(6, "i", 81);
|
|
184
279
|
i0.ɵɵelementEnd()()();
|
|
185
280
|
} if (rf & 2) {
|
|
186
|
-
const
|
|
281
|
+
const item_r14 = i0.ɵɵnextContext();
|
|
187
282
|
const ctx_r3 = i0.ɵɵnextContext(4);
|
|
188
|
-
i0.ɵɵproperty("title",
|
|
283
|
+
i0.ɵɵproperty("title", item_r14.tooltip || "");
|
|
189
284
|
i0.ɵɵadvance();
|
|
190
|
-
i0.ɵɵclassMap(
|
|
285
|
+
i0.ɵɵclassMap(item_r14.icon);
|
|
191
286
|
i0.ɵɵadvance(2);
|
|
192
|
-
i0.ɵɵtextInterpolate(
|
|
287
|
+
i0.ɵɵtextInterpolate(item_r14.label);
|
|
193
288
|
i0.ɵɵadvance();
|
|
194
289
|
i0.ɵɵclassProp("dark", ctx_r3.IsDarkMode);
|
|
195
290
|
i0.ɵɵadvance(2);
|
|
196
291
|
i0.ɵɵclassMap(ctx_r3.IsDarkMode ? "fa-solid fa-moon" : "fa-solid fa-sun");
|
|
197
292
|
} }
|
|
198
|
-
function
|
|
199
|
-
i0.ɵɵelementStart(0, "span",
|
|
293
|
+
function ShellComponent_Conditional_20_For_3_Conditional_1_Conditional_0_Conditional_1_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
294
|
+
i0.ɵɵelementStart(0, "span", 83);
|
|
200
295
|
i0.ɵɵtext(1);
|
|
201
296
|
i0.ɵɵelementEnd();
|
|
202
297
|
} if (rf & 2) {
|
|
203
|
-
const
|
|
298
|
+
const item_r14 = i0.ɵɵnextContext(2);
|
|
204
299
|
i0.ɵɵadvance();
|
|
205
|
-
i0.ɵɵtextInterpolate(
|
|
300
|
+
i0.ɵɵtextInterpolate(item_r14.shortcut);
|
|
206
301
|
} }
|
|
207
|
-
function
|
|
208
|
-
const
|
|
209
|
-
i0.ɵɵelementStart(0, "div",
|
|
210
|
-
i0.ɵɵlistener("click", function
|
|
302
|
+
function ShellComponent_Conditional_20_For_3_Conditional_1_Conditional_0_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
303
|
+
const _r15 = i0.ɵɵgetCurrentView();
|
|
304
|
+
i0.ɵɵelementStart(0, "div", 82);
|
|
305
|
+
i0.ɵɵlistener("click", function ShellComponent_Conditional_20_For_3_Conditional_1_Conditional_0_Conditional_1_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r15); const item_r14 = i0.ɵɵnextContext(); const ctx_r3 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(item_r14.enabled && ctx_r3.onUserMenuItemClick(item_r14.id)); });
|
|
211
306
|
i0.ɵɵelement(1, "i");
|
|
212
|
-
i0.ɵɵelementStart(2, "span",
|
|
307
|
+
i0.ɵɵelementStart(2, "span", 78);
|
|
213
308
|
i0.ɵɵtext(3);
|
|
214
309
|
i0.ɵɵelementEnd();
|
|
215
|
-
i0.ɵɵconditionalCreate(4,
|
|
310
|
+
i0.ɵɵconditionalCreate(4, ShellComponent_Conditional_20_For_3_Conditional_1_Conditional_0_Conditional_1_Conditional_4_Template, 2, 1, "span", 83);
|
|
216
311
|
i0.ɵɵelementEnd();
|
|
217
312
|
} if (rf & 2) {
|
|
218
|
-
const
|
|
219
|
-
i0.ɵɵstyleProp("color",
|
|
220
|
-
i0.ɵɵclassProp("disabled", !
|
|
221
|
-
i0.ɵɵproperty("title",
|
|
313
|
+
const item_r14 = i0.ɵɵnextContext();
|
|
314
|
+
i0.ɵɵstyleProp("color", item_r14.color || null);
|
|
315
|
+
i0.ɵɵclassProp("disabled", !item_r14.enabled)("danger", item_r14.cssClass === "danger");
|
|
316
|
+
i0.ɵɵproperty("title", item_r14.tooltip || "");
|
|
222
317
|
i0.ɵɵadvance();
|
|
223
|
-
i0.ɵɵclassMap(
|
|
318
|
+
i0.ɵɵclassMap(item_r14.icon);
|
|
224
319
|
i0.ɵɵadvance(2);
|
|
225
|
-
i0.ɵɵtextInterpolate(
|
|
320
|
+
i0.ɵɵtextInterpolate(item_r14.label);
|
|
226
321
|
i0.ɵɵadvance();
|
|
227
|
-
i0.ɵɵconditional(
|
|
322
|
+
i0.ɵɵconditional(item_r14.shortcut ? 4 : -1);
|
|
228
323
|
} }
|
|
229
|
-
function
|
|
230
|
-
i0.ɵɵconditionalCreate(0,
|
|
324
|
+
function ShellComponent_Conditional_20_For_3_Conditional_1_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
325
|
+
i0.ɵɵconditionalCreate(0, ShellComponent_Conditional_20_For_3_Conditional_1_Conditional_0_Conditional_0_Template, 7, 8, "div", 75)(1, ShellComponent_Conditional_20_For_3_Conditional_1_Conditional_0_Conditional_1_Template, 5, 11, "div", 76);
|
|
231
326
|
} if (rf & 2) {
|
|
232
327
|
i0.ɵɵconditional(ctx.id === "toggle-theme" ? 0 : 1);
|
|
233
328
|
} }
|
|
234
|
-
function
|
|
235
|
-
i0.ɵɵconditionalCreate(0,
|
|
329
|
+
function ShellComponent_Conditional_20_For_3_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
330
|
+
i0.ɵɵconditionalCreate(0, ShellComponent_Conditional_20_For_3_Conditional_1_Conditional_0_Template, 2, 1);
|
|
236
331
|
} if (rf & 2) {
|
|
237
332
|
let tmp_14_0;
|
|
238
|
-
const
|
|
333
|
+
const element_r16 = i0.ɵɵnextContext().$implicit;
|
|
239
334
|
const ctx_r3 = i0.ɵɵnextContext(2);
|
|
240
|
-
i0.ɵɵconditional((tmp_14_0 = ctx_r3.asMenuItem(
|
|
335
|
+
i0.ɵɵconditional((tmp_14_0 = ctx_r3.asMenuItem(element_r16)) ? 0 : -1, tmp_14_0);
|
|
241
336
|
} }
|
|
242
|
-
function
|
|
243
|
-
i0.ɵɵconditionalCreate(0,
|
|
244
|
-
i0.ɵɵconditionalCreate(1,
|
|
337
|
+
function ShellComponent_Conditional_20_For_3_Template(rf, ctx) { if (rf & 1) {
|
|
338
|
+
i0.ɵɵconditionalCreate(0, ShellComponent_Conditional_20_For_3_Conditional_0_Template, 1, 0, "div", 74);
|
|
339
|
+
i0.ɵɵconditionalCreate(1, ShellComponent_Conditional_20_For_3_Conditional_1_Template, 1, 1);
|
|
245
340
|
} if (rf & 2) {
|
|
246
|
-
const
|
|
341
|
+
const element_r16 = ctx.$implicit;
|
|
247
342
|
const ctx_r3 = i0.ɵɵnextContext(2);
|
|
248
|
-
i0.ɵɵconditional(ctx_r3.isMenuDivider(
|
|
343
|
+
i0.ɵɵconditional(ctx_r3.isMenuDivider(element_r16) ? 0 : -1);
|
|
249
344
|
i0.ɵɵadvance();
|
|
250
|
-
i0.ɵɵconditional(!ctx_r3.isMenuDivider(
|
|
345
|
+
i0.ɵɵconditional(!ctx_r3.isMenuDivider(element_r16) ? 1 : -1);
|
|
251
346
|
} }
|
|
252
|
-
function
|
|
253
|
-
i0.ɵɵelementStart(0, "div",
|
|
254
|
-
i0.ɵɵconditionalCreate(1,
|
|
255
|
-
i0.ɵɵrepeaterCreate(2,
|
|
347
|
+
function ShellComponent_Conditional_20_Template(rf, ctx) { if (rf & 1) {
|
|
348
|
+
i0.ɵɵelementStart(0, "div", 68);
|
|
349
|
+
i0.ɵɵconditionalCreate(1, ShellComponent_Conditional_20_Conditional_1_Template, 7, 3);
|
|
350
|
+
i0.ɵɵrepeaterCreate(2, ShellComponent_Conditional_20_For_3_Template, 2, 2, null, null, i0.ɵɵrepeaterTrackByIdentity);
|
|
256
351
|
i0.ɵɵelementEnd();
|
|
257
352
|
} if (rf & 2) {
|
|
258
353
|
let tmp_3_0;
|
|
@@ -265,25 +360,25 @@ function ShellComponent_Conditional_19_Template(rf, ctx) { if (rf & 1) {
|
|
|
265
360
|
i0.ɵɵadvance();
|
|
266
361
|
i0.ɵɵrepeater(ctx_r3.userMenuElements);
|
|
267
362
|
} }
|
|
268
|
-
function
|
|
269
|
-
const
|
|
270
|
-
i0.ɵɵelementStart(0, "div",
|
|
271
|
-
i0.ɵɵlistener("click", function
|
|
363
|
+
function ShellComponent_Conditional_21_Template(rf, ctx) { if (rf & 1) {
|
|
364
|
+
const _r17 = i0.ɵɵgetCurrentView();
|
|
365
|
+
i0.ɵɵelementStart(0, "div", 84);
|
|
366
|
+
i0.ɵɵlistener("click", function ShellComponent_Conditional_21_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r17); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.closeSearch()); });
|
|
272
367
|
i0.ɵɵelementEnd();
|
|
273
368
|
} }
|
|
274
|
-
function
|
|
275
|
-
const
|
|
276
|
-
i0.ɵɵelementStart(0, "div",
|
|
277
|
-
i0.ɵɵlistener("click", function
|
|
369
|
+
function ShellComponent_Conditional_29_Template(rf, ctx) { if (rf & 1) {
|
|
370
|
+
const _r18 = i0.ɵɵgetCurrentView();
|
|
371
|
+
i0.ɵɵelementStart(0, "div", 85);
|
|
372
|
+
i0.ɵɵlistener("click", function ShellComponent_Conditional_29_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r18); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.closeMobileNav()); });
|
|
278
373
|
i0.ɵɵelementEnd();
|
|
279
374
|
} }
|
|
280
|
-
function
|
|
281
|
-
const
|
|
282
|
-
i0.ɵɵelementStart(0, "div",
|
|
375
|
+
function ShellComponent_Conditional_36_Template(rf, ctx) { if (rf & 1) {
|
|
376
|
+
const _r19 = i0.ɵɵgetCurrentView();
|
|
377
|
+
i0.ɵɵelementStart(0, "div", 36)(1, "div", 86);
|
|
283
378
|
i0.ɵɵtext(2);
|
|
284
379
|
i0.ɵɵelementEnd();
|
|
285
|
-
i0.ɵɵelementStart(3, "mj-app-nav",
|
|
286
|
-
i0.ɵɵlistener("navItemClick", function
|
|
380
|
+
i0.ɵɵelementStart(3, "mj-app-nav", 87);
|
|
381
|
+
i0.ɵɵlistener("navItemClick", function ShellComponent_Conditional_36_Template_mj_app_nav_navItemClick_3_listener($event) { i0.ɵɵrestoreView(_r19); 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(_r19); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onNavItemDismiss($event)); });
|
|
287
382
|
i0.ɵɵelementEnd()();
|
|
288
383
|
} if (rf & 2) {
|
|
289
384
|
const ctx_r3 = i0.ɵɵnextContext();
|
|
@@ -292,8 +387,8 @@ function ShellComponent_Conditional_35_Template(rf, ctx) { if (rf & 1) {
|
|
|
292
387
|
i0.ɵɵadvance();
|
|
293
388
|
i0.ɵɵproperty("app", ctx_r3.activeApp);
|
|
294
389
|
} }
|
|
295
|
-
function
|
|
296
|
-
i0.ɵɵelementStart(0, "span",
|
|
390
|
+
function ShellComponent_Conditional_46_Template(rf, ctx) { if (rf & 1) {
|
|
391
|
+
i0.ɵɵelementStart(0, "span", 40);
|
|
297
392
|
i0.ɵɵtext(1);
|
|
298
393
|
i0.ɵɵelementEnd();
|
|
299
394
|
} if (rf & 2) {
|
|
@@ -301,23 +396,23 @@ function ShellComponent_Conditional_45_Template(rf, ctx) { if (rf & 1) {
|
|
|
301
396
|
i0.ɵɵadvance();
|
|
302
397
|
i0.ɵɵtextInterpolate1(" ", ctx_r3.unreadNotificationCount > 99 ? "99+" : ctx_r3.unreadNotificationCount, " ");
|
|
303
398
|
} }
|
|
304
|
-
function
|
|
305
|
-
const
|
|
306
|
-
i0.ɵɵelementStart(0, "div",
|
|
307
|
-
i0.ɵɵelement(2, "i",
|
|
399
|
+
function ShellComponent_Conditional_48_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
400
|
+
const _r20 = i0.ɵɵgetCurrentView();
|
|
401
|
+
i0.ɵɵelementStart(0, "div", 89)(1, "p", 91);
|
|
402
|
+
i0.ɵɵelement(2, "i", 92);
|
|
308
403
|
i0.ɵɵtext(3, " Taking longer than expected ");
|
|
309
404
|
i0.ɵɵelementEnd();
|
|
310
|
-
i0.ɵɵelementStart(4, "p",
|
|
405
|
+
i0.ɵɵelementStart(4, "p", 93);
|
|
311
406
|
i0.ɵɵtext(5, " This can happen after updates or due to cached data issues. ");
|
|
312
407
|
i0.ɵɵelementEnd();
|
|
313
|
-
i0.ɵɵelementStart(6, "button",
|
|
314
|
-
i0.ɵɵlistener("click", function
|
|
315
|
-
i0.ɵɵelement(7, "i",
|
|
408
|
+
i0.ɵɵelementStart(6, "button", 94);
|
|
409
|
+
i0.ɵɵlistener("click", function ShellComponent_Conditional_48_Conditional_2_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r20); const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.ResetApplication()); });
|
|
410
|
+
i0.ɵɵelement(7, "i", 95);
|
|
316
411
|
i0.ɵɵtext(8, " Reset ");
|
|
317
412
|
i0.ɵɵelementEnd()();
|
|
318
413
|
} }
|
|
319
|
-
function
|
|
320
|
-
i0.ɵɵelementStart(0, "div",
|
|
414
|
+
function ShellComponent_Conditional_48_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
415
|
+
i0.ɵɵelementStart(0, "div", 90);
|
|
321
416
|
i0.ɵɵtext(1);
|
|
322
417
|
i0.ɵɵelementEnd();
|
|
323
418
|
} if (rf & 2) {
|
|
@@ -325,10 +420,10 @@ function ShellComponent_Conditional_47_Conditional_3_Template(rf, ctx) { if (rf
|
|
|
325
420
|
i0.ɵɵadvance();
|
|
326
421
|
i0.ɵɵtextInterpolate1("MemberJunction \u00B7 v", ctx_r3.MJVersion);
|
|
327
422
|
} }
|
|
328
|
-
function
|
|
329
|
-
i0.ɵɵelementStart(0, "div",
|
|
330
|
-
i0.ɵɵelement(1, "mj-loading",
|
|
331
|
-
i0.ɵɵconditionalCreate(2,
|
|
423
|
+
function ShellComponent_Conditional_48_Template(rf, ctx) { if (rf & 1) {
|
|
424
|
+
i0.ɵɵelementStart(0, "div", 42);
|
|
425
|
+
i0.ɵɵelement(1, "mj-loading", 88);
|
|
426
|
+
i0.ɵɵconditionalCreate(2, ShellComponent_Conditional_48_Conditional_2_Template, 9, 0, "div", 89)(3, ShellComponent_Conditional_48_Conditional_3_Template, 2, 1, "div", 90);
|
|
332
427
|
i0.ɵɵelementEnd();
|
|
333
428
|
} if (rf & 2) {
|
|
334
429
|
const ctx_r3 = i0.ɵɵnextContext();
|
|
@@ -337,10 +432,10 @@ function ShellComponent_Conditional_47_Template(rf, ctx) { if (rf & 1) {
|
|
|
337
432
|
i0.ɵɵadvance();
|
|
338
433
|
i0.ɵɵconditional(ctx_r3.ShowResetOption ? 2 : 3);
|
|
339
434
|
} }
|
|
340
|
-
function
|
|
341
|
-
i0.ɵɵelementStart(0, "div",
|
|
342
|
-
i0.ɵɵelement(2, "mj-loading",
|
|
343
|
-
i0.ɵɵelementStart(3, "span",
|
|
435
|
+
function ShellComponent_Conditional_52_Template(rf, ctx) { if (rf & 1) {
|
|
436
|
+
i0.ɵɵelementStart(0, "div", 45)(1, "div", 96);
|
|
437
|
+
i0.ɵɵelement(2, "mj-loading", 97);
|
|
438
|
+
i0.ɵɵelementStart(3, "span", 98);
|
|
344
439
|
i0.ɵɵtext(4);
|
|
345
440
|
i0.ɵɵelementEnd()()();
|
|
346
441
|
} if (rf & 2) {
|
|
@@ -382,6 +477,7 @@ export class ShellComponent extends BaseAngularComponent {
|
|
|
382
477
|
fileOpenService;
|
|
383
478
|
feedbackDialogService;
|
|
384
479
|
feedbackService;
|
|
480
|
+
activityService;
|
|
385
481
|
subscriptions = [];
|
|
386
482
|
urlBasedNavigation = false; // Track if we're loading from a URL
|
|
387
483
|
initialNavigationComplete = false; // Track if initial navigation has completed
|
|
@@ -393,6 +489,10 @@ export class ShellComponent extends BaseAngularComponent {
|
|
|
393
489
|
userMenuVisible = false; // User avatar context menu
|
|
394
490
|
mobileNavOpen = false; // Mobile navigation drawer
|
|
395
491
|
unreadNotificationCount = 0; // Notification badge count
|
|
492
|
+
// Global Activity indicator (P3)
|
|
493
|
+
activityItems = [];
|
|
494
|
+
activityRunningCount = 0;
|
|
495
|
+
activityOpen = false;
|
|
396
496
|
isViewingSystemTab = false; // True when viewing a resource tab (not associated with a registered app)
|
|
397
497
|
loadingAppId = null; // ID of app currently being loaded (for app switcher loading indicator)
|
|
398
498
|
// Loading animation state
|
|
@@ -469,7 +569,7 @@ export class ShellComponent extends BaseAngularComponent {
|
|
|
469
569
|
return this.appManager.GetNavBarApps('Left of User Menu')
|
|
470
570
|
.filter(app => !(app.HideNavBarIconWhenActive && UUIDsEqual(app.ID, this.activeApp?.ID)));
|
|
471
571
|
}
|
|
472
|
-
constructor(appManager, workspaceManager, layoutManager, tabService, navigationService, route, router, authBase, cdr, userAvatarService, userSharingCenterDialogService, aboutDialogService, profileDialogService, viewContainerRef, titleService, developerModeService, startupValidationService, commandPaletteService, themeService, homePinService, fileOpenService, feedbackDialogService, feedbackService) {
|
|
572
|
+
constructor(appManager, workspaceManager, layoutManager, tabService, navigationService, route, router, authBase, cdr, userAvatarService, userSharingCenterDialogService, aboutDialogService, profileDialogService, viewContainerRef, titleService, developerModeService, startupValidationService, commandPaletteService, themeService, homePinService, fileOpenService, feedbackDialogService, feedbackService, activityService) {
|
|
473
573
|
super();
|
|
474
574
|
this.appManager = appManager;
|
|
475
575
|
this.workspaceManager = workspaceManager;
|
|
@@ -494,6 +594,7 @@ export class ShellComponent extends BaseAngularComponent {
|
|
|
494
594
|
this.fileOpenService = fileOpenService;
|
|
495
595
|
this.feedbackDialogService = feedbackDialogService;
|
|
496
596
|
this.feedbackService = feedbackService;
|
|
597
|
+
this.activityService = activityService;
|
|
497
598
|
// Thread the active provider into the bootstrap services that need provider
|
|
498
599
|
// context. They each fall back to Metadata.Provider when no explicit provider
|
|
499
600
|
// is set, so this is a no-op for single-provider apps but enables correct
|
|
@@ -577,6 +678,14 @@ export class ShellComponent extends BaseAngularComponent {
|
|
|
577
678
|
this.subscriptions.push(this.workspaceManager.TabBarVisible.subscribe(visible => {
|
|
578
679
|
this.tabBarVisible = visible;
|
|
579
680
|
}));
|
|
681
|
+
// Subscribe to the global Activity tracker (Run Pipeline, Sync, Cluster, …)
|
|
682
|
+
this.subscriptions.push(this.activityService.Activities$.subscribe(items => {
|
|
683
|
+
this.activityItems = items;
|
|
684
|
+
this.activityRunningCount = items.filter(i => i.Status === 'running').length;
|
|
685
|
+
if (items.length === 0)
|
|
686
|
+
this.activityOpen = false;
|
|
687
|
+
this.cdr.detectChanges();
|
|
688
|
+
}));
|
|
580
689
|
// Subscribe to unread notification count changes
|
|
581
690
|
this.subscriptions.push(MJNotificationService.UnreadCount$.subscribe(count => {
|
|
582
691
|
this.unreadNotificationCount = count;
|
|
@@ -618,6 +727,25 @@ export class ShellComponent extends BaseAngularComponent {
|
|
|
618
727
|
await this.handleNoAppsAvailable();
|
|
619
728
|
return;
|
|
620
729
|
}
|
|
730
|
+
// App-locked session (e.g. magic-link): ignore whatever app the URL names
|
|
731
|
+
// (including a pasted /app/home) and keep the user on their scoped app.
|
|
732
|
+
const lockedId = this.authBase.GetSessionScope()?.restrictedToApplicationId;
|
|
733
|
+
if (lockedId) {
|
|
734
|
+
const scopedApp = this.appManager.GetAppById(lockedId);
|
|
735
|
+
if (scopedApp) {
|
|
736
|
+
// Resolve the app the URL currently names and compare by ID — never
|
|
737
|
+
// string-match a hand-rolled name slug, which diverges from a custom
|
|
738
|
+
// Path and would loop the redirect. (navigateToApp uses app.Path.)
|
|
739
|
+
const path = (this.router.url || '').split('#')[0].split('?')[0];
|
|
740
|
+
const urlAppPath = path.match(/\/app\/([^\/?#]+)/)?.[1];
|
|
741
|
+
const currentApp = urlAppPath ? this.appManager.GetAppByPath(decodeURIComponent(urlAppPath)) : undefined;
|
|
742
|
+
if (!currentApp || !UUIDsEqual(currentApp.ID, lockedId)) {
|
|
743
|
+
await this.navigateToApp(scopedApp);
|
|
744
|
+
return;
|
|
745
|
+
}
|
|
746
|
+
// already on the scoped app — fall through to normal handling below
|
|
747
|
+
}
|
|
748
|
+
}
|
|
621
749
|
// Check if URL specifies an app by parsing the browser URL
|
|
622
750
|
const currentUrl = this.router.url;
|
|
623
751
|
const appMatch = currentUrl.match(/\/app\/([^\/]+)/);
|
|
@@ -1537,6 +1665,15 @@ export class ShellComponent extends BaseAngularComponent {
|
|
|
1537
1665
|
* a race condition in components we DO NOT control, so while the naming
|
|
1538
1666
|
* is intended to imply the goal it doesn't "hurt" to have this work this way
|
|
1539
1667
|
*/
|
|
1668
|
+
/**
|
|
1669
|
+
* True when the auth session is locked to a single application (e.g. a
|
|
1670
|
+
* magic-link session). The header hides app-switching chrome so the external
|
|
1671
|
+
* user stays within their scoped app. Data access is still enforced
|
|
1672
|
+
* server-side by the user's role; this is the UI-confinement layer.
|
|
1673
|
+
*/
|
|
1674
|
+
get appSwitchingLocked() {
|
|
1675
|
+
return !!this.authBase.GetSessionScope()?.restrictedToApplicationId;
|
|
1676
|
+
}
|
|
1540
1677
|
onFirstResourceLoadComplete() {
|
|
1541
1678
|
this.waitingForFirstResource = false;
|
|
1542
1679
|
this.loading = false;
|
|
@@ -1616,17 +1753,28 @@ export class ShellComponent extends BaseAngularComponent {
|
|
|
1616
1753
|
this.ShowResetOption = false;
|
|
1617
1754
|
}
|
|
1618
1755
|
/**
|
|
1619
|
-
* Nuclear recovery: clear all browser-side
|
|
1620
|
-
*
|
|
1621
|
-
*
|
|
1756
|
+
* Nuclear recovery: reset server-side workspace, clear all browser-side
|
|
1757
|
+
* cached data, and reload the page. This recovers from stuck loading states
|
|
1758
|
+
* caused by corrupted, stale, or incompatible workspace/tab data (e.g., after
|
|
1759
|
+
* a version upgrade that changes the workspace configuration schema).
|
|
1622
1760
|
*/
|
|
1623
|
-
ResetApplication() {
|
|
1761
|
+
async ResetApplication() {
|
|
1762
|
+
try {
|
|
1763
|
+
// 1. Reset server-side workspace to a clean default configuration.
|
|
1764
|
+
// This is the most common cause of stuck loading: stale tab configs
|
|
1765
|
+
// from a previous version reference resources/driver classes that
|
|
1766
|
+
// no longer exist or have changed format.
|
|
1767
|
+
await this.workspaceManager.ResetConfiguration();
|
|
1768
|
+
}
|
|
1769
|
+
catch (e) {
|
|
1770
|
+
console.warn('Error resetting workspace configuration:', e);
|
|
1771
|
+
}
|
|
1624
1772
|
try {
|
|
1625
|
-
//
|
|
1773
|
+
// 2. Clear localStorage
|
|
1626
1774
|
localStorage.clear();
|
|
1627
|
-
//
|
|
1775
|
+
// 3. Clear sessionStorage
|
|
1628
1776
|
sessionStorage.clear();
|
|
1629
|
-
//
|
|
1777
|
+
// 4. Delete all IndexedDB databases
|
|
1630
1778
|
if (window.indexedDB?.databases) {
|
|
1631
1779
|
window.indexedDB.databases().then(databases => {
|
|
1632
1780
|
for (const db of databases) {
|
|
@@ -2614,6 +2762,23 @@ export class ShellComponent extends BaseAngularComponent {
|
|
|
2614
2762
|
/**
|
|
2615
2763
|
* Show notifications page as a tab
|
|
2616
2764
|
*/
|
|
2765
|
+
/** Toggle the global Activity drawer. */
|
|
2766
|
+
toggleActivity(event) {
|
|
2767
|
+
event.stopPropagation();
|
|
2768
|
+
this.activityOpen = !this.activityOpen;
|
|
2769
|
+
this.cdr.detectChanges();
|
|
2770
|
+
}
|
|
2771
|
+
/** Clear finished activities from the tracker. */
|
|
2772
|
+
clearFinishedActivity() {
|
|
2773
|
+
this.activityService.ClearFinished();
|
|
2774
|
+
}
|
|
2775
|
+
/** Close the Activity drawer when clicking anywhere outside it. */
|
|
2776
|
+
onDocumentClickCloseActivity() {
|
|
2777
|
+
if (this.activityOpen) {
|
|
2778
|
+
this.activityOpen = false;
|
|
2779
|
+
this.cdr.detectChanges();
|
|
2780
|
+
}
|
|
2781
|
+
}
|
|
2617
2782
|
showNotifications() {
|
|
2618
2783
|
MJGlobal.Instance.RaiseEvent({
|
|
2619
2784
|
event: MJEventType.ComponentEvent,
|
|
@@ -2905,8 +3070,7 @@ export class ShellComponent extends BaseAngularComponent {
|
|
|
2905
3070
|
}
|
|
2906
3071
|
}
|
|
2907
3072
|
// Update URL to reflect the new app
|
|
2908
|
-
|
|
2909
|
-
this.router.navigateByUrl(`/app/${encodeURIComponent(appPath)}`);
|
|
3073
|
+
this.router.navigateByUrl(this.appManager.GetAppUrl(app));
|
|
2910
3074
|
}
|
|
2911
3075
|
/**
|
|
2912
3076
|
* Redirect to the first available app (fallback)
|
|
@@ -2926,7 +3090,7 @@ export class ShellComponent extends BaseAngularComponent {
|
|
|
2926
3090
|
this.cdr.detectChanges();
|
|
2927
3091
|
}
|
|
2928
3092
|
}
|
|
2929
|
-
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.UserSharingCenterDialogService), i0.ɵɵdirectiveInject(i7.AboutDialogService), i0.ɵɵdirectiveInject(i8.ProfileDialogService), i0.ɵɵdirectiveInject(i0.ViewContainerRef), i0.ɵɵdirectiveInject(i2.TitleService), i0.ɵɵdirectiveInject(i2.DeveloperModeService), i0.ɵɵdirectiveInject(i9.StartupValidationService), i0.ɵɵdirectiveInject(i10.CommandPaletteService), i0.ɵɵdirectiveInject(i2.ThemeService), i0.ɵɵdirectiveInject(i2.HomeAppPinService), i0.ɵɵdirectiveInject(i11.FileOpenService), i0.ɵɵdirectiveInject(i12.FeedbackDialogService), i0.ɵɵdirectiveInject(i12.FeedbackService)); };
|
|
3093
|
+
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.UserSharingCenterDialogService), i0.ɵɵdirectiveInject(i7.AboutDialogService), i0.ɵɵdirectiveInject(i8.ProfileDialogService), i0.ɵɵdirectiveInject(i0.ViewContainerRef), i0.ɵɵdirectiveInject(i2.TitleService), i0.ɵɵdirectiveInject(i2.DeveloperModeService), i0.ɵɵdirectiveInject(i9.StartupValidationService), i0.ɵɵdirectiveInject(i10.CommandPaletteService), i0.ɵɵdirectiveInject(i2.ThemeService), i0.ɵɵdirectiveInject(i2.HomeAppPinService), i0.ɵɵdirectiveInject(i11.FileOpenService), i0.ɵɵdirectiveInject(i12.FeedbackDialogService), i0.ɵɵdirectiveInject(i12.FeedbackService), i0.ɵɵdirectiveInject(i2.ActivityService)); };
|
|
2930
3094
|
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ShellComponent, selectors: [["mj-shell"]], viewQuery: function ShellComponent_Query(rf, ctx) { if (rf & 1) {
|
|
2931
3095
|
i0.ɵɵviewQuery(_c0, 5)(_c1, 5)(TabContainerComponent, 5)(_c2, 5);
|
|
2932
3096
|
} if (rf & 2) {
|
|
@@ -2936,8 +3100,8 @@ export class ShellComponent extends BaseAngularComponent {
|
|
|
2936
3100
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.tabContainerRef = _t.first);
|
|
2937
3101
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.appAccessDialog = _t.first);
|
|
2938
3102
|
} }, hostBindings: function ShellComponent_HostBindings(rf, ctx) { if (rf & 1) {
|
|
2939
|
-
i0.ɵɵlistener("keydown", function ShellComponent_keydown_HostBindingHandler($event) { return ctx.OnGlobalKeydown($event); }, i0.ɵɵresolveDocument);
|
|
2940
|
-
} }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls:
|
|
3103
|
+
i0.ɵɵlistener("keydown", function ShellComponent_keydown_HostBindingHandler($event) { return ctx.OnGlobalKeydown($event); }, i0.ɵɵresolveDocument)("click", function ShellComponent_click_HostBindingHandler() { return ctx.onDocumentClickCloseActivity(); }, i0.ɵɵresolveDocument);
|
|
3104
|
+
} }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 53, vars: 27, 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, "activeApp", "isViewingSystemTab", "loadingAppId"], [1, "desktop-nav", 3, "app"], [1, "shell-search-bar", "desktop-only"], [1, "spacer"], [1, "header-actions"], [1, "activity-wrap"], ["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"], [3, "appSelected", "activeApp", "isViewingSystemTab", "loadingAppId"], [1, "desktop-nav", 3, "navItemClick", "navItemDismiss", "app"], ["Placeholder", "Search everything...", 3, "ResultSelected", "SearchSubmitted", "SeeAllRequested", "ShowShortcutHint", "EnablePreview", "EnableRecent", "MaxPreviewResults"], ["title", "Activity", 1, "icon-btn", "desktop-only", "activity-btn", 3, "click"], [1, "fa-solid", "fa-wave-square"], [1, "activity-badge"], [1, "activity-drawer"], [1, "activity-drawer", 3, "click"], [1, "activity-drawer-head"], ["title", "Clear finished", 1, "activity-clear", 3, "click"], [1, "fa-solid", "fa-broom"], [1, "activity-list"], [1, "activity-row", 3, "is-error"], [1, "activity-row"], [1, "activity-row-icon"], [1, "activity-row-body"], [1, "activity-row-label"], [1, "activity-row-detail"], [1, "activity-bar"], [1, "activity-bar-fill"], [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-version"], [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) {
|
|
2941
3105
|
const _r1 = i0.ɵɵgetCurrentView();
|
|
2942
3106
|
i0.ɵɵelementStart(0, "div", 3)(1, "header", 4);
|
|
2943
3107
|
i0.ɵɵelement(2, "div", 5);
|
|
@@ -2946,116 +3110,118 @@ export class ShellComponent extends BaseAngularComponent {
|
|
|
2946
3110
|
i0.ɵɵelement(4, "i", 7);
|
|
2947
3111
|
i0.ɵɵelementEnd();
|
|
2948
3112
|
i0.ɵɵconditionalCreate(5, ShellComponent_Conditional_5_Template, 3, 0, "div", 8);
|
|
2949
|
-
i0.ɵɵ
|
|
2950
|
-
i0.ɵɵlistener("appSelected", function ShellComponent_Template_mj_app_switcher_appSelected_6_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onAppSwitch($event)); });
|
|
2951
|
-
i0.ɵɵelementEnd();
|
|
3113
|
+
i0.ɵɵconditionalCreate(6, ShellComponent_Conditional_6_Template, 1, 3, "mj-app-switcher", 9);
|
|
2952
3114
|
i0.ɵɵconditionalCreate(7, ShellComponent_Conditional_7_Template, 1, 1, "mj-app-nav", 10);
|
|
2953
3115
|
i0.ɵɵconditionalCreate(8, ShellComponent_Conditional_8_Template, 3, 4, "div", 11);
|
|
2954
3116
|
i0.ɵɵelement(9, "div", 12);
|
|
2955
|
-
i0.ɵɵelementStart(10, "div", 13)
|
|
2956
|
-
i0.ɵɵ
|
|
2957
|
-
i0.ɵɵ
|
|
2958
|
-
i0.ɵɵ
|
|
3117
|
+
i0.ɵɵelementStart(10, "div", 13);
|
|
3118
|
+
i0.ɵɵconditionalCreate(11, ShellComponent_Conditional_11_Template, 5, 4, "div", 14);
|
|
3119
|
+
i0.ɵɵelementStart(12, "button", 15);
|
|
3120
|
+
i0.ɵɵlistener("click", function ShellComponent_Template_button_click_12_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.showNotifications()); });
|
|
3121
|
+
i0.ɵɵelement(13, "i", 16);
|
|
3122
|
+
i0.ɵɵconditionalCreate(14, ShellComponent_Conditional_14_Template, 2, 1, "span", 17);
|
|
2959
3123
|
i0.ɵɵelementEnd();
|
|
2960
|
-
i0.ɵɵconditionalCreate(
|
|
2961
|
-
i0.ɵɵelementStart(
|
|
2962
|
-
i0.ɵɵlistener("click", function
|
|
2963
|
-
i0.ɵɵconditionalCreate(
|
|
3124
|
+
i0.ɵɵconditionalCreate(15, ShellComponent_Conditional_15_Template, 3, 0, "div", 18);
|
|
3125
|
+
i0.ɵɵelementStart(16, "div", 19)(17, "button", 20);
|
|
3126
|
+
i0.ɵɵlistener("click", function ShellComponent_Template_button_click_17_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.toggleUserMenu($event)); });
|
|
3127
|
+
i0.ɵɵconditionalCreate(18, ShellComponent_Conditional_18_Template, 1, 1, "img", 21)(19, ShellComponent_Conditional_19_Template, 2, 2, "div", 22);
|
|
2964
3128
|
i0.ɵɵelementEnd();
|
|
2965
|
-
i0.ɵɵconditionalCreate(
|
|
3129
|
+
i0.ɵɵconditionalCreate(20, ShellComponent_Conditional_20_Template, 4, 5, "div", 23);
|
|
2966
3130
|
i0.ɵɵelementEnd()()();
|
|
2967
|
-
i0.ɵɵconditionalCreate(
|
|
2968
|
-
i0.ɵɵelementStart(
|
|
2969
|
-
i0.ɵɵlistener("click", function
|
|
2970
|
-
i0.ɵɵelementStart(
|
|
2971
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
3131
|
+
i0.ɵɵconditionalCreate(21, ShellComponent_Conditional_21_Template, 1, 0, "div", 24);
|
|
3132
|
+
i0.ɵɵelementStart(22, "div", 25)(23, "div", 26);
|
|
3133
|
+
i0.ɵɵlistener("click", function ShellComponent_Template_div_click_23_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView($event.stopPropagation()); });
|
|
3134
|
+
i0.ɵɵelementStart(24, "mj-dropdown", 27);
|
|
3135
|
+
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); });
|
|
2972
3136
|
i0.ɵɵelementEnd();
|
|
2973
|
-
i0.ɵɵelementStart(
|
|
2974
|
-
i0.ɵɵlistener("keydown.enter", function
|
|
3137
|
+
i0.ɵɵelementStart(25, "input", 28, 0);
|
|
3138
|
+
i0.ɵɵlistener("keydown.enter", function ShellComponent_Template_input_keydown_enter_25_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onSearch($event)); });
|
|
2975
3139
|
i0.ɵɵelementEnd();
|
|
2976
|
-
i0.ɵɵelementStart(
|
|
2977
|
-
i0.ɵɵlistener("click", function
|
|
2978
|
-
i0.ɵɵelement(
|
|
3140
|
+
i0.ɵɵelementStart(27, "button", 29);
|
|
3141
|
+
i0.ɵɵlistener("click", function ShellComponent_Template_button_click_27_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onSearch($event)); });
|
|
3142
|
+
i0.ɵɵelement(28, "i", 30);
|
|
2979
3143
|
i0.ɵɵelementEnd()()();
|
|
2980
|
-
i0.ɵɵconditionalCreate(
|
|
2981
|
-
i0.ɵɵelementStart(
|
|
2982
|
-
i0.ɵɵtext(
|
|
3144
|
+
i0.ɵɵconditionalCreate(29, ShellComponent_Conditional_29_Template, 1, 0, "div", 31);
|
|
3145
|
+
i0.ɵɵelementStart(30, "div", 32)(31, "div", 33)(32, "span");
|
|
3146
|
+
i0.ɵɵtext(33, "Navigation");
|
|
2983
3147
|
i0.ɵɵelementEnd();
|
|
2984
|
-
i0.ɵɵelementStart(
|
|
2985
|
-
i0.ɵɵlistener("click", function
|
|
2986
|
-
i0.ɵɵelement(
|
|
3148
|
+
i0.ɵɵelementStart(34, "button", 34);
|
|
3149
|
+
i0.ɵɵlistener("click", function ShellComponent_Template_button_click_34_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.closeMobileNav()); });
|
|
3150
|
+
i0.ɵɵelement(35, "i", 35);
|
|
2987
3151
|
i0.ɵɵelementEnd()();
|
|
2988
|
-
i0.ɵɵconditionalCreate(
|
|
2989
|
-
i0.ɵɵelementStart(
|
|
2990
|
-
i0.ɵɵlistener("click", function
|
|
2991
|
-
i0.ɵɵelement(
|
|
2992
|
-
i0.ɵɵelementStart(
|
|
2993
|
-
i0.ɵɵtext(
|
|
3152
|
+
i0.ɵɵconditionalCreate(36, ShellComponent_Conditional_36_Template, 4, 2, "div", 36);
|
|
3153
|
+
i0.ɵɵelementStart(37, "div", 37)(38, "button", 38);
|
|
3154
|
+
i0.ɵɵlistener("click", function ShellComponent_Template_button_click_38_listener() { i0.ɵɵrestoreView(_r1); ctx.toggleSearch(); return i0.ɵɵresetView(ctx.closeMobileNav()); });
|
|
3155
|
+
i0.ɵɵelement(39, "i", 30);
|
|
3156
|
+
i0.ɵɵelementStart(40, "span");
|
|
3157
|
+
i0.ɵɵtext(41, "Search");
|
|
2994
3158
|
i0.ɵɵelementEnd()();
|
|
2995
|
-
i0.ɵɵelementStart(
|
|
2996
|
-
i0.ɵɵlistener("click", function
|
|
2997
|
-
i0.ɵɵelement(
|
|
2998
|
-
i0.ɵɵelementStart(
|
|
2999
|
-
i0.ɵɵtext(
|
|
3159
|
+
i0.ɵɵelementStart(42, "button", 39);
|
|
3160
|
+
i0.ɵɵlistener("click", function ShellComponent_Template_button_click_42_listener() { i0.ɵɵrestoreView(_r1); ctx.showNotifications(); return i0.ɵɵresetView(ctx.closeMobileNav()); });
|
|
3161
|
+
i0.ɵɵelement(43, "i", 16);
|
|
3162
|
+
i0.ɵɵelementStart(44, "span");
|
|
3163
|
+
i0.ɵɵtext(45, "Notifications");
|
|
3000
3164
|
i0.ɵɵelementEnd();
|
|
3001
|
-
i0.ɵɵconditionalCreate(
|
|
3165
|
+
i0.ɵɵconditionalCreate(46, ShellComponent_Conditional_46_Template, 2, 1, "span", 40);
|
|
3002
3166
|
i0.ɵɵelementEnd()()();
|
|
3003
|
-
i0.ɵɵelementStart(
|
|
3004
|
-
i0.ɵɵlistener("firstResourceLoadComplete", function
|
|
3167
|
+
i0.ɵɵelementStart(47, "mj-tab-container", 41);
|
|
3168
|
+
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()); });
|
|
3005
3169
|
i0.ɵɵelementEnd()();
|
|
3006
|
-
i0.ɵɵconditionalCreate(
|
|
3007
|
-
i0.ɵɵelementStart(
|
|
3008
|
-
i0.ɵɵlistener("result", function
|
|
3170
|
+
i0.ɵɵconditionalCreate(48, ShellComponent_Conditional_48_Template, 4, 6, "div", 42);
|
|
3171
|
+
i0.ɵɵelementStart(49, "mj-app-access-dialog", 43, 1);
|
|
3172
|
+
i0.ɵɵlistener("result", function ShellComponent_Template_mj_app_access_dialog_result_49_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onAppAccessDialogResult($event)); });
|
|
3009
3173
|
i0.ɵɵelementEnd();
|
|
3010
|
-
i0.ɵɵelementStart(
|
|
3011
|
-
i0.ɵɵlistener("AppSelected", function
|
|
3174
|
+
i0.ɵɵelementStart(51, "mj-command-palette", 44);
|
|
3175
|
+
i0.ɵɵlistener("AppSelected", function ShellComponent_Template_mj_command_palette_AppSelected_51_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onAppSwitch($event)); });
|
|
3012
3176
|
i0.ɵɵelementEnd();
|
|
3013
|
-
i0.ɵɵconditionalCreate(
|
|
3177
|
+
i0.ɵɵconditionalCreate(52, ShellComponent_Conditional_52_Template, 5, 2, "div", 45);
|
|
3014
3178
|
} if (rf & 2) {
|
|
3015
3179
|
i0.ɵɵclassProp("hidden", ctx.loading)("tabs-visible", ctx.tabBarVisible);
|
|
3016
3180
|
i0.ɵɵadvance(5);
|
|
3017
|
-
i0.ɵɵconditional(ctx.leftOfSwitcherApps.length > 0 ? 5 : -1);
|
|
3181
|
+
i0.ɵɵconditional(ctx.leftOfSwitcherApps.length > 0 && !ctx.appSwitchingLocked ? 5 : -1);
|
|
3018
3182
|
i0.ɵɵadvance();
|
|
3019
|
-
i0.ɵɵ
|
|
3183
|
+
i0.ɵɵconditional(!ctx.appSwitchingLocked ? 6 : -1);
|
|
3020
3184
|
i0.ɵɵadvance();
|
|
3021
3185
|
i0.ɵɵconditional(ctx.activeApp ? 7 : -1);
|
|
3022
3186
|
i0.ɵɵadvance();
|
|
3023
3187
|
i0.ɵɵconditional(ctx.ShowSearchBar ? 8 : -1);
|
|
3024
|
-
i0.ɵɵadvance(
|
|
3025
|
-
i0.ɵɵconditional(ctx.
|
|
3188
|
+
i0.ɵɵadvance(3);
|
|
3189
|
+
i0.ɵɵconditional(ctx.activityItems.length > 0 ? 11 : -1);
|
|
3190
|
+
i0.ɵɵadvance(3);
|
|
3191
|
+
i0.ɵɵconditional(ctx.unreadNotificationCount > 0 ? 14 : -1);
|
|
3026
3192
|
i0.ɵɵadvance();
|
|
3027
|
-
i0.ɵɵconditional(ctx.leftOfUserMenuApps.length > 0 ?
|
|
3193
|
+
i0.ɵɵconditional(ctx.leftOfUserMenuApps.length > 0 ? 15 : -1);
|
|
3028
3194
|
i0.ɵɵadvance(3);
|
|
3029
|
-
i0.ɵɵconditional(ctx.userImageURL ?
|
|
3195
|
+
i0.ɵɵconditional(ctx.userImageURL ? 18 : 19);
|
|
3030
3196
|
i0.ɵɵadvance(2);
|
|
3031
|
-
i0.ɵɵconditional(ctx.userMenuVisible ?
|
|
3197
|
+
i0.ɵɵconditional(ctx.userMenuVisible ? 20 : -1);
|
|
3032
3198
|
i0.ɵɵadvance();
|
|
3033
|
-
i0.ɵɵconditional(ctx.isSearchOpen ?
|
|
3199
|
+
i0.ɵɵconditional(ctx.isSearchOpen ? 21 : -1);
|
|
3034
3200
|
i0.ɵɵadvance();
|
|
3035
3201
|
i0.ɵɵclassProp("open", ctx.isSearchOpen);
|
|
3036
3202
|
i0.ɵɵadvance(2);
|
|
3037
3203
|
i0.ɵɵproperty("Data", ctx.searchableEntities);
|
|
3038
3204
|
i0.ɵɵtwoWayProperty("ngModel", ctx.selectedEntity);
|
|
3039
3205
|
i0.ɵɵadvance(5);
|
|
3040
|
-
i0.ɵɵconditional(ctx.mobileNavOpen ?
|
|
3206
|
+
i0.ɵɵconditional(ctx.mobileNavOpen ? 29 : -1);
|
|
3041
3207
|
i0.ɵɵadvance();
|
|
3042
3208
|
i0.ɵɵclassProp("open", ctx.mobileNavOpen);
|
|
3043
3209
|
i0.ɵɵadvance(6);
|
|
3044
|
-
i0.ɵɵconditional(ctx.activeApp ?
|
|
3210
|
+
i0.ɵɵconditional(ctx.activeApp ? 36 : -1);
|
|
3045
3211
|
i0.ɵɵadvance(10);
|
|
3046
|
-
i0.ɵɵconditional(ctx.unreadNotificationCount > 0 ?
|
|
3212
|
+
i0.ɵɵconditional(ctx.unreadNotificationCount > 0 ? 46 : -1);
|
|
3047
3213
|
i0.ɵɵadvance();
|
|
3048
3214
|
i0.ɵɵclassProp("hide-tab-bar", !ctx.tabBarVisible);
|
|
3049
3215
|
i0.ɵɵadvance();
|
|
3050
|
-
i0.ɵɵconditional(ctx.loading ?
|
|
3216
|
+
i0.ɵɵconditional(ctx.loading ? 48 : -1);
|
|
3051
3217
|
i0.ɵɵadvance(4);
|
|
3052
|
-
i0.ɵɵconditional(ctx.PinProgressVisible ?
|
|
3053
|
-
} }, dependencies: [i13.NgControlStatus, i13.NgModel, i14.MJDropdownComponent, i15.LoadingComponent, i16.SearchCompositeComponent, i17.AppSwitcherComponent, i18.AppNavComponent, i19.TabContainerComponent, i20.AppAccessDialogComponent, i21.CommandPaletteComponent], styles: ["[_nghost-%COMP%] {\n display: block;\n height: 100%;\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: 100%;\n width: 100%;\n overflow: hidden;\n position: relative;\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 position: fixed;\n top: 0;\n left: 0;\n width: 100vw;\n height: 100vh;\n z-index: 99999;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding-bottom: 15vh;\n background: var(--mj-bg-page);\n}\n\n.loading-version[_ngcontent-%COMP%] {\n margin-top: var(--mj-space-8, 24px);\n font-size: 11px;\n color: var(--mj-text-muted);\n letter-spacing: 0.4px;\n opacity: 0.6;\n user-select: none;\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: absolute;\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}"] });
|
|
3218
|
+
i0.ɵɵconditional(ctx.PinProgressVisible ? 52 : -1);
|
|
3219
|
+
} }, dependencies: [i13.NgControlStatus, i13.NgModel, i14.MJDropdownComponent, i15.LoadingComponent, i16.SearchCompositeComponent, i17.AppSwitcherComponent, i18.AppNavComponent, i19.TabContainerComponent, i20.AppAccessDialogComponent, i21.CommandPaletteComponent], styles: ["[_nghost-%COMP%] {\n display: block;\n height: 100%;\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: 100%;\n width: 100%;\n overflow: hidden;\n position: relative;\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 position: fixed;\n top: 0;\n left: 0;\n width: 100vw;\n height: 100vh;\n z-index: 99999;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding-bottom: 15vh;\n background: var(--mj-bg-page);\n}\n\n.loading-version[_ngcontent-%COMP%] {\n margin-top: var(--mj-space-8, 24px);\n font-size: 11px;\n color: var(--mj-text-muted);\n letter-spacing: 0.4px;\n opacity: 0.6;\n user-select: none;\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 position: relative;\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\n .header-actions[_ngcontent-%COMP%] {\n flex-direction: row;\n flex-wrap: nowrap;\n }\n .header-actions[_ngcontent-%COMP%] .user-menu[_ngcontent-%COMP%], \n .header-actions[_ngcontent-%COMP%] .nav-bar-apps[_ngcontent-%COMP%] {\n flex-shrink: 0;\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: absolute;\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}\n\n\n\n\n.activity-wrap[_ngcontent-%COMP%] { position: relative; display: inline-flex; }\n.activity-btn[_ngcontent-%COMP%] { position: relative; }\n.activity-btn[_ngcontent-%COMP%] .activity-pulse[_ngcontent-%COMP%] { color: var(--mj-brand-primary); }\n.activity-badge[_ngcontent-%COMP%] {\n position: absolute;\n top: 2px;\n right: 2px;\n min-width: 16px;\n height: 16px;\n padding: 0 4px;\n border-radius: 8px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 10px;\n font-weight: 700;\n line-height: 16px;\n text-align: center;\n}\n.activity-drawer[_ngcontent-%COMP%] {\n position: absolute;\n top: calc(100% + 8px);\n right: 0;\n width: 320px;\n max-height: 420px;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface-elevated);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n box-shadow: 0 8px 28px color-mix(in srgb, var(--mj-text-primary) 18%, transparent);\n z-index: 1000;\n overflow: hidden;\n}\n.activity-drawer-head[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 12px;\n font-weight: 700;\n font-size: 0.85rem;\n color: var(--mj-text-primary);\n border-bottom: 1px solid var(--mj-border-default);\n}\n.activity-clear[_ngcontent-%COMP%] {\n background: none;\n border: none;\n color: var(--mj-text-muted);\n cursor: pointer;\n font-size: 0.8rem;\n padding: 4px 6px;\n border-radius: 6px;\n}\n.activity-clear[_ngcontent-%COMP%]:hover { color: var(--mj-text-primary); background: var(--mj-bg-surface-hover); }\n.activity-list[_ngcontent-%COMP%] { overflow-y: auto; padding: 6px; }\n.activity-row[_ngcontent-%COMP%] {\n display: flex;\n gap: 10px;\n padding: 9px 8px;\n border-radius: 8px;\n}\n.activity-row[_ngcontent-%COMP%]:hover { background: var(--mj-bg-surface-hover); }\n.activity-row-icon[_ngcontent-%COMP%] { margin-top: 2px; color: var(--mj-brand-primary); font-size: 0.85rem; }\n.activity-row.is-error[_ngcontent-%COMP%] .activity-row-icon[_ngcontent-%COMP%] { color: var(--mj-status-error); }\n.activity-row-body[_ngcontent-%COMP%] { flex: 1; min-width: 0; }\n.activity-row-label[_ngcontent-%COMP%] { font-size: 0.82rem; font-weight: 600; color: var(--mj-text-primary); }\n.activity-row-detail[_ngcontent-%COMP%] { font-size: 0.72rem; color: var(--mj-text-muted); margin-top: 1px; }\n.activity-bar[_ngcontent-%COMP%] {\n margin-top: 6px;\n height: 4px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 2px;\n overflow: hidden;\n}\n.activity-bar-fill[_ngcontent-%COMP%] { height: 100%; background: var(--mj-brand-primary); transition: width 0.3s ease; }"] });
|
|
3054
3220
|
}
|
|
3055
3221
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ShellComponent, [{
|
|
3056
3222
|
type: Component,
|
|
3057
|
-
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 <!-- 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 } @else {\n <div class=\"loading-version\">MemberJunction \u00B7 v{{ MJVersion }}</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: 100%;\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: 100%;\n width: 100%;\n overflow: hidden;\n position: relative;\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 position: fixed;\n top: 0;\n left: 0;\n width: 100vw;\n height: 100vh;\n z-index: 99999;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding-bottom: 15vh;\n background: var(--mj-bg-page);\n}\n\n.loading-version {\n margin-top: var(--mj-space-8, 24px);\n font-size: 11px;\n color: var(--mj-text-muted);\n letter-spacing: 0.4px;\n opacity: 0.6;\n user-select: none;\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: absolute;\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}"] }]
|
|
3058
|
-
}], () => [{ 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.UserSharingCenterDialogService }, { type: i7.AboutDialogService }, { type: i8.ProfileDialogService }, { type: i0.ViewContainerRef }, { type: i2.TitleService }, { type: i2.DeveloperModeService }, { type: i9.StartupValidationService }, { type: i10.CommandPaletteService }, { type: i2.ThemeService }, { type: i2.HomeAppPinService }, { type: i11.FileOpenService }, { type: i12.FeedbackDialogService }, { type: i12.FeedbackService }], { searchInput: [{
|
|
3223
|
+
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 && !appSwitchingLocked) {\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 (hidden for app-locked sessions, e.g. magic-link) -->\n @if (!appSwitchingLocked) {\n <mj-app-switcher\n [activeApp]=\"activeApp\"\n [isViewingSystemTab]=\"isViewingSystemTab\"\n [loadingAppId]=\"loadingAppId\"\n (appSelected)=\"onAppSwitch($event)\">\n </mj-app-switcher>\n }\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 (activity, notifications, user menu) -->\n <div class=\"header-actions\">\n <!-- Global Activity indicator -->\n @if (activityItems.length > 0) {\n <div class=\"activity-wrap\">\n <button class=\"icon-btn desktop-only activity-btn\" title=\"Activity\" (click)=\"toggleActivity($event)\">\n <i class=\"fa-solid fa-wave-square\" [class.activity-pulse]=\"activityRunningCount > 0\"></i>\n @if (activityRunningCount > 0) {\n <span class=\"activity-badge\">{{ activityRunningCount }}</span>\n }\n </button>\n @if (activityOpen) {\n <div class=\"activity-drawer\" (click)=\"$event.stopPropagation()\">\n <div class=\"activity-drawer-head\">\n <span>Activity</span>\n <button class=\"activity-clear\" (click)=\"clearFinishedActivity()\" title=\"Clear finished\">\n <i class=\"fa-solid fa-broom\"></i>\n </button>\n </div>\n <div class=\"activity-list\">\n @for (a of activityItems; track a.ID) {\n <div class=\"activity-row\" [class.is-error]=\"a.Status === 'error'\">\n <i class=\"activity-row-icon\"\n [class]=\"a.Status === 'running' ? 'fa-solid fa-spinner fa-spin'\n : a.Status === 'error' ? 'fa-solid fa-circle-exclamation'\n : 'fa-solid fa-circle-check'\"></i>\n <div class=\"activity-row-body\">\n <div class=\"activity-row-label\">{{ a.Label }}</div>\n @if (a.Detail) { <div class=\"activity-row-detail\">{{ a.Detail }}</div> }\n @if (a.Status === 'running' && a.Progress != null) {\n <div class=\"activity-bar\"><div class=\"activity-bar-fill\" [style.width.%]=\"a.Progress\"></div></div>\n }\n </div>\n </div>\n }\n </div>\n </div>\n }\n </div>\n }\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 <!-- 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 } @else {\n <div class=\"loading-version\">MemberJunction \u00B7 v{{ MJVersion }}</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: 100%;\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: 100%;\n width: 100%;\n overflow: hidden;\n position: relative;\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 position: fixed;\n top: 0;\n left: 0;\n width: 100vw;\n height: 100vh;\n z-index: 99999;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding-bottom: 15vh;\n background: var(--mj-bg-page);\n}\n\n.loading-version {\n margin-top: var(--mj-space-8, 24px);\n font-size: 11px;\n color: var(--mj-text-muted);\n letter-spacing: 0.4px;\n opacity: 0.6;\n user-select: none;\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 position: relative;\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 /* Keep the right-edge cluster (chat/nav-bar app icons + avatar) on one row.\n Without pinning this, the icons can wrap and the avatar drops onto a second\n line, stacking under the chat icon. */\n .header-actions {\n flex-direction: row;\n flex-wrap: nowrap;\n }\n .header-actions .user-menu,\n .header-actions .nav-bar-apps {\n flex-shrink: 0;\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: absolute;\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}\n/* ============================================================\n Global Activity indicator (P3)\n ============================================================ */\n.activity-wrap { position: relative; display: inline-flex; }\n.activity-btn { position: relative; }\n.activity-btn .activity-pulse { color: var(--mj-brand-primary); }\n.activity-badge {\n position: absolute;\n top: 2px;\n right: 2px;\n min-width: 16px;\n height: 16px;\n padding: 0 4px;\n border-radius: 8px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 10px;\n font-weight: 700;\n line-height: 16px;\n text-align: center;\n}\n.activity-drawer {\n position: absolute;\n top: calc(100% + 8px);\n right: 0;\n width: 320px;\n max-height: 420px;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface-elevated);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n box-shadow: 0 8px 28px color-mix(in srgb, var(--mj-text-primary) 18%, transparent);\n z-index: 1000;\n overflow: hidden;\n}\n.activity-drawer-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 12px;\n font-weight: 700;\n font-size: 0.85rem;\n color: var(--mj-text-primary);\n border-bottom: 1px solid var(--mj-border-default);\n}\n.activity-clear {\n background: none;\n border: none;\n color: var(--mj-text-muted);\n cursor: pointer;\n font-size: 0.8rem;\n padding: 4px 6px;\n border-radius: 6px;\n}\n.activity-clear:hover { color: var(--mj-text-primary); background: var(--mj-bg-surface-hover); }\n.activity-list { overflow-y: auto; padding: 6px; }\n.activity-row {\n display: flex;\n gap: 10px;\n padding: 9px 8px;\n border-radius: 8px;\n}\n.activity-row:hover { background: var(--mj-bg-surface-hover); }\n.activity-row-icon { margin-top: 2px; color: var(--mj-brand-primary); font-size: 0.85rem; }\n.activity-row.is-error .activity-row-icon { color: var(--mj-status-error); }\n.activity-row-body { flex: 1; min-width: 0; }\n.activity-row-label { font-size: 0.82rem; font-weight: 600; color: var(--mj-text-primary); }\n.activity-row-detail { font-size: 0.72rem; color: var(--mj-text-muted); margin-top: 1px; }\n.activity-bar {\n margin-top: 6px;\n height: 4px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 2px;\n overflow: hidden;\n}\n.activity-bar-fill { height: 100%; background: var(--mj-brand-primary); transition: width 0.3s ease; }\n"] }]
|
|
3224
|
+
}], () => [{ 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.UserSharingCenterDialogService }, { type: i7.AboutDialogService }, { type: i8.ProfileDialogService }, { type: i0.ViewContainerRef }, { type: i2.TitleService }, { type: i2.DeveloperModeService }, { type: i9.StartupValidationService }, { type: i10.CommandPaletteService }, { type: i2.ThemeService }, { type: i2.HomeAppPinService }, { type: i11.FileOpenService }, { type: i12.FeedbackDialogService }, { type: i12.FeedbackService }, { type: i2.ActivityService }], { searchInput: [{
|
|
3059
3225
|
type: ViewChild,
|
|
3060
3226
|
args: ['searchInput']
|
|
3061
3227
|
}], shellSearchComposite: [{
|
|
@@ -3073,6 +3239,9 @@ export class ShellComponent extends BaseAngularComponent {
|
|
|
3073
3239
|
}], OnGlobalKeydown: [{
|
|
3074
3240
|
type: HostListener,
|
|
3075
3241
|
args: ['document:keydown', ['$event']]
|
|
3242
|
+
}], onDocumentClickCloseActivity: [{
|
|
3243
|
+
type: HostListener,
|
|
3244
|
+
args: ['document:click']
|
|
3076
3245
|
}] }); })();
|
|
3077
3246
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ShellComponent, { className: "ShellComponent", filePath: "src/lib/shell/shell.component.ts", lineNumber: 53 }); })();
|
|
3078
3247
|
//# sourceMappingURL=shell.component.js.map
|