@memberjunction/ng-explorer-core 6.1.0-edge.4 → 6.1.0-edge.6
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/README.md +19 -0
- package/dist/generated/lazy-feature-config.d.ts.map +1 -1
- package/dist/generated/lazy-feature-config.js +12 -6
- package/dist/generated/lazy-feature-config.js.map +1 -1
- package/dist/lib/about/about-dialog.component.js +4 -4
- package/dist/lib/about/about-dialog.component.js.map +1 -1
- package/dist/lib/command-palette/command-palette.component.d.ts +13 -0
- package/dist/lib/command-palette/command-palette.component.d.ts.map +1 -1
- package/dist/lib/command-palette/command-palette.component.js +106 -42
- package/dist/lib/command-palette/command-palette.component.js.map +1 -1
- package/dist/lib/conversation-feedback/conversation-feedback.js +1 -1
- package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.js +1 -1
- package/dist/lib/oauth/oauth-callback.component.js +1 -1
- package/dist/lib/omnibar/omnibar-palette.component.d.ts.map +1 -1
- package/dist/lib/omnibar/omnibar-palette.component.js +9 -3
- package/dist/lib/omnibar/omnibar-palette.component.js.map +1 -1
- package/dist/lib/omnibar/providers/omnibar-record.provider.d.ts.map +1 -1
- package/dist/lib/omnibar/providers/omnibar-record.provider.js +9 -3
- package/dist/lib/omnibar/providers/omnibar-record.provider.js.map +1 -1
- package/dist/lib/profile/profile-dialog.component.js +1 -1
- package/dist/lib/resource-wrappers/chat-conversations-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/chat-conversations-resource.component.js +13 -12
- package/dist/lib/resource-wrappers/chat-conversations-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/chat-deeplink-params.d.ts +24 -0
- package/dist/lib/resource-wrappers/chat-deeplink-params.d.ts.map +1 -0
- package/dist/lib/resource-wrappers/chat-deeplink-params.js +27 -0
- package/dist/lib/resource-wrappers/chat-deeplink-params.js.map +1 -0
- package/dist/lib/resource-wrappers/dashboard-resource.component.d.ts +7 -0
- package/dist/lib/resource-wrappers/dashboard-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/dashboard-resource.component.js +29 -14
- package/dist/lib/resource-wrappers/dashboard-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/list-detail-resource.component.js +1 -1
- package/dist/lib/resource-wrappers/list-detail-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/query-resource.component.js +1 -1
- package/dist/lib/resource-wrappers/query-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/record-resource.component.d.ts +3 -0
- package/dist/lib/resource-wrappers/record-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/record-resource.component.js +18 -4
- package/dist/lib/resource-wrappers/record-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/search-results-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/search-results-resource.component.js +6 -2
- package/dist/lib/resource-wrappers/search-results-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/view-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/view-resource.component.js +6 -3
- package/dist/lib/resource-wrappers/view-resource.component.js.map +1 -1
- package/dist/lib/server-connectivity/server-connectivity-banner.component.d.ts +20 -8
- package/dist/lib/server-connectivity/server-connectivity-banner.component.d.ts.map +1 -1
- package/dist/lib/server-connectivity/server-connectivity-banner.component.js +25 -20
- package/dist/lib/server-connectivity/server-connectivity-banner.component.js.map +1 -1
- package/dist/lib/shell/components/dialogs/app-access-dialog.component.js +2 -2
- package/dist/lib/shell/components/dialogs/app-access-dialog.component.js.map +1 -1
- package/dist/lib/shell/components/header/app-nav.component.js +1 -1
- package/dist/lib/shell/components/header/app-switcher.component.js +82 -83
- package/dist/lib/shell/components/header/app-switcher.component.js.map +1 -1
- package/dist/lib/shell/components/record-open/record-bar.component.js +1 -1
- package/dist/lib/shell/components/record-open/record-origin-crumb.component.js +1 -1
- package/dist/lib/shell/components/record-open/record-switcher-sheet.component.js +1 -1
- package/dist/lib/shell/components/record-open/records-hub-pill.component.js +1 -1
- package/dist/lib/shell/components/tabs/tab-container.component.d.ts +25 -0
- package/dist/lib/shell/components/tabs/tab-container.component.d.ts.map +1 -1
- package/dist/lib/shell/components/tabs/tab-container.component.js +88 -4
- package/dist/lib/shell/components/tabs/tab-container.component.js.map +1 -1
- package/dist/lib/shell/services/sharing-center-dialog-host.component.js +2 -2
- package/dist/lib/shell/services/sharing-center-dialog-host.component.js.map +1 -1
- package/dist/lib/shell/shell-chrome-policy.d.ts +54 -0
- package/dist/lib/shell/shell-chrome-policy.d.ts.map +1 -0
- package/dist/lib/shell/shell-chrome-policy.js +62 -0
- package/dist/lib/shell/shell-chrome-policy.js.map +1 -0
- package/dist/lib/shell/shell.component.d.ts +42 -0
- package/dist/lib/shell/shell.component.d.ts.map +1 -1
- package/dist/lib/shell/shell.component.js +394 -255
- package/dist/lib/shell/shell.component.js.map +1 -1
- package/dist/lib/single-dashboard/Components/edit-dashboard/edit-dashboard.component.js +1 -1
- package/dist/lib/single-dashboard/single-dashboard.component.js +1 -1
- package/dist/lib/single-list-detail/single-list-detail.component.d.ts +9 -0
- package/dist/lib/single-list-detail/single-list-detail.component.d.ts.map +1 -1
- package/dist/lib/single-list-detail/single-list-detail.component.js +34 -15
- package/dist/lib/single-list-detail/single-list-detail.component.js.map +1 -1
- package/dist/lib/single-record/single-record.component.d.ts +10 -0
- package/dist/lib/single-record/single-record.component.d.ts.map +1 -1
- package/dist/lib/single-record/single-record.component.js +23 -3
- package/dist/lib/single-record/single-record.component.js.map +1 -1
- 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 +5 -2
- package/dist/lib/single-search-result/single-search-result.component.js.map +1 -1
- package/dist/lib/user-notifications/user-notifications.component.js +11 -12
- package/dist/lib/user-notifications/user-notifications.component.js.map +1 -1
- package/dist/lib/user-profile/user-profile.component.js +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 +62 -62
|
@@ -14,6 +14,7 @@ import { BaseUserMenu, isUserMenuDivider } from '../user-menu';
|
|
|
14
14
|
import { InstanceConfigEngine, UserInfoEngine } from '@memberjunction/core-entities';
|
|
15
15
|
import { PACKAGE_VERSION } from '@memberjunction/graphql-dataprovider';
|
|
16
16
|
import { BaseAngularComponent } from '@memberjunction/ng-base-types';
|
|
17
|
+
import { ApplyShellChromePolicy, BaseShellChromePolicy } from './shell-chrome-policy';
|
|
17
18
|
import * as i0 from "@angular/core";
|
|
18
19
|
import * as i1 from "@memberjunction/ng-base-application";
|
|
19
20
|
import * as i2 from "@memberjunction/ng-shared";
|
|
@@ -39,14 +40,16 @@ import * as i21 from "./components/dialogs/app-access-dialog.component";
|
|
|
39
40
|
import * as i22 from "../command-palette/command-palette.component";
|
|
40
41
|
import * as i23 from "../omnibar/omnibar-palette.component";
|
|
41
42
|
const _c0 = ["searchInput"];
|
|
42
|
-
const _c1 = ["
|
|
43
|
-
const _c2 = ["
|
|
44
|
-
const _c3 = ["
|
|
43
|
+
const _c1 = ["mobileNavDrawer"];
|
|
44
|
+
const _c2 = ["mobileNavToggle"];
|
|
45
|
+
const _c3 = ["omnibarPalette"];
|
|
46
|
+
const _c4 = ["shellSearchComposite"];
|
|
47
|
+
const _c5 = ["appAccessDialog"];
|
|
45
48
|
const _forTrack0 = ($index, $item) => $item.ID;
|
|
46
|
-
function
|
|
49
|
+
function ShellComponent_Conditional_8_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
47
50
|
const _r2 = i0.ɵɵgetCurrentView();
|
|
48
|
-
i0.ɵɵelementStart(0, "button",
|
|
49
|
-
i0.ɵɵlistener("click", function
|
|
51
|
+
i0.ɵɵelementStart(0, "button", 50);
|
|
52
|
+
i0.ɵɵlistener("click", function ShellComponent_Conditional_8_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_8_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)); });
|
|
50
53
|
i0.ɵɵelement(1, "i");
|
|
51
54
|
i0.ɵɵelementEnd();
|
|
52
55
|
} if (rf & 2) {
|
|
@@ -59,32 +62,32 @@ function ShellComponent_Conditional_5_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
|
59
62
|
i0.ɵɵadvance();
|
|
60
63
|
i0.ɵɵclassMap(app_r3.Icon);
|
|
61
64
|
} }
|
|
62
|
-
function
|
|
63
|
-
i0.ɵɵelementStart(0, "div",
|
|
64
|
-
i0.ɵɵrepeaterCreate(1,
|
|
65
|
+
function ShellComponent_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
66
|
+
i0.ɵɵelementStart(0, "div", 12);
|
|
67
|
+
i0.ɵɵrepeaterCreate(1, ShellComponent_Conditional_8_For_2_Template, 2, 8, "button", 49, i0.ɵɵrepeaterTrackByIdentity);
|
|
65
68
|
i0.ɵɵelementEnd();
|
|
66
69
|
} if (rf & 2) {
|
|
67
70
|
const ctx_r3 = i0.ɵɵnextContext();
|
|
68
71
|
i0.ɵɵadvance();
|
|
69
72
|
i0.ɵɵrepeater(ctx_r3.leftOfSwitcherApps);
|
|
70
73
|
} }
|
|
71
|
-
function
|
|
74
|
+
function ShellComponent_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
72
75
|
const _r5 = i0.ɵɵgetCurrentView();
|
|
73
|
-
i0.ɵɵelementStart(0, "mj-app-switcher",
|
|
74
|
-
i0.ɵɵlistener("appSelected", function
|
|
76
|
+
i0.ɵɵelementStart(0, "mj-app-switcher", 51);
|
|
77
|
+
i0.ɵɵlistener("appSelected", function ShellComponent_Conditional_9_Template_mj_app_switcher_appSelected_0_listener($event) { i0.ɵɵrestoreView(_r5); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onAppSwitch($event)); });
|
|
75
78
|
i0.ɵɵelementEnd();
|
|
76
79
|
} if (rf & 2) {
|
|
77
80
|
const ctx_r3 = i0.ɵɵnextContext();
|
|
78
81
|
i0.ɵɵproperty("activeApp", ctx_r3.activeApp)("isViewingSystemTab", ctx_r3.isViewingSystemTab)("loadingAppId", ctx_r3.loadingAppId)("SwitcherStyle", ctx_r3.AppSwitcherStyle)("Provider", ctx_r3.Provider);
|
|
79
82
|
} }
|
|
80
|
-
function
|
|
83
|
+
function ShellComponent_Conditional_10_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
81
84
|
i0.ɵɵelement(0, "mj-records-hub-pill");
|
|
82
85
|
} }
|
|
83
|
-
function
|
|
86
|
+
function ShellComponent_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
84
87
|
const _r6 = i0.ɵɵgetCurrentView();
|
|
85
|
-
i0.ɵɵelementStart(0, "mj-app-nav",
|
|
86
|
-
i0.ɵɵlistener("navItemClick", function
|
|
87
|
-
i0.ɵɵconditionalCreate(1,
|
|
88
|
+
i0.ɵɵelementStart(0, "mj-app-nav", 52);
|
|
89
|
+
i0.ɵɵlistener("navItemClick", function ShellComponent_Conditional_10_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_10_Template_mj_app_nav_navItemDismiss_0_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onNavItemDismiss($event)); });
|
|
90
|
+
i0.ɵɵconditionalCreate(1, ShellComponent_Conditional_10_Conditional_1_Template, 1, 0, "mj-records-hub-pill");
|
|
88
91
|
i0.ɵɵelementEnd();
|
|
89
92
|
} if (rf & 2) {
|
|
90
93
|
const ctx_r3 = i0.ɵɵnextContext();
|
|
@@ -92,18 +95,18 @@ function ShellComponent_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
|
92
95
|
i0.ɵɵadvance();
|
|
93
96
|
i0.ɵɵconditional(ctx_r3.RecordTabsStyle ? 1 : -1);
|
|
94
97
|
} }
|
|
95
|
-
function
|
|
96
|
-
i0.ɵɵelement(0, "mj-records-hub-pill",
|
|
98
|
+
function ShellComponent_Conditional_11_Template(rf, ctx) { if (rf & 1) {
|
|
99
|
+
i0.ɵɵelement(0, "mj-records-hub-pill", 15);
|
|
97
100
|
} }
|
|
98
|
-
function
|
|
101
|
+
function ShellComponent_Conditional_14_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
99
102
|
const _r7 = i0.ɵɵgetCurrentView();
|
|
100
|
-
i0.ɵɵelementStart(0, "button",
|
|
101
|
-
i0.ɵɵlistener("click", function
|
|
102
|
-
i0.ɵɵelement(1, "i",
|
|
103
|
-
i0.ɵɵelementStart(2, "span",
|
|
103
|
+
i0.ɵɵelementStart(0, "button", 54);
|
|
104
|
+
i0.ɵɵlistener("click", function ShellComponent_Conditional_14_Conditional_0_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r7); const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.OnHeaderSearchClick()); });
|
|
105
|
+
i0.ɵɵelement(1, "i", 55);
|
|
106
|
+
i0.ɵɵelementStart(2, "span", 56);
|
|
104
107
|
i0.ɵɵtext(3, "Search everything");
|
|
105
108
|
i0.ɵɵelementEnd();
|
|
106
|
-
i0.ɵɵelementStart(4, "kbd",
|
|
109
|
+
i0.ɵɵelementStart(4, "kbd", 57);
|
|
107
110
|
i0.ɵɵtext(5);
|
|
108
111
|
i0.ɵɵelementEnd()();
|
|
109
112
|
} if (rf & 2) {
|
|
@@ -112,14 +115,14 @@ function ShellComponent_Conditional_11_Conditional_0_Template(rf, ctx) { if (rf
|
|
|
112
115
|
i0.ɵɵadvance(5);
|
|
113
116
|
i0.ɵɵtextInterpolate(ctx_r3.OmnibarShortcutLabel);
|
|
114
117
|
} }
|
|
115
|
-
function
|
|
118
|
+
function ShellComponent_Conditional_14_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
116
119
|
const _r8 = i0.ɵɵgetCurrentView();
|
|
117
|
-
i0.ɵɵelementStart(0, "div",
|
|
118
|
-
i0.ɵɵlistener("ResultSelected", function
|
|
120
|
+
i0.ɵɵelementStart(0, "div", 58)(1, "mj-search-composite", 59, 4);
|
|
121
|
+
i0.ɵɵlistener("ResultSelected", function ShellComponent_Conditional_14_Conditional_1_Template_mj_search_composite_ResultSelected_1_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.OnSearchResultSelected($event)); })("SearchSubmitted", function ShellComponent_Conditional_14_Conditional_1_Template_mj_search_composite_SearchSubmitted_1_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.OnSearchSubmitted($event)); })("SeeAllRequested", function ShellComponent_Conditional_14_Conditional_1_Template_mj_search_composite_SeeAllRequested_1_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.OnSeeAllSearch($event)); })("RecentRecordSelected", function ShellComponent_Conditional_14_Conditional_1_Template_mj_search_composite_RecentRecordSelected_1_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.OnSearchResultSelected($event)); })("PromoAccepted", function ShellComponent_Conditional_14_Conditional_1_Template_mj_search_composite_PromoAccepted_1_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.OnOmnibarPromoAccepted($event)); })("PromoDismissed", function ShellComponent_Conditional_14_Conditional_1_Template_mj_search_composite_PromoDismissed_1_listener() { i0.ɵɵrestoreView(_r8); const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.OnOmnibarPromoDismissed()); });
|
|
119
122
|
i0.ɵɵelementEnd()();
|
|
120
|
-
i0.ɵɵelementStart(3, "button",
|
|
121
|
-
i0.ɵɵlistener("click", function
|
|
122
|
-
i0.ɵɵelement(4, "i",
|
|
123
|
+
i0.ɵɵelementStart(3, "button", 60);
|
|
124
|
+
i0.ɵɵlistener("click", function ShellComponent_Conditional_14_Conditional_1_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r8); const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.OnHeaderSearchClick()); });
|
|
125
|
+
i0.ɵɵelement(4, "i", 55);
|
|
123
126
|
i0.ɵɵelementEnd();
|
|
124
127
|
} if (rf & 2) {
|
|
125
128
|
const ctx_r3 = i0.ɵɵnextContext(2);
|
|
@@ -128,14 +131,14 @@ function ShellComponent_Conditional_11_Conditional_1_Template(rf, ctx) { if (rf
|
|
|
128
131
|
i0.ɵɵadvance(2);
|
|
129
132
|
i0.ɵɵattribute("aria-label", "Search everything (" + ctx_r3.OmnibarShortcutLabel + ")");
|
|
130
133
|
} }
|
|
131
|
-
function
|
|
132
|
-
i0.ɵɵconditionalCreate(0,
|
|
134
|
+
function ShellComponent_Conditional_14_Template(rf, ctx) { if (rf & 1) {
|
|
135
|
+
i0.ɵɵconditionalCreate(0, ShellComponent_Conditional_14_Conditional_0_Template, 6, 2, "button", 53)(1, ShellComponent_Conditional_14_Conditional_1_Template, 5, 7);
|
|
133
136
|
} if (rf & 2) {
|
|
134
137
|
const ctx_r3 = i0.ɵɵnextContext();
|
|
135
138
|
i0.ɵɵconditional(ctx_r3.UseOmnibar ? 0 : 1);
|
|
136
139
|
} }
|
|
137
|
-
function
|
|
138
|
-
i0.ɵɵelementStart(0, "span",
|
|
140
|
+
function ShellComponent_Conditional_15_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
141
|
+
i0.ɵɵelementStart(0, "span", 63);
|
|
139
142
|
i0.ɵɵtext(1);
|
|
140
143
|
i0.ɵɵelementEnd();
|
|
141
144
|
} if (rf & 2) {
|
|
@@ -143,8 +146,8 @@ function ShellComponent_Conditional_12_Conditional_3_Template(rf, ctx) { if (rf
|
|
|
143
146
|
i0.ɵɵadvance();
|
|
144
147
|
i0.ɵɵtextInterpolate(ctx_r3.activityRunningCount);
|
|
145
148
|
} }
|
|
146
|
-
function
|
|
147
|
-
i0.ɵɵelementStart(0, "div",
|
|
149
|
+
function ShellComponent_Conditional_15_Conditional_4_For_8_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
150
|
+
i0.ɵɵelementStart(0, "div", 75);
|
|
148
151
|
i0.ɵɵtext(1);
|
|
149
152
|
i0.ɵɵelementEnd();
|
|
150
153
|
} if (rf & 2) {
|
|
@@ -152,23 +155,23 @@ function ShellComponent_Conditional_12_Conditional_4_For_8_Conditional_5_Templat
|
|
|
152
155
|
i0.ɵɵadvance();
|
|
153
156
|
i0.ɵɵtextInterpolate(a_r11.Detail);
|
|
154
157
|
} }
|
|
155
|
-
function
|
|
156
|
-
i0.ɵɵelementStart(0, "div",
|
|
157
|
-
i0.ɵɵelement(1, "div",
|
|
158
|
+
function ShellComponent_Conditional_15_Conditional_4_For_8_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
159
|
+
i0.ɵɵelementStart(0, "div", 76);
|
|
160
|
+
i0.ɵɵelement(1, "div", 77);
|
|
158
161
|
i0.ɵɵelementEnd();
|
|
159
162
|
} if (rf & 2) {
|
|
160
163
|
const a_r11 = i0.ɵɵnextContext().$implicit;
|
|
161
164
|
i0.ɵɵadvance();
|
|
162
165
|
i0.ɵɵstyleProp("width", a_r11.Progress, "%");
|
|
163
166
|
} }
|
|
164
|
-
function
|
|
165
|
-
i0.ɵɵelementStart(0, "div",
|
|
166
|
-
i0.ɵɵelement(1, "i",
|
|
167
|
-
i0.ɵɵelementStart(2, "div",
|
|
167
|
+
function ShellComponent_Conditional_15_Conditional_4_For_8_Template(rf, ctx) { if (rf & 1) {
|
|
168
|
+
i0.ɵɵelementStart(0, "div", 71);
|
|
169
|
+
i0.ɵɵelement(1, "i", 72);
|
|
170
|
+
i0.ɵɵelementStart(2, "div", 73)(3, "div", 74);
|
|
168
171
|
i0.ɵɵtext(4);
|
|
169
172
|
i0.ɵɵelementEnd();
|
|
170
|
-
i0.ɵɵconditionalCreate(5,
|
|
171
|
-
i0.ɵɵconditionalCreate(6,
|
|
173
|
+
i0.ɵɵconditionalCreate(5, ShellComponent_Conditional_15_Conditional_4_For_8_Conditional_5_Template, 2, 1, "div", 75);
|
|
174
|
+
i0.ɵɵconditionalCreate(6, ShellComponent_Conditional_15_Conditional_4_For_8_Conditional_6_Template, 2, 2, "div", 76);
|
|
172
175
|
i0.ɵɵelementEnd()();
|
|
173
176
|
} if (rf & 2) {
|
|
174
177
|
const a_r11 = ctx.$implicit;
|
|
@@ -182,33 +185,33 @@ function ShellComponent_Conditional_12_Conditional_4_For_8_Template(rf, ctx) { i
|
|
|
182
185
|
i0.ɵɵadvance();
|
|
183
186
|
i0.ɵɵconditional(a_r11.Status === "running" && a_r11.Progress != null ? 6 : -1);
|
|
184
187
|
} }
|
|
185
|
-
function
|
|
188
|
+
function ShellComponent_Conditional_15_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
186
189
|
const _r10 = i0.ɵɵgetCurrentView();
|
|
187
|
-
i0.ɵɵelementStart(0, "div",
|
|
188
|
-
i0.ɵɵlistener("click", function
|
|
189
|
-
i0.ɵɵelementStart(1, "div",
|
|
190
|
+
i0.ɵɵelementStart(0, "div", 65);
|
|
191
|
+
i0.ɵɵlistener("click", function ShellComponent_Conditional_15_Conditional_4_Template_div_click_0_listener($event) { return $event.stopPropagation(); });
|
|
192
|
+
i0.ɵɵelementStart(1, "div", 66)(2, "span");
|
|
190
193
|
i0.ɵɵtext(3, "Activity");
|
|
191
194
|
i0.ɵɵelementEnd();
|
|
192
|
-
i0.ɵɵelementStart(4, "button",
|
|
193
|
-
i0.ɵɵlistener("click", function
|
|
194
|
-
i0.ɵɵelement(5, "i",
|
|
195
|
+
i0.ɵɵelementStart(4, "button", 67);
|
|
196
|
+
i0.ɵɵlistener("click", function ShellComponent_Conditional_15_Conditional_4_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r10); const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.clearFinishedActivity()); });
|
|
197
|
+
i0.ɵɵelement(5, "i", 68);
|
|
195
198
|
i0.ɵɵelementEnd()();
|
|
196
|
-
i0.ɵɵelementStart(6, "div",
|
|
197
|
-
i0.ɵɵrepeaterCreate(7,
|
|
199
|
+
i0.ɵɵelementStart(6, "div", 69);
|
|
200
|
+
i0.ɵɵrepeaterCreate(7, ShellComponent_Conditional_15_Conditional_4_For_8_Template, 7, 7, "div", 70, _forTrack0);
|
|
198
201
|
i0.ɵɵelementEnd()();
|
|
199
202
|
} if (rf & 2) {
|
|
200
203
|
const ctx_r3 = i0.ɵɵnextContext(2);
|
|
201
204
|
i0.ɵɵadvance(7);
|
|
202
205
|
i0.ɵɵrepeater(ctx_r3.activityItems);
|
|
203
206
|
} }
|
|
204
|
-
function
|
|
207
|
+
function ShellComponent_Conditional_15_Template(rf, ctx) { if (rf & 1) {
|
|
205
208
|
const _r9 = i0.ɵɵgetCurrentView();
|
|
206
|
-
i0.ɵɵelementStart(0, "div",
|
|
207
|
-
i0.ɵɵlistener("click", function
|
|
208
|
-
i0.ɵɵelement(2, "i",
|
|
209
|
-
i0.ɵɵconditionalCreate(3,
|
|
209
|
+
i0.ɵɵelementStart(0, "div", 18)(1, "button", 61);
|
|
210
|
+
i0.ɵɵlistener("click", function ShellComponent_Conditional_15_Template_button_click_1_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.toggleActivity($event)); });
|
|
211
|
+
i0.ɵɵelement(2, "i", 62);
|
|
212
|
+
i0.ɵɵconditionalCreate(3, ShellComponent_Conditional_15_Conditional_3_Template, 2, 1, "span", 63);
|
|
210
213
|
i0.ɵɵelementEnd();
|
|
211
|
-
i0.ɵɵconditionalCreate(4,
|
|
214
|
+
i0.ɵɵconditionalCreate(4, ShellComponent_Conditional_15_Conditional_4_Template, 9, 0, "div", 64);
|
|
212
215
|
i0.ɵɵelementEnd();
|
|
213
216
|
} if (rf & 2) {
|
|
214
217
|
const ctx_r3 = i0.ɵɵnextContext();
|
|
@@ -219,8 +222,8 @@ function ShellComponent_Conditional_12_Template(rf, ctx) { if (rf & 1) {
|
|
|
219
222
|
i0.ɵɵadvance();
|
|
220
223
|
i0.ɵɵconditional(ctx_r3.activityOpen ? 4 : -1);
|
|
221
224
|
} }
|
|
222
|
-
function
|
|
223
|
-
i0.ɵɵelementStart(0, "span",
|
|
225
|
+
function ShellComponent_Conditional_16_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
226
|
+
i0.ɵɵelementStart(0, "span", 80);
|
|
224
227
|
i0.ɵɵtext(1);
|
|
225
228
|
i0.ɵɵelementEnd();
|
|
226
229
|
} if (rf & 2) {
|
|
@@ -228,22 +231,22 @@ function ShellComponent_Conditional_13_Conditional_2_Template(rf, ctx) { if (rf
|
|
|
228
231
|
i0.ɵɵadvance();
|
|
229
232
|
i0.ɵɵtextInterpolate1(" ", ctx_r3.unreadNotificationCount > 99 ? "99+" : ctx_r3.unreadNotificationCount, " ");
|
|
230
233
|
} }
|
|
231
|
-
function
|
|
234
|
+
function ShellComponent_Conditional_16_Template(rf, ctx) { if (rf & 1) {
|
|
232
235
|
const _r12 = i0.ɵɵgetCurrentView();
|
|
233
|
-
i0.ɵɵelementStart(0, "button",
|
|
234
|
-
i0.ɵɵlistener("click", function
|
|
235
|
-
i0.ɵɵelement(1, "i",
|
|
236
|
-
i0.ɵɵconditionalCreate(2,
|
|
236
|
+
i0.ɵɵelementStart(0, "button", 78);
|
|
237
|
+
i0.ɵɵlistener("click", function ShellComponent_Conditional_16_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r12); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.showNotifications()); });
|
|
238
|
+
i0.ɵɵelement(1, "i", 79);
|
|
239
|
+
i0.ɵɵconditionalCreate(2, ShellComponent_Conditional_16_Conditional_2_Template, 2, 1, "span", 80);
|
|
237
240
|
i0.ɵɵelementEnd();
|
|
238
241
|
} if (rf & 2) {
|
|
239
242
|
const ctx_r3 = i0.ɵɵnextContext();
|
|
240
243
|
i0.ɵɵadvance(2);
|
|
241
244
|
i0.ɵɵconditional(ctx_r3.unreadNotificationCount > 0 ? 2 : -1);
|
|
242
245
|
} }
|
|
243
|
-
function
|
|
246
|
+
function ShellComponent_Conditional_17_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
244
247
|
const _r13 = i0.ɵɵgetCurrentView();
|
|
245
|
-
i0.ɵɵelementStart(0, "button",
|
|
246
|
-
i0.ɵɵlistener("click", function
|
|
248
|
+
i0.ɵɵelementStart(0, "button", 50);
|
|
249
|
+
i0.ɵɵlistener("click", function ShellComponent_Conditional_17_For_2_Template_button_click_0_listener($event) { const app_r14 = i0.ɵɵrestoreView(_r13).$implicit; const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.onNavBarAppClick(app_r14, $event)); })("dblclick", function ShellComponent_Conditional_17_For_2_Template_button_dblclick_0_listener($event) { const app_r14 = i0.ɵɵrestoreView(_r13).$implicit; const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.onNavBarAppDblClick(app_r14, $event)); });
|
|
247
250
|
i0.ɵɵelement(1, "i");
|
|
248
251
|
i0.ɵɵelementEnd();
|
|
249
252
|
} if (rf & 2) {
|
|
@@ -256,23 +259,23 @@ function ShellComponent_Conditional_14_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
|
256
259
|
i0.ɵɵadvance();
|
|
257
260
|
i0.ɵɵclassMap(app_r14.Icon);
|
|
258
261
|
} }
|
|
259
|
-
function
|
|
260
|
-
i0.ɵɵelementStart(0, "div",
|
|
261
|
-
i0.ɵɵrepeaterCreate(1,
|
|
262
|
+
function ShellComponent_Conditional_17_Template(rf, ctx) { if (rf & 1) {
|
|
263
|
+
i0.ɵɵelementStart(0, "div", 20);
|
|
264
|
+
i0.ɵɵrepeaterCreate(1, ShellComponent_Conditional_17_For_2_Template, 2, 8, "button", 49, i0.ɵɵrepeaterTrackByIdentity);
|
|
262
265
|
i0.ɵɵelementEnd();
|
|
263
266
|
} if (rf & 2) {
|
|
264
267
|
const ctx_r3 = i0.ɵɵnextContext();
|
|
265
268
|
i0.ɵɵadvance();
|
|
266
269
|
i0.ɵɵrepeater(ctx_r3.leftOfUserMenuApps);
|
|
267
270
|
} }
|
|
268
|
-
function
|
|
269
|
-
i0.ɵɵelement(0, "img",
|
|
271
|
+
function ShellComponent_Conditional_20_Template(rf, ctx) { if (rf & 1) {
|
|
272
|
+
i0.ɵɵelement(0, "img", 23);
|
|
270
273
|
} if (rf & 2) {
|
|
271
274
|
const ctx_r3 = i0.ɵɵnextContext();
|
|
272
275
|
i0.ɵɵproperty("src", ctx_r3.userImageURL, i0.ɵɵsanitizeUrl);
|
|
273
276
|
} }
|
|
274
|
-
function
|
|
275
|
-
i0.ɵɵelementStart(0, "div",
|
|
277
|
+
function ShellComponent_Conditional_21_Template(rf, ctx) { if (rf & 1) {
|
|
278
|
+
i0.ɵɵelementStart(0, "div", 24);
|
|
276
279
|
i0.ɵɵelement(1, "i");
|
|
277
280
|
i0.ɵɵelementEnd();
|
|
278
281
|
} if (rf & 2) {
|
|
@@ -280,59 +283,59 @@ function ShellComponent_Conditional_18_Template(rf, ctx) { if (rf & 1) {
|
|
|
280
283
|
i0.ɵɵadvance();
|
|
281
284
|
i0.ɵɵclassMap(ctx_r3.userIconClass || "fa-solid fa-user");
|
|
282
285
|
} }
|
|
283
|
-
function
|
|
284
|
-
i0.ɵɵelementStart(0, "span",
|
|
286
|
+
function ShellComponent_Conditional_22_Conditional_1_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
287
|
+
i0.ɵɵelementStart(0, "span", 85);
|
|
285
288
|
i0.ɵɵtext(1);
|
|
286
289
|
i0.ɵɵelementEnd();
|
|
287
290
|
} if (rf & 2) {
|
|
288
|
-
let
|
|
291
|
+
let tmp_7_0;
|
|
289
292
|
const ctx_r3 = i0.ɵɵnextContext(3);
|
|
290
293
|
i0.ɵɵadvance();
|
|
291
|
-
i0.ɵɵtextInterpolate1(" ", (
|
|
294
|
+
i0.ɵɵtextInterpolate1(" ", (tmp_7_0 = ctx_r3.getUserDisplayInfo()) == null ? null : tmp_7_0.email, " ");
|
|
292
295
|
} }
|
|
293
|
-
function
|
|
294
|
-
i0.ɵɵelementStart(0, "span",
|
|
296
|
+
function ShellComponent_Conditional_22_Conditional_1_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
297
|
+
i0.ɵɵelementStart(0, "span", 86);
|
|
295
298
|
i0.ɵɵtext(1);
|
|
296
299
|
i0.ɵɵelementEnd();
|
|
297
300
|
} if (rf & 2) {
|
|
298
|
-
let
|
|
301
|
+
let tmp_7_0;
|
|
299
302
|
const ctx_r3 = i0.ɵɵnextContext(3);
|
|
300
303
|
i0.ɵɵadvance();
|
|
301
|
-
i0.ɵɵtextInterpolate((
|
|
304
|
+
i0.ɵɵtextInterpolate((tmp_7_0 = ctx_r3.getUserDisplayInfo()) == null ? null : tmp_7_0.subtitle);
|
|
302
305
|
} }
|
|
303
|
-
function
|
|
304
|
-
i0.ɵɵelementStart(0, "div",
|
|
306
|
+
function ShellComponent_Conditional_22_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
307
|
+
i0.ɵɵelementStart(0, "div", 82)(1, "div", 83)(2, "span", 84);
|
|
305
308
|
i0.ɵɵtext(3);
|
|
306
309
|
i0.ɵɵelementEnd();
|
|
307
|
-
i0.ɵɵconditionalCreate(4,
|
|
308
|
-
i0.ɵɵconditionalCreate(5,
|
|
310
|
+
i0.ɵɵconditionalCreate(4, ShellComponent_Conditional_22_Conditional_1_Conditional_4_Template, 2, 1, "span", 85);
|
|
311
|
+
i0.ɵɵconditionalCreate(5, ShellComponent_Conditional_22_Conditional_1_Conditional_5_Template, 2, 1, "span", 86);
|
|
309
312
|
i0.ɵɵelementEnd()();
|
|
310
|
-
i0.ɵɵelement(6, "div",
|
|
313
|
+
i0.ɵɵelement(6, "div", 87);
|
|
311
314
|
} if (rf & 2) {
|
|
312
|
-
let tmp_5_0;
|
|
313
315
|
let tmp_6_0;
|
|
314
316
|
let tmp_7_0;
|
|
317
|
+
let tmp_8_0;
|
|
315
318
|
const ctx_r3 = i0.ɵɵnextContext(2);
|
|
316
319
|
i0.ɵɵadvance(3);
|
|
317
|
-
i0.ɵɵtextInterpolate(((
|
|
320
|
+
i0.ɵɵtextInterpolate(((tmp_6_0 = ctx_r3.getUserDisplayInfo()) == null ? null : tmp_6_0.name) || ctx_r3.userName);
|
|
318
321
|
i0.ɵɵadvance();
|
|
319
|
-
i0.ɵɵconditional(((
|
|
322
|
+
i0.ɵɵconditional(((tmp_7_0 = ctx_r3.getUserMenuOptions()) == null ? null : tmp_7_0.showUserEmail) && ((tmp_7_0 = ctx_r3.getUserDisplayInfo()) == null ? null : tmp_7_0.email) ? 4 : -1);
|
|
320
323
|
i0.ɵɵadvance();
|
|
321
|
-
i0.ɵɵconditional(((
|
|
324
|
+
i0.ɵɵconditional(((tmp_8_0 = ctx_r3.getUserDisplayInfo()) == null ? null : tmp_8_0.subtitle) ? 5 : -1);
|
|
322
325
|
} }
|
|
323
|
-
function
|
|
324
|
-
i0.ɵɵelement(0, "div",
|
|
326
|
+
function ShellComponent_Conditional_22_For_3_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
327
|
+
i0.ɵɵelement(0, "div", 87);
|
|
325
328
|
} }
|
|
326
|
-
function
|
|
329
|
+
function ShellComponent_Conditional_22_For_3_Conditional_1_Conditional_0_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
327
330
|
const _r15 = i0.ɵɵgetCurrentView();
|
|
328
|
-
i0.ɵɵelementStart(0, "div",
|
|
329
|
-
i0.ɵɵlistener("click", function
|
|
331
|
+
i0.ɵɵelementStart(0, "div", 90);
|
|
332
|
+
i0.ɵɵlistener("click", function ShellComponent_Conditional_22_For_3_Conditional_1_Conditional_0_Conditional_0_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r15); const item_r16 = i0.ɵɵnextContext(); const ctx_r3 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r3.onUserMenuItemClick(item_r16.id)); });
|
|
330
333
|
i0.ɵɵelement(1, "i");
|
|
331
|
-
i0.ɵɵelementStart(2, "span",
|
|
334
|
+
i0.ɵɵelementStart(2, "span", 91);
|
|
332
335
|
i0.ɵɵtext(3);
|
|
333
336
|
i0.ɵɵelementEnd();
|
|
334
|
-
i0.ɵɵelementStart(4, "div",
|
|
335
|
-
i0.ɵɵelement(6, "i",
|
|
337
|
+
i0.ɵɵelementStart(4, "div", 92)(5, "div", 93);
|
|
338
|
+
i0.ɵɵelement(6, "i", 94);
|
|
336
339
|
i0.ɵɵelementEnd()()();
|
|
337
340
|
} if (rf & 2) {
|
|
338
341
|
const item_r16 = i0.ɵɵnextContext();
|
|
@@ -347,8 +350,8 @@ function ShellComponent_Conditional_19_For_3_Conditional_1_Conditional_0_Conditi
|
|
|
347
350
|
i0.ɵɵadvance(2);
|
|
348
351
|
i0.ɵɵclassMap(ctx_r3.IsDarkMode ? "fa-solid fa-moon" : "fa-solid fa-sun");
|
|
349
352
|
} }
|
|
350
|
-
function
|
|
351
|
-
i0.ɵɵelementStart(0, "span",
|
|
353
|
+
function ShellComponent_Conditional_22_For_3_Conditional_1_Conditional_0_Conditional_1_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
354
|
+
i0.ɵɵelementStart(0, "span", 96);
|
|
352
355
|
i0.ɵɵtext(1);
|
|
353
356
|
i0.ɵɵelementEnd();
|
|
354
357
|
} if (rf & 2) {
|
|
@@ -356,15 +359,15 @@ function ShellComponent_Conditional_19_For_3_Conditional_1_Conditional_0_Conditi
|
|
|
356
359
|
i0.ɵɵadvance();
|
|
357
360
|
i0.ɵɵtextInterpolate(item_r16.shortcut);
|
|
358
361
|
} }
|
|
359
|
-
function
|
|
362
|
+
function ShellComponent_Conditional_22_For_3_Conditional_1_Conditional_0_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
360
363
|
const _r17 = i0.ɵɵgetCurrentView();
|
|
361
|
-
i0.ɵɵelementStart(0, "div",
|
|
362
|
-
i0.ɵɵlistener("click", function
|
|
364
|
+
i0.ɵɵelementStart(0, "div", 95);
|
|
365
|
+
i0.ɵɵlistener("click", function ShellComponent_Conditional_22_For_3_Conditional_1_Conditional_0_Conditional_1_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r17); const item_r16 = i0.ɵɵnextContext(); const ctx_r3 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(item_r16.enabled && ctx_r3.onUserMenuItemClick(item_r16.id)); });
|
|
363
366
|
i0.ɵɵelement(1, "i");
|
|
364
|
-
i0.ɵɵelementStart(2, "span",
|
|
367
|
+
i0.ɵɵelementStart(2, "span", 91);
|
|
365
368
|
i0.ɵɵtext(3);
|
|
366
369
|
i0.ɵɵelementEnd();
|
|
367
|
-
i0.ɵɵconditionalCreate(4,
|
|
370
|
+
i0.ɵɵconditionalCreate(4, ShellComponent_Conditional_22_For_3_Conditional_1_Conditional_0_Conditional_1_Conditional_4_Template, 2, 1, "span", 96);
|
|
368
371
|
i0.ɵɵelementEnd();
|
|
369
372
|
} if (rf & 2) {
|
|
370
373
|
const item_r16 = i0.ɵɵnextContext();
|
|
@@ -378,22 +381,22 @@ function ShellComponent_Conditional_19_For_3_Conditional_1_Conditional_0_Conditi
|
|
|
378
381
|
i0.ɵɵadvance();
|
|
379
382
|
i0.ɵɵconditional(item_r16.shortcut ? 4 : -1);
|
|
380
383
|
} }
|
|
381
|
-
function
|
|
382
|
-
i0.ɵɵconditionalCreate(0,
|
|
384
|
+
function ShellComponent_Conditional_22_For_3_Conditional_1_Conditional_0_Template(rf, ctx) { if (rf & 1) {
|
|
385
|
+
i0.ɵɵconditionalCreate(0, ShellComponent_Conditional_22_For_3_Conditional_1_Conditional_0_Conditional_0_Template, 7, 8, "div", 88)(1, ShellComponent_Conditional_22_For_3_Conditional_1_Conditional_0_Conditional_1_Template, 5, 11, "div", 89);
|
|
383
386
|
} if (rf & 2) {
|
|
384
387
|
i0.ɵɵconditional(ctx.id === "toggle-theme" ? 0 : 1);
|
|
385
388
|
} }
|
|
386
|
-
function
|
|
387
|
-
i0.ɵɵconditionalCreate(0,
|
|
389
|
+
function ShellComponent_Conditional_22_For_3_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
390
|
+
i0.ɵɵconditionalCreate(0, ShellComponent_Conditional_22_For_3_Conditional_1_Conditional_0_Template, 2, 1);
|
|
388
391
|
} if (rf & 2) {
|
|
389
|
-
let
|
|
392
|
+
let tmp_16_0;
|
|
390
393
|
const element_r18 = i0.ɵɵnextContext().$implicit;
|
|
391
394
|
const ctx_r3 = i0.ɵɵnextContext(2);
|
|
392
|
-
i0.ɵɵconditional((
|
|
395
|
+
i0.ɵɵconditional((tmp_16_0 = ctx_r3.asMenuItem(element_r18)) ? 0 : -1, tmp_16_0);
|
|
393
396
|
} }
|
|
394
|
-
function
|
|
395
|
-
i0.ɵɵconditionalCreate(0,
|
|
396
|
-
i0.ɵɵconditionalCreate(1,
|
|
397
|
+
function ShellComponent_Conditional_22_For_3_Template(rf, ctx) { if (rf & 1) {
|
|
398
|
+
i0.ɵɵconditionalCreate(0, ShellComponent_Conditional_22_For_3_Conditional_0_Template, 1, 0, "div", 87);
|
|
399
|
+
i0.ɵɵconditionalCreate(1, ShellComponent_Conditional_22_For_3_Conditional_1_Template, 1, 1);
|
|
397
400
|
} if (rf & 2) {
|
|
398
401
|
const element_r18 = ctx.$implicit;
|
|
399
402
|
const ctx_r3 = i0.ɵɵnextContext(2);
|
|
@@ -401,41 +404,41 @@ function ShellComponent_Conditional_19_For_3_Template(rf, ctx) { if (rf & 1) {
|
|
|
401
404
|
i0.ɵɵadvance();
|
|
402
405
|
i0.ɵɵconditional(!ctx_r3.isMenuDivider(element_r18) ? 1 : -1);
|
|
403
406
|
} }
|
|
404
|
-
function
|
|
405
|
-
i0.ɵɵelementStart(0, "div",
|
|
406
|
-
i0.ɵɵconditionalCreate(1,
|
|
407
|
-
i0.ɵɵrepeaterCreate(2,
|
|
407
|
+
function ShellComponent_Conditional_22_Template(rf, ctx) { if (rf & 1) {
|
|
408
|
+
i0.ɵɵelementStart(0, "div", 81);
|
|
409
|
+
i0.ɵɵconditionalCreate(1, ShellComponent_Conditional_22_Conditional_1_Template, 7, 3);
|
|
410
|
+
i0.ɵɵrepeaterCreate(2, ShellComponent_Conditional_22_For_3_Template, 2, 2, null, null, i0.ɵɵrepeaterTrackByIdentity);
|
|
408
411
|
i0.ɵɵelementEnd();
|
|
409
412
|
} if (rf & 2) {
|
|
410
|
-
let tmp_4_0;
|
|
411
413
|
let tmp_5_0;
|
|
412
414
|
let tmp_6_0;
|
|
415
|
+
let tmp_7_0;
|
|
413
416
|
const ctx_r3 = i0.ɵɵnextContext();
|
|
414
|
-
i0.ɵɵclassProp("menu-fade", ((
|
|
417
|
+
i0.ɵɵclassProp("menu-fade", ((tmp_5_0 = ctx_r3.getUserMenuOptions()) == null ? null : tmp_5_0.animationStyle) === "fade")("menu-slide", ((tmp_6_0 = ctx_r3.getUserMenuOptions()) == null ? null : tmp_6_0.animationStyle) === "slide");
|
|
415
418
|
i0.ɵɵadvance();
|
|
416
|
-
i0.ɵɵconditional(((
|
|
419
|
+
i0.ɵɵconditional(((tmp_7_0 = ctx_r3.getUserMenuOptions()) == null ? null : tmp_7_0.showUserName) ? 1 : -1);
|
|
417
420
|
i0.ɵɵadvance();
|
|
418
421
|
i0.ɵɵrepeater(ctx_r3.userMenuElements);
|
|
419
422
|
} }
|
|
420
|
-
function
|
|
423
|
+
function ShellComponent_Conditional_23_Template(rf, ctx) { if (rf & 1) {
|
|
421
424
|
const _r19 = i0.ɵɵgetCurrentView();
|
|
422
|
-
i0.ɵɵelementStart(0, "div",
|
|
423
|
-
i0.ɵɵlistener("click", function
|
|
425
|
+
i0.ɵɵelementStart(0, "div", 97);
|
|
426
|
+
i0.ɵɵlistener("click", function ShellComponent_Conditional_23_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r19); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.closeSearch()); });
|
|
424
427
|
i0.ɵɵelementEnd();
|
|
425
428
|
} }
|
|
426
|
-
function
|
|
429
|
+
function ShellComponent_Conditional_31_Template(rf, ctx) { if (rf & 1) {
|
|
427
430
|
const _r20 = i0.ɵɵgetCurrentView();
|
|
428
|
-
i0.ɵɵelementStart(0, "div",
|
|
429
|
-
i0.ɵɵlistener("click", function
|
|
431
|
+
i0.ɵɵelementStart(0, "div", 98);
|
|
432
|
+
i0.ɵɵlistener("click", function ShellComponent_Conditional_31_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r20); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.closeMobileNav()); });
|
|
430
433
|
i0.ɵɵelementEnd();
|
|
431
434
|
} }
|
|
432
|
-
function
|
|
435
|
+
function ShellComponent_Conditional_39_Template(rf, ctx) { if (rf & 1) {
|
|
433
436
|
const _r21 = i0.ɵɵgetCurrentView();
|
|
434
|
-
i0.ɵɵelementStart(0, "div",
|
|
437
|
+
i0.ɵɵelementStart(0, "div", 38)(1, "div", 99);
|
|
435
438
|
i0.ɵɵtext(2);
|
|
436
439
|
i0.ɵɵelementEnd();
|
|
437
|
-
i0.ɵɵelementStart(3, "mj-app-nav",
|
|
438
|
-
i0.ɵɵlistener("navItemClick", function
|
|
440
|
+
i0.ɵɵelementStart(3, "mj-app-nav", 100);
|
|
441
|
+
i0.ɵɵlistener("navItemClick", function ShellComponent_Conditional_39_Template_mj_app_nav_navItemClick_3_listener($event) { i0.ɵɵrestoreView(_r21); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onNavItemClick($event)); })("navItemDismiss", function ShellComponent_Conditional_39_Template_mj_app_nav_navItemDismiss_3_listener($event) { i0.ɵɵrestoreView(_r21); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.onNavItemDismiss($event)); });
|
|
439
442
|
i0.ɵɵelementEnd()();
|
|
440
443
|
} if (rf & 2) {
|
|
441
444
|
const ctx_r3 = i0.ɵɵnextContext();
|
|
@@ -444,14 +447,14 @@ function ShellComponent_Conditional_35_Template(rf, ctx) { if (rf & 1) {
|
|
|
444
447
|
i0.ɵɵadvance();
|
|
445
448
|
i0.ɵɵproperty("app", ctx_r3.activeApp)("OverflowEnabled", false);
|
|
446
449
|
} }
|
|
447
|
-
function
|
|
450
|
+
function ShellComponent_Conditional_40_Template(rf, ctx) { if (rf & 1) {
|
|
448
451
|
const _r22 = i0.ɵɵgetCurrentView();
|
|
449
|
-
i0.ɵɵelementStart(0, "div",
|
|
450
|
-
i0.ɵɵlistener("Activated", function
|
|
452
|
+
i0.ɵɵelementStart(0, "div", 39)(1, "mj-records-hub-pill", 101);
|
|
453
|
+
i0.ɵɵlistener("Activated", function ShellComponent_Conditional_40_Template_mj_records_hub_pill_Activated_1_listener() { i0.ɵɵrestoreView(_r22); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.closeMobileNav()); });
|
|
451
454
|
i0.ɵɵelementEnd()();
|
|
452
455
|
} }
|
|
453
|
-
function
|
|
454
|
-
i0.ɵɵelementStart(0, "span",
|
|
456
|
+
function ShellComponent_Conditional_46_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
457
|
+
i0.ɵɵelementStart(0, "span", 103);
|
|
455
458
|
i0.ɵɵtext(1);
|
|
456
459
|
i0.ɵɵelementEnd();
|
|
457
460
|
} if (rf & 2) {
|
|
@@ -459,38 +462,38 @@ function ShellComponent_Conditional_42_Conditional_4_Template(rf, ctx) { if (rf
|
|
|
459
462
|
i0.ɵɵadvance();
|
|
460
463
|
i0.ɵɵtextInterpolate1(" ", ctx_r3.unreadNotificationCount > 99 ? "99+" : ctx_r3.unreadNotificationCount, " ");
|
|
461
464
|
} }
|
|
462
|
-
function
|
|
465
|
+
function ShellComponent_Conditional_46_Template(rf, ctx) { if (rf & 1) {
|
|
463
466
|
const _r23 = i0.ɵɵgetCurrentView();
|
|
464
|
-
i0.ɵɵelementStart(0, "button",
|
|
465
|
-
i0.ɵɵlistener("click", function
|
|
466
|
-
i0.ɵɵelement(1, "i",
|
|
467
|
+
i0.ɵɵelementStart(0, "button", 102);
|
|
468
|
+
i0.ɵɵlistener("click", function ShellComponent_Conditional_46_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r23); const ctx_r3 = i0.ɵɵnextContext(); ctx_r3.showNotifications(); return i0.ɵɵresetView(ctx_r3.closeMobileNav()); });
|
|
469
|
+
i0.ɵɵelement(1, "i", 79);
|
|
467
470
|
i0.ɵɵelementStart(2, "span");
|
|
468
471
|
i0.ɵɵtext(3, "Notifications");
|
|
469
472
|
i0.ɵɵelementEnd();
|
|
470
|
-
i0.ɵɵconditionalCreate(4,
|
|
473
|
+
i0.ɵɵconditionalCreate(4, ShellComponent_Conditional_46_Conditional_4_Template, 2, 1, "span", 103);
|
|
471
474
|
i0.ɵɵelementEnd();
|
|
472
475
|
} if (rf & 2) {
|
|
473
476
|
const ctx_r3 = i0.ɵɵnextContext();
|
|
474
477
|
i0.ɵɵadvance(4);
|
|
475
478
|
i0.ɵɵconditional(ctx_r3.unreadNotificationCount > 0 ? 4 : -1);
|
|
476
479
|
} }
|
|
477
|
-
function
|
|
480
|
+
function ShellComponent_Conditional_48_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
478
481
|
const _r24 = i0.ɵɵgetCurrentView();
|
|
479
|
-
i0.ɵɵelementStart(0, "div",
|
|
480
|
-
i0.ɵɵelement(2, "i",
|
|
482
|
+
i0.ɵɵelementStart(0, "div", 105)(1, "p", 107);
|
|
483
|
+
i0.ɵɵelement(2, "i", 108);
|
|
481
484
|
i0.ɵɵtext(3, " Taking longer than expected ");
|
|
482
485
|
i0.ɵɵelementEnd();
|
|
483
|
-
i0.ɵɵelementStart(4, "p",
|
|
486
|
+
i0.ɵɵelementStart(4, "p", 109);
|
|
484
487
|
i0.ɵɵtext(5, " This can happen after updates or due to cached data issues. ");
|
|
485
488
|
i0.ɵɵelementEnd();
|
|
486
|
-
i0.ɵɵelementStart(6, "button",
|
|
487
|
-
i0.ɵɵlistener("click", function
|
|
488
|
-
i0.ɵɵelement(7, "i",
|
|
489
|
+
i0.ɵɵelementStart(6, "button", 110);
|
|
490
|
+
i0.ɵɵlistener("click", function ShellComponent_Conditional_48_Conditional_2_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r24); const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.ResetApplication()); });
|
|
491
|
+
i0.ɵɵelement(7, "i", 111);
|
|
489
492
|
i0.ɵɵtext(8, " Reset ");
|
|
490
493
|
i0.ɵɵelementEnd()();
|
|
491
494
|
} }
|
|
492
|
-
function
|
|
493
|
-
i0.ɵɵelementStart(0, "div",
|
|
495
|
+
function ShellComponent_Conditional_48_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
496
|
+
i0.ɵɵelementStart(0, "div", 106);
|
|
494
497
|
i0.ɵɵtext(1);
|
|
495
498
|
i0.ɵɵelementEnd();
|
|
496
499
|
} if (rf & 2) {
|
|
@@ -498,10 +501,10 @@ function ShellComponent_Conditional_44_Conditional_3_Template(rf, ctx) { if (rf
|
|
|
498
501
|
i0.ɵɵadvance();
|
|
499
502
|
i0.ɵɵtextInterpolate1("MemberJunction \u00B7 v", ctx_r3.MJVersion);
|
|
500
503
|
} }
|
|
501
|
-
function
|
|
502
|
-
i0.ɵɵelementStart(0, "div",
|
|
503
|
-
i0.ɵɵelement(1, "mj-loading",
|
|
504
|
-
i0.ɵɵconditionalCreate(2,
|
|
504
|
+
function ShellComponent_Conditional_48_Template(rf, ctx) { if (rf & 1) {
|
|
505
|
+
i0.ɵɵelementStart(0, "div", 44);
|
|
506
|
+
i0.ɵɵelement(1, "mj-loading", 104);
|
|
507
|
+
i0.ɵɵconditionalCreate(2, ShellComponent_Conditional_48_Conditional_2_Template, 9, 0, "div", 105)(3, ShellComponent_Conditional_48_Conditional_3_Template, 2, 1, "div", 106);
|
|
505
508
|
i0.ɵɵelementEnd();
|
|
506
509
|
} if (rf & 2) {
|
|
507
510
|
const ctx_r3 = i0.ɵɵnextContext();
|
|
@@ -510,21 +513,27 @@ function ShellComponent_Conditional_44_Template(rf, ctx) { if (rf & 1) {
|
|
|
510
513
|
i0.ɵɵadvance();
|
|
511
514
|
i0.ɵɵconditional(ctx_r3.ShowResetOption ? 2 : 3);
|
|
512
515
|
} }
|
|
513
|
-
function
|
|
516
|
+
function ShellComponent_Conditional_52_Template(rf, ctx) { if (rf & 1) {
|
|
514
517
|
const _r25 = i0.ɵɵgetCurrentView();
|
|
515
|
-
i0.ɵɵelementStart(0, "mj-
|
|
516
|
-
i0.ɵɵ
|
|
517
|
-
i0.ɵɵ
|
|
518
|
+
i0.ɵɵelementStart(0, "mj-omnibar-palette", 112, 5);
|
|
519
|
+
i0.ɵɵlistener("SettingsRequested", function ShellComponent_Conditional_52_Template_mj_omnibar_palette_SettingsRequested_0_listener() { i0.ɵɵrestoreView(_r25); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.OnPaletteSettingsRequested()); });
|
|
520
|
+
i0.ɵɵelementEnd();
|
|
521
|
+
} }
|
|
522
|
+
function ShellComponent_Conditional_53_Template(rf, ctx) { if (rf & 1) {
|
|
523
|
+
const _r26 = i0.ɵɵgetCurrentView();
|
|
524
|
+
i0.ɵɵelementStart(0, "mj-search-overlay", 113);
|
|
525
|
+
i0.ɵɵtwoWayListener("IsOpenChange", function ShellComponent_Conditional_53_Template_mj_search_overlay_IsOpenChange_0_listener($event) { i0.ɵɵrestoreView(_r26); const ctx_r3 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r3.LegacySearchOpen, $event) || (ctx_r3.LegacySearchOpen = $event); return i0.ɵɵresetView($event); });
|
|
526
|
+
i0.ɵɵlistener("ResultSelected", function ShellComponent_Conditional_53_Template_mj_search_overlay_ResultSelected_0_listener($event) { i0.ɵɵrestoreView(_r26); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.OnOverlayResultSelected($event)); })("SeeAllRequested", function ShellComponent_Conditional_53_Template_mj_search_overlay_SeeAllRequested_0_listener($event) { i0.ɵɵrestoreView(_r26); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.OnOverlaySeeAll($event)); })("PromoAccepted", function ShellComponent_Conditional_53_Template_mj_search_overlay_PromoAccepted_0_listener($event) { i0.ɵɵrestoreView(_r26); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.OnOmnibarPromoAccepted($event)); })("PromoDismissed", function ShellComponent_Conditional_53_Template_mj_search_overlay_PromoDismissed_0_listener() { i0.ɵɵrestoreView(_r26); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.OnOmnibarPromoDismissed()); });
|
|
518
527
|
i0.ɵɵelementEnd();
|
|
519
528
|
} if (rf & 2) {
|
|
520
529
|
const ctx_r3 = i0.ɵɵnextContext();
|
|
521
530
|
i0.ɵɵtwoWayProperty("IsOpen", ctx_r3.LegacySearchOpen);
|
|
522
531
|
i0.ɵɵproperty("EnableGlobalShortcut", false)("ShowPromo", ctx_r3.ShowOmnibarPromo)("PromoText", ctx_r3.OmnibarPromoText);
|
|
523
532
|
} }
|
|
524
|
-
function
|
|
525
|
-
i0.ɵɵelementStart(0, "div",
|
|
526
|
-
i0.ɵɵelement(2, "mj-loading",
|
|
527
|
-
i0.ɵɵelementStart(3, "span",
|
|
533
|
+
function ShellComponent_Conditional_54_Template(rf, ctx) { if (rf & 1) {
|
|
534
|
+
i0.ɵɵelementStart(0, "div", 48)(1, "div", 114);
|
|
535
|
+
i0.ɵɵelement(2, "mj-loading", 115);
|
|
536
|
+
i0.ɵɵelementStart(3, "span", 116);
|
|
528
537
|
i0.ɵɵtext(4);
|
|
529
538
|
i0.ɵɵelementEnd()()();
|
|
530
539
|
} if (rf & 2) {
|
|
@@ -534,6 +543,14 @@ function ShellComponent_Conditional_51_Template(rf, ctx) { if (rf & 1) {
|
|
|
534
543
|
i0.ɵɵadvance(2);
|
|
535
544
|
i0.ɵɵtextInterpolate(ctx_r3.PinProgressText);
|
|
536
545
|
} }
|
|
546
|
+
/**
|
|
547
|
+
* Main shell component for the new Explorer UX.
|
|
548
|
+
*
|
|
549
|
+
* Provides:
|
|
550
|
+
* - App-centric header with app switcher and nav items
|
|
551
|
+
* - Golden Layout-based tab container
|
|
552
|
+
* - Unified workspace state management
|
|
553
|
+
*/
|
|
537
554
|
export class ShellComponent extends BaseAngularComponent {
|
|
538
555
|
appManager;
|
|
539
556
|
workspaceManager;
|
|
@@ -632,6 +649,9 @@ export class ShellComponent extends BaseAngularComponent {
|
|
|
632
649
|
searchableEntities = [];
|
|
633
650
|
selectedEntity = null;
|
|
634
651
|
searchInput;
|
|
652
|
+
/** Mobile drawer + its toggle — used to return focus to the toggle when the drawer closes. */
|
|
653
|
+
mobileNavDrawer;
|
|
654
|
+
mobileNavToggle;
|
|
635
655
|
// Legacy universal search overlay (omnibar-off MOBILE path) — opened by the
|
|
636
656
|
// mobile search icon or Ctrl/Cmd+K when the inline composite isn't visible.
|
|
637
657
|
// Desktop omnibar-off uses the inline header composite instead.
|
|
@@ -640,11 +660,20 @@ export class ShellComponent extends BaseAngularComponent {
|
|
|
640
660
|
// memoized `chromeFlags` accessor below (see ShellChromeFlags) so Angular's
|
|
641
661
|
// change detection reads a cached field instead of hitting the engine per pass.
|
|
642
662
|
_chromeFlags = null;
|
|
663
|
+
/**
|
|
664
|
+
* The host's chrome policy (see {@link BaseShellChromePolicy}) — the identity unless a host
|
|
665
|
+
* registered a subclass. Consulted on every resolve; its `Changed` drops the cache.
|
|
666
|
+
*/
|
|
667
|
+
chromePolicy = MJGlobal.Instance.ClassFactory.CreateInstance(BaseShellChromePolicy) ?? new BaseShellChromePolicy();
|
|
643
668
|
/**
|
|
644
669
|
* Resolve the instance-config chrome flags once and cache them. Computed live
|
|
645
670
|
* from the fail-open defaults until InstanceConfigEngine has loaded, then frozen
|
|
646
671
|
* on the first post-load read — so the pre-load defaults are never cached over
|
|
647
672
|
* the real values, and every steady-state read is a plain field access.
|
|
673
|
+
*
|
|
674
|
+
* Instance Config is the ceiling; the host's chrome policy may narrow it per user
|
|
675
|
+
* (see {@link BaseShellChromePolicy}). The cache is dropped when the policy fires
|
|
676
|
+
* `Changed`, so an organization or plan switch repaints the chrome.
|
|
648
677
|
*/
|
|
649
678
|
get chromeFlags() {
|
|
650
679
|
if (this._chromeFlags) {
|
|
@@ -652,7 +681,7 @@ export class ShellComponent extends BaseAngularComponent {
|
|
|
652
681
|
}
|
|
653
682
|
const engine = InstanceConfigEngine.Instance;
|
|
654
683
|
const rawStyle = engine.Get('Shell.AppSwitcher.Style');
|
|
655
|
-
const
|
|
684
|
+
const baseline = {
|
|
656
685
|
searchBar: engine.GetBoolean('Shell.SearchBar.Enabled', true),
|
|
657
686
|
searchPreview: engine.GetBoolean('Shell.SearchBar.EnablePreview', true),
|
|
658
687
|
notifications: engine.GetBoolean('Shell.Notifications.Enabled', true),
|
|
@@ -667,11 +696,17 @@ export class ShellComponent extends BaseAngularComponent {
|
|
|
667
696
|
// depend on when a template happens to be evaluated.
|
|
668
697
|
recordOpenStyle: this.resolvedRecordOpenStyle,
|
|
669
698
|
};
|
|
699
|
+
const flags = ApplyShellChromePolicy(baseline, this.chromePolicy);
|
|
670
700
|
if (engine.Loaded) {
|
|
671
701
|
this._chromeFlags = flags;
|
|
672
702
|
}
|
|
673
703
|
return flags;
|
|
674
704
|
}
|
|
705
|
+
/** The policy's answer may have changed: forget the cached flags and repaint. */
|
|
706
|
+
onChromePolicyChanged() {
|
|
707
|
+
this._chromeFlags = null;
|
|
708
|
+
this.cdr.markForCheck();
|
|
709
|
+
}
|
|
675
710
|
/** The record-open style resolved at startup ('records' until resolved) */
|
|
676
711
|
resolvedRecordOpenStyle = 'records';
|
|
677
712
|
/**
|
|
@@ -701,6 +736,19 @@ export class ShellComponent extends BaseAngularComponent {
|
|
|
701
736
|
this.workspaceManager.TempTabConsumptionFilter = this.resolvedRecordOpenStyle === 'records'
|
|
702
737
|
? (tab) => !IsRecordsTabConfiguration(tab.configuration)
|
|
703
738
|
: null;
|
|
739
|
+
// The records region's OWN temp-tab pool (TabRequest.TempScope 'records').
|
|
740
|
+
// Region membership again, not record identity, so a record docked to the
|
|
741
|
+
// workspace is in neither pool: "Move to Workspace" takes a record out of
|
|
742
|
+
// preview replacement, which is the point of docking it.
|
|
743
|
+
// ...minus any tab the user is actively editing. Replacement destroys the
|
|
744
|
+
// pane, so an editing tab leaves the pool and the next plain open gets
|
|
745
|
+
// its own tab — the edit survives without a modal interrupting a browse.
|
|
746
|
+
// (VS Code reaches the same outcome by promoting a modified preview; this
|
|
747
|
+
// is the same guarantee read off state we already have, instead of a new
|
|
748
|
+
// dirty-tracking pipeline.)
|
|
749
|
+
this.workspaceManager.RecordsRegionTabFilter = this.resolvedRecordOpenStyle === 'records'
|
|
750
|
+
? (tab) => IsRecordsRegionTab(tab.configuration) && !this.tabContainerRef?.IsRecordTabEditing(tab.id)
|
|
751
|
+
: null;
|
|
704
752
|
}
|
|
705
753
|
get ShowSearchBar() {
|
|
706
754
|
return this.chromeFlags.searchBar;
|
|
@@ -795,6 +843,9 @@ export class ShellComponent extends BaseAngularComponent {
|
|
|
795
843
|
shellSearchComposite;
|
|
796
844
|
/** Header affordance click → open the palette. */
|
|
797
845
|
OpenOmnibar(initialQuery = '') {
|
|
846
|
+
if (!this.ShowSearchBar) {
|
|
847
|
+
return;
|
|
848
|
+
}
|
|
798
849
|
this.omnibarPalette?.Open(initialQuery);
|
|
799
850
|
}
|
|
800
851
|
// Tab container reference for thumbnail capture
|
|
@@ -946,6 +997,8 @@ export class ShellComponent extends BaseAngularComponent {
|
|
|
946
997
|
this.subscriptions.push(this.workspaceManager.TabBarVisible.subscribe(visible => {
|
|
947
998
|
this.tabBarVisible = visible;
|
|
948
999
|
}));
|
|
1000
|
+
// The host's chrome policy says its answer may have changed (org or plan switch)
|
|
1001
|
+
this.subscriptions.push(this.chromePolicy.Changed.subscribe(() => this.onChromePolicyChanged()));
|
|
949
1002
|
// Subscribe to the global Activity tracker (Run Pipeline, Sync, Cluster, …)
|
|
950
1003
|
this.subscriptions.push(this.activityService.Activities$.subscribe(items => {
|
|
951
1004
|
this.activityItems = items;
|
|
@@ -1210,6 +1263,15 @@ export class ShellComponent extends BaseAngularComponent {
|
|
|
1210
1263
|
if (shouldSetActiveApp) {
|
|
1211
1264
|
await this.appManager.SetActiveApp(request.ApplicationId);
|
|
1212
1265
|
}
|
|
1266
|
+
// Scope URL-driven record opens to the records pool. Assigned HERE rather
|
|
1267
|
+
// than at the resolver that built the request: those live in MJExplorer,
|
|
1268
|
+
// which this package must not modify, and every one of them funnels
|
|
1269
|
+
// through this method anyway. Without it a deep link to a record consumes
|
|
1270
|
+
// the NAV temp tab and converts it into a records tab — the asymmetry
|
|
1271
|
+
// records opens through NavigationService no longer have.
|
|
1272
|
+
if (this.RecordTabsStyle && IsRecordsRegionTab(request.Configuration)) {
|
|
1273
|
+
request.TempScope = 'records';
|
|
1274
|
+
}
|
|
1213
1275
|
this.workspaceManager.OpenTab(request, appColor);
|
|
1214
1276
|
}
|
|
1215
1277
|
/**
|
|
@@ -2413,8 +2475,10 @@ export class ShellComponent extends BaseAngularComponent {
|
|
|
2413
2475
|
return;
|
|
2414
2476
|
}
|
|
2415
2477
|
const { item, shiftKey } = event;
|
|
2416
|
-
// Close mobile nav if open
|
|
2417
|
-
|
|
2478
|
+
// Close mobile nav if open. Routed through closeMobileNav() rather than setting the flag
|
|
2479
|
+
// directly so focus does not get dropped to <body> when the drawer goes inert — tapping a
|
|
2480
|
+
// nav item is the most common way the drawer closes on a phone.
|
|
2481
|
+
this.closeMobileNav();
|
|
2418
2482
|
// Use NavigationService with forceNewTab option if shift was pressed
|
|
2419
2483
|
this.navigationService.OpenNavItem(this.activeApp.ID, item, this.activeApp.GetColor(), { forceNewTab: shiftKey });
|
|
2420
2484
|
}
|
|
@@ -2436,12 +2500,55 @@ export class ShellComponent extends BaseAngularComponent {
|
|
|
2436
2500
|
*/
|
|
2437
2501
|
toggleMobileNav() {
|
|
2438
2502
|
this.mobileNavOpen = !this.mobileNavOpen;
|
|
2503
|
+
if (!this.mobileNavOpen) {
|
|
2504
|
+
this.returnFocusFromMobileNav();
|
|
2505
|
+
}
|
|
2439
2506
|
}
|
|
2440
2507
|
/**
|
|
2441
2508
|
* Close mobile navigation drawer
|
|
2442
2509
|
*/
|
|
2443
2510
|
closeMobileNav() {
|
|
2444
|
-
this.mobileNavOpen
|
|
2511
|
+
if (this.mobileNavOpen) {
|
|
2512
|
+
this.mobileNavOpen = false;
|
|
2513
|
+
this.returnFocusFromMobileNav();
|
|
2514
|
+
}
|
|
2515
|
+
}
|
|
2516
|
+
/**
|
|
2517
|
+
* When the drawer closes it becomes `inert`, which drops focus to <body> if focus was
|
|
2518
|
+
* inside it — the user's place in the page is gone and the next Tab restarts at the top.
|
|
2519
|
+
* Hand focus back to the control that opened it instead. No-op when focus was elsewhere
|
|
2520
|
+
* (e.g. the drawer was closed from a keyboard shortcut while the user was in the content).
|
|
2521
|
+
*/
|
|
2522
|
+
returnFocusFromMobileNav() {
|
|
2523
|
+
const drawer = this.mobileNavDrawer?.nativeElement;
|
|
2524
|
+
const active = document.activeElement;
|
|
2525
|
+
if (!drawer || !active || !drawer.contains(active)) {
|
|
2526
|
+
return;
|
|
2527
|
+
}
|
|
2528
|
+
this.mobileNavToggle?.nativeElement.focus();
|
|
2529
|
+
}
|
|
2530
|
+
/**
|
|
2531
|
+
* Accessible name for the avatar button. The name must never depend on the avatar image
|
|
2532
|
+
* rendering — a Gravatar CORS failure drops to the icon fallback, and an icon carries no
|
|
2533
|
+
* name of its own — so it is set on the BUTTON and falls back to a generic label before
|
|
2534
|
+
* the user record has loaded.
|
|
2535
|
+
*/
|
|
2536
|
+
get avatarAriaLabel() {
|
|
2537
|
+
return this.userName ? `Account: ${this.userName}` : 'Account';
|
|
2538
|
+
}
|
|
2539
|
+
/**
|
|
2540
|
+
* Skip link target handoff (WCAG 2.4.1). Focus is moved programmatically rather than left
|
|
2541
|
+
* to the browser's fragment navigation: the shell's main region is a Golden Layout host,
|
|
2542
|
+
* and letting the URL hash change here would collide with the deep-link/tab restore path.
|
|
2543
|
+
*/
|
|
2544
|
+
skipToMainContent(event) {
|
|
2545
|
+
event.preventDefault();
|
|
2546
|
+
const main = document.getElementById('mj-main-content');
|
|
2547
|
+
if (!main) {
|
|
2548
|
+
return;
|
|
2549
|
+
}
|
|
2550
|
+
main.focus();
|
|
2551
|
+
main.scrollIntoView({ block: 'start' });
|
|
2445
2552
|
}
|
|
2446
2553
|
/**
|
|
2447
2554
|
* Toggle user menu visibility
|
|
@@ -2734,11 +2841,10 @@ export class ShellComponent extends BaseAngularComponent {
|
|
|
2734
2841
|
const entityInfo = md.Entities.find(e => e.Name === entityName);
|
|
2735
2842
|
if (!entityInfo)
|
|
2736
2843
|
return null;
|
|
2737
|
-
|
|
2738
|
-
|
|
2844
|
+
// recordId is the tab's compact key segment (bare value, or "F1|v1||F2|v2" for a composite key)
|
|
2845
|
+
const compositeKey = CompositeKey.FromURLSegment(entityInfo, recordId);
|
|
2846
|
+
if (compositeKey.KeyValuePairs.length === 0)
|
|
2739
2847
|
return null;
|
|
2740
|
-
const compositeKey = new CompositeKey();
|
|
2741
|
-
compositeKey.KeyValuePairs = [{ FieldName: pkField.Name, Value: recordId }];
|
|
2742
2848
|
const results = await md.GetEntityRecordNames([{ EntityName: entityName, CompositeKey: compositeKey }]);
|
|
2743
2849
|
if (results.length > 0 && results[0].Success && results[0].RecordName) {
|
|
2744
2850
|
return results[0].RecordName;
|
|
@@ -2977,6 +3083,9 @@ export class ShellComponent extends BaseAngularComponent {
|
|
|
2977
3083
|
* Toggle search popup visibility
|
|
2978
3084
|
*/
|
|
2979
3085
|
toggleSearch() {
|
|
3086
|
+
if (!this.ShowSearchBar) {
|
|
3087
|
+
return;
|
|
3088
|
+
}
|
|
2980
3089
|
if (this.UseOmnibar) {
|
|
2981
3090
|
this.OpenOmnibar();
|
|
2982
3091
|
return;
|
|
@@ -3054,6 +3163,11 @@ export class ShellComponent extends BaseAngularComponent {
|
|
|
3054
3163
|
(.desktop-only) but its ViewChild still exists — focusing an invisible input
|
|
3055
3164
|
would silently eat the interaction. */
|
|
3056
3165
|
OnHeaderSearchClick() {
|
|
3166
|
+
// No search surface at all when the chrome hides search — the header affordance is
|
|
3167
|
+
// gone, but the Ctrl/Cmd+K chord and the mobile icon route here too.
|
|
3168
|
+
if (!this.ShowSearchBar) {
|
|
3169
|
+
return;
|
|
3170
|
+
}
|
|
3057
3171
|
const isMobile = window.matchMedia('(max-width: 768px)').matches;
|
|
3058
3172
|
if (this.UseOmnibar) {
|
|
3059
3173
|
this.OpenOmnibar();
|
|
@@ -3082,7 +3196,14 @@ export class ShellComponent extends BaseAngularComponent {
|
|
|
3082
3196
|
// truthful origin (default capture) — "back" returns the user there.
|
|
3083
3197
|
// Contrast the chat overlay, a persistent surface whose true origin is
|
|
3084
3198
|
// the conversation (it passes an explicit recordSource).
|
|
3085
|
-
|
|
3199
|
+
//
|
|
3200
|
+
// `RecordID` is a compact CompositeKey segment — the bare value for a single-column primary
|
|
3201
|
+
// key, "F1|v1||F2|v2" for a composite one — and the key column can have ANY name (the search
|
|
3202
|
+
// lanes read it off entity metadata). Resolve it against that metadata; hardcoding
|
|
3203
|
+
// `{ FieldName: 'ID' }` made Load() fail with "Primary key ID not found" for every entity
|
|
3204
|
+
// whose key isn't called ID, and could never open a composite-key record at all.
|
|
3205
|
+
const entityInfo = this.ProviderToUse.EntityByName(result.EntityName);
|
|
3206
|
+
const pkey = CompositeKey.FromURLSegment(entityInfo, result.RecordID);
|
|
3086
3207
|
this.navigationService.OpenEntityRecord(result.EntityName, pkey);
|
|
3087
3208
|
}
|
|
3088
3209
|
/** Legacy search overlay selection → same navigation path as the old composite. */
|
|
@@ -3498,138 +3619,156 @@ export class ShellComponent extends BaseAngularComponent {
|
|
|
3498
3619
|
}
|
|
3499
3620
|
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)); };
|
|
3500
3621
|
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ShellComponent, selectors: [["mj-shell"]], viewQuery: function ShellComponent_Query(rf, ctx) { if (rf & 1) {
|
|
3501
|
-
i0.ɵɵviewQuery(_c0, 5)(_c1, 5)(_c2, 5)(TabContainerComponent, 5)(
|
|
3622
|
+
i0.ɵɵviewQuery(_c0, 5)(_c1, 5)(_c2, 5)(_c3, 5)(_c4, 5)(TabContainerComponent, 5)(_c5, 5);
|
|
3502
3623
|
} if (rf & 2) {
|
|
3503
3624
|
let _t;
|
|
3504
3625
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.searchInput = _t.first);
|
|
3626
|
+
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.mobileNavDrawer = _t.first);
|
|
3627
|
+
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.mobileNavToggle = _t.first);
|
|
3505
3628
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.omnibarPalette = _t.first);
|
|
3506
3629
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.shellSearchComposite = _t.first);
|
|
3507
3630
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.tabContainerRef = _t.first);
|
|
3508
3631
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.appAccessDialog = _t.first);
|
|
3509
3632
|
} }, hostBindings: function ShellComponent_HostBindings(rf, ctx) { if (rf & 1) {
|
|
3510
3633
|
i0.ɵɵlistener("keydown", function ShellComponent_keydown_HostBindingHandler($event) { return ctx.OnGlobalKeydown($event); }, i0.ɵɵresolveDocument)("click", function ShellComponent_click_HostBindingHandler() { return ctx.onDocumentClickCloseActivity(); }, i0.ɵɵresolveDocument);
|
|
3511
|
-
} }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls:
|
|
3634
|
+
} }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 55, vars: 35, consts: [["mobileNavToggle", ""], ["searchInput", ""], ["mobileNavDrawer", ""], ["appAccessDialog", ""], ["shellSearchComposite", ""], ["omnibarPalette", ""], [1, "shell-container"], ["href", "#mj-main-content", 1, "mj-skip-link", 3, "click"], [1, "shell-header"], ["title", "MemberJunction", 1, "mj-logo"], ["title", "Menu", "aria-label", "Menu", "aria-controls", "mj-mobile-nav-drawer", 1, "hamburger-btn", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-bars"], [1, "nav-bar-apps", "left-of-switcher"], [3, "activeApp", "isViewingSystemTab", "loadingAppId", "SwitcherStyle", "Provider"], [1, "desktop-nav", 3, "app", "OverflowEnabled"], [1, "desktop-nav"], [1, "spacer"], [1, "header-actions"], [1, "activity-wrap"], ["title", "Notifications", 1, "icon-btn", "desktop-only", "notification-btn"], [1, "nav-bar-apps", "left-of-user-menu"], [1, "user-menu"], [1, "avatar-btn", 3, "click"], ["alt", "", "aria-hidden", "true", 1, "avatar-img", 3, "src"], ["aria-hidden", "true", 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", "AriaLabel", "Search in", 1, "search-entity-dropdown", 3, "ngModelChange", "Data", "ngModel"], ["type", "text", "placeholder", "Search...", "aria-label", "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"], ["id", "mj-mobile-nav-drawer", 1, "mobile-nav-drawer"], [1, "mobile-nav-header"], ["aria-label", "Close navigation", 1, "close-btn", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-xmark"], [1, "mobile-nav-content"], [1, "mobile-nav-records"], [1, "mobile-nav-footer"], ["title", "Search", 1, "mobile-nav-action", 3, "click"], ["title", "Notifications", 1, "mobile-nav-action"], ["id", "mj-main-content", "role", "main", "tabindex", "-1", 3, "firstResourceLoadComplete", "layoutInitError"], [1, "shell-loading"], [3, "result"], [3, "AppSelected"], ["Placeholder", "Search everything...", 3, "IsOpen", "EnableGlobalShortcut", "ShowPromo", "PromoText"], [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", "SwitcherStyle", "Provider"], [1, "desktop-nav", 3, "navItemClick", "navItemDismiss", "app", "OverflowEnabled"], ["title", "Search everything", 1, "search-btn"], ["title", "Search everything", 1, "search-btn", 3, "click"], [1, "fa-solid", "fa-magnifying-glass"], [1, "search-btn-text", "desktop-only"], ["aria-hidden", "true", 1, "search-btn-kbd", "desktop-only"], [1, "shell-search-bar", "desktop-only"], ["Placeholder", "Search everything...", 3, "ResultSelected", "SearchSubmitted", "SeeAllRequested", "RecentRecordSelected", "PromoAccepted", "PromoDismissed", "ShowShortcutHint", "EnablePreview", "EnableRecent", "MaxPreviewResults", "ShowPromo", "PromoText"], ["title", "Search everything", 1, "search-btn", "search-btn-mobile", 3, "click"], ["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"], ["title", "Notifications", 1, "icon-btn", "desktop-only", "notification-btn", 3, "click"], [1, "fa-solid", "fa-bell"], [1, "notification-badge"], [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", "OverflowEnabled"], [3, "Activated"], ["title", "Notifications", 1, "mobile-nav-action", 3, "click"], [1, "notification-badge-mobile"], ["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"], [3, "SettingsRequested"], ["Placeholder", "Search everything...", 3, "IsOpenChange", "ResultSelected", "SeeAllRequested", "PromoAccepted", "PromoDismissed", "IsOpen", "EnableGlobalShortcut", "ShowPromo", "PromoText"], [1, "pin-progress-modal"], ["size", "small", 3, "showText"], [1, "pin-progress-text"]], template: function ShellComponent_Template(rf, ctx) { if (rf & 1) {
|
|
3512
3635
|
const _r1 = i0.ɵɵgetCurrentView();
|
|
3513
|
-
i0.ɵɵelementStart(0, "div",
|
|
3514
|
-
i0.ɵɵ
|
|
3515
|
-
i0.ɵɵ
|
|
3516
|
-
i0.ɵɵlistener("click", function ShellComponent_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.toggleMobileNav()); });
|
|
3517
|
-
i0.ɵɵelement(4, "i", 8);
|
|
3636
|
+
i0.ɵɵelementStart(0, "div", 6)(1, "a", 7);
|
|
3637
|
+
i0.ɵɵlistener("click", function ShellComponent_Template_a_click_1_listener($event) { return ctx.skipToMainContent($event); });
|
|
3638
|
+
i0.ɵɵtext(2, "Skip to main content");
|
|
3518
3639
|
i0.ɵɵelementEnd();
|
|
3519
|
-
i0.ɵɵ
|
|
3520
|
-
i0.ɵɵ
|
|
3521
|
-
i0.ɵɵ
|
|
3522
|
-
i0.ɵɵ
|
|
3523
|
-
i0.ɵɵ
|
|
3524
|
-
i0.ɵɵconditionalCreate(11, ShellComponent_Conditional_11_Template, 2, 1);
|
|
3525
|
-
i0.ɵɵconditionalCreate(12, ShellComponent_Conditional_12_Template, 5, 4, "div", 15);
|
|
3526
|
-
i0.ɵɵconditionalCreate(13, ShellComponent_Conditional_13_Template, 3, 1, "button", 16);
|
|
3527
|
-
i0.ɵɵconditionalCreate(14, ShellComponent_Conditional_14_Template, 3, 0, "div", 17);
|
|
3528
|
-
i0.ɵɵelementStart(15, "div", 18)(16, "button", 19);
|
|
3529
|
-
i0.ɵɵlistener("click", function ShellComponent_Template_button_click_16_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.toggleUserMenu($event)); });
|
|
3530
|
-
i0.ɵɵconditionalCreate(17, ShellComponent_Conditional_17_Template, 1, 1, "img", 20)(18, ShellComponent_Conditional_18_Template, 2, 2, "div", 21);
|
|
3640
|
+
i0.ɵɵelementStart(3, "header", 8);
|
|
3641
|
+
i0.ɵɵelement(4, "div", 9);
|
|
3642
|
+
i0.ɵɵelementStart(5, "button", 10, 0);
|
|
3643
|
+
i0.ɵɵlistener("click", function ShellComponent_Template_button_click_5_listener() { return ctx.toggleMobileNav(); });
|
|
3644
|
+
i0.ɵɵelement(7, "i", 11);
|
|
3531
3645
|
i0.ɵɵelementEnd();
|
|
3532
|
-
i0.ɵɵconditionalCreate(
|
|
3646
|
+
i0.ɵɵconditionalCreate(8, ShellComponent_Conditional_8_Template, 3, 0, "div", 12);
|
|
3647
|
+
i0.ɵɵconditionalCreate(9, ShellComponent_Conditional_9_Template, 1, 5, "mj-app-switcher", 13);
|
|
3648
|
+
i0.ɵɵconditionalCreate(10, ShellComponent_Conditional_10_Template, 2, 3, "mj-app-nav", 14)(11, ShellComponent_Conditional_11_Template, 1, 0, "mj-records-hub-pill", 15);
|
|
3649
|
+
i0.ɵɵelement(12, "div", 16);
|
|
3650
|
+
i0.ɵɵelementStart(13, "div", 17);
|
|
3651
|
+
i0.ɵɵconditionalCreate(14, ShellComponent_Conditional_14_Template, 2, 1);
|
|
3652
|
+
i0.ɵɵconditionalCreate(15, ShellComponent_Conditional_15_Template, 5, 4, "div", 18);
|
|
3653
|
+
i0.ɵɵconditionalCreate(16, ShellComponent_Conditional_16_Template, 3, 1, "button", 19);
|
|
3654
|
+
i0.ɵɵconditionalCreate(17, ShellComponent_Conditional_17_Template, 3, 0, "div", 20);
|
|
3655
|
+
i0.ɵɵelementStart(18, "div", 21)(19, "button", 22);
|
|
3656
|
+
i0.ɵɵlistener("click", function ShellComponent_Template_button_click_19_listener($event) { return ctx.toggleUserMenu($event); });
|
|
3657
|
+
i0.ɵɵconditionalCreate(20, ShellComponent_Conditional_20_Template, 1, 1, "img", 23)(21, ShellComponent_Conditional_21_Template, 2, 2, "div", 24);
|
|
3658
|
+
i0.ɵɵelementEnd();
|
|
3659
|
+
i0.ɵɵconditionalCreate(22, ShellComponent_Conditional_22_Template, 4, 5, "div", 25);
|
|
3533
3660
|
i0.ɵɵelementEnd()()();
|
|
3534
|
-
i0.ɵɵconditionalCreate(
|
|
3535
|
-
i0.ɵɵelementStart(
|
|
3536
|
-
i0.ɵɵlistener("click", function
|
|
3537
|
-
i0.ɵɵelementStart(
|
|
3538
|
-
i0.ɵɵtwoWayListener("ngModelChange", function
|
|
3661
|
+
i0.ɵɵconditionalCreate(23, ShellComponent_Conditional_23_Template, 1, 0, "div", 26);
|
|
3662
|
+
i0.ɵɵelementStart(24, "div", 27)(25, "div", 28);
|
|
3663
|
+
i0.ɵɵlistener("click", function ShellComponent_Template_div_click_25_listener($event) { return $event.stopPropagation(); });
|
|
3664
|
+
i0.ɵɵelementStart(26, "mj-dropdown", 29);
|
|
3665
|
+
i0.ɵɵtwoWayListener("ngModelChange", function ShellComponent_Template_mj_dropdown_ngModelChange_26_listener($event) { i0.ɵɵrestoreView(_r1); i0.ɵɵtwoWayBindingSet(ctx.selectedEntity, $event) || (ctx.selectedEntity = $event); return i0.ɵɵresetView($event); });
|
|
3539
3666
|
i0.ɵɵelementEnd();
|
|
3540
|
-
i0.ɵɵelementStart(
|
|
3541
|
-
i0.ɵɵlistener("keydown.enter", function
|
|
3667
|
+
i0.ɵɵelementStart(27, "input", 30, 1);
|
|
3668
|
+
i0.ɵɵlistener("keydown.enter", function ShellComponent_Template_input_keydown_enter_27_listener($event) { return ctx.onSearch($event); });
|
|
3542
3669
|
i0.ɵɵelementEnd();
|
|
3543
|
-
i0.ɵɵelementStart(
|
|
3544
|
-
i0.ɵɵlistener("click", function
|
|
3545
|
-
i0.ɵɵelement(
|
|
3670
|
+
i0.ɵɵelementStart(29, "button", 31);
|
|
3671
|
+
i0.ɵɵlistener("click", function ShellComponent_Template_button_click_29_listener($event) { return ctx.onSearch($event); });
|
|
3672
|
+
i0.ɵɵelement(30, "i", 32);
|
|
3546
3673
|
i0.ɵɵelementEnd()()();
|
|
3547
|
-
i0.ɵɵconditionalCreate(
|
|
3548
|
-
i0.ɵɵelementStart(
|
|
3549
|
-
i0.ɵɵtext(
|
|
3674
|
+
i0.ɵɵconditionalCreate(31, ShellComponent_Conditional_31_Template, 1, 0, "div", 33);
|
|
3675
|
+
i0.ɵɵelementStart(32, "div", 34, 2)(34, "div", 35)(35, "span");
|
|
3676
|
+
i0.ɵɵtext(36, "Navigation");
|
|
3550
3677
|
i0.ɵɵelementEnd();
|
|
3551
|
-
i0.ɵɵelementStart(
|
|
3552
|
-
i0.ɵɵlistener("click", function
|
|
3553
|
-
i0.ɵɵelement(
|
|
3678
|
+
i0.ɵɵelementStart(37, "button", 36);
|
|
3679
|
+
i0.ɵɵlistener("click", function ShellComponent_Template_button_click_37_listener() { return ctx.closeMobileNav(); });
|
|
3680
|
+
i0.ɵɵelement(38, "i", 37);
|
|
3554
3681
|
i0.ɵɵelementEnd()();
|
|
3555
|
-
i0.ɵɵconditionalCreate(
|
|
3556
|
-
i0.ɵɵconditionalCreate(
|
|
3557
|
-
i0.ɵɵelementStart(
|
|
3558
|
-
i0.ɵɵlistener("click", function
|
|
3559
|
-
i0.ɵɵelement(
|
|
3560
|
-
i0.ɵɵelementStart(
|
|
3561
|
-
i0.ɵɵtext(
|
|
3682
|
+
i0.ɵɵconditionalCreate(39, ShellComponent_Conditional_39_Template, 4, 3, "div", 38);
|
|
3683
|
+
i0.ɵɵconditionalCreate(40, ShellComponent_Conditional_40_Template, 2, 0, "div", 39);
|
|
3684
|
+
i0.ɵɵelementStart(41, "div", 40)(42, "button", 41);
|
|
3685
|
+
i0.ɵɵlistener("click", function ShellComponent_Template_button_click_42_listener() { i0.ɵɵrestoreView(_r1); ctx.toggleSearch(); return i0.ɵɵresetView(ctx.closeMobileNav()); });
|
|
3686
|
+
i0.ɵɵelement(43, "i", 32);
|
|
3687
|
+
i0.ɵɵelementStart(44, "span");
|
|
3688
|
+
i0.ɵɵtext(45, "Search");
|
|
3562
3689
|
i0.ɵɵelementEnd()();
|
|
3563
|
-
i0.ɵɵconditionalCreate(
|
|
3690
|
+
i0.ɵɵconditionalCreate(46, ShellComponent_Conditional_46_Template, 5, 1, "button", 42);
|
|
3564
3691
|
i0.ɵɵelementEnd()();
|
|
3565
|
-
i0.ɵɵelementStart(
|
|
3566
|
-
i0.ɵɵlistener("firstResourceLoadComplete", function
|
|
3692
|
+
i0.ɵɵelementStart(47, "mj-tab-container", 43);
|
|
3693
|
+
i0.ɵɵlistener("firstResourceLoadComplete", function ShellComponent_Template_mj_tab_container_firstResourceLoadComplete_47_listener() { return ctx.onFirstResourceLoadComplete(); })("layoutInitError", function ShellComponent_Template_mj_tab_container_layoutInitError_47_listener() { return ctx.handleLayoutError(); });
|
|
3567
3694
|
i0.ɵɵelementEnd()();
|
|
3568
|
-
i0.ɵɵconditionalCreate(
|
|
3569
|
-
i0.ɵɵelementStart(
|
|
3570
|
-
i0.ɵɵlistener("result", function
|
|
3571
|
-
i0.ɵɵelementEnd();
|
|
3572
|
-
i0.ɵɵelementStart(47, "mj-command-palette", 43);
|
|
3573
|
-
i0.ɵɵlistener("AppSelected", function ShellComponent_Template_mj_command_palette_AppSelected_47_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onAppSwitch($event)); });
|
|
3695
|
+
i0.ɵɵconditionalCreate(48, ShellComponent_Conditional_48_Template, 4, 6, "div", 44);
|
|
3696
|
+
i0.ɵɵelementStart(49, "mj-app-access-dialog", 45, 3);
|
|
3697
|
+
i0.ɵɵlistener("result", function ShellComponent_Template_mj_app_access_dialog_result_49_listener($event) { return ctx.onAppAccessDialogResult($event); });
|
|
3574
3698
|
i0.ɵɵelementEnd();
|
|
3575
|
-
i0.ɵɵelementStart(
|
|
3576
|
-
i0.ɵɵlistener("
|
|
3699
|
+
i0.ɵɵelementStart(51, "mj-command-palette", 46);
|
|
3700
|
+
i0.ɵɵlistener("AppSelected", function ShellComponent_Template_mj_command_palette_AppSelected_51_listener($event) { return ctx.onAppSwitch($event); });
|
|
3577
3701
|
i0.ɵɵelementEnd();
|
|
3578
|
-
i0.ɵɵconditionalCreate(
|
|
3579
|
-
i0.ɵɵconditionalCreate(
|
|
3702
|
+
i0.ɵɵconditionalCreate(52, ShellComponent_Conditional_52_Template, 2, 0, "mj-omnibar-palette");
|
|
3703
|
+
i0.ɵɵconditionalCreate(53, ShellComponent_Conditional_53_Template, 1, 4, "mj-search-overlay", 47);
|
|
3704
|
+
i0.ɵɵconditionalCreate(54, ShellComponent_Conditional_54_Template, 5, 2, "div", 48);
|
|
3580
3705
|
} if (rf & 2) {
|
|
3581
3706
|
i0.ɵɵclassProp("hidden", ctx.loading)("tabs-visible", ctx.tabBarVisible);
|
|
3582
3707
|
i0.ɵɵadvance(5);
|
|
3583
|
-
i0.ɵɵ
|
|
3708
|
+
i0.ɵɵattribute("aria-expanded", ctx.mobileNavOpen);
|
|
3709
|
+
i0.ɵɵadvance(3);
|
|
3710
|
+
i0.ɵɵconditional(ctx.leftOfSwitcherApps.length > 0 && !ctx.appSwitchingLocked ? 8 : -1);
|
|
3584
3711
|
i0.ɵɵadvance();
|
|
3585
|
-
i0.ɵɵconditional(!ctx.appSwitchingLocked && ctx.ShowAppSwitcher ?
|
|
3712
|
+
i0.ɵɵconditional(!ctx.appSwitchingLocked && ctx.ShowAppSwitcher ? 9 : -1);
|
|
3586
3713
|
i0.ɵɵadvance();
|
|
3587
|
-
i0.ɵɵconditional(ctx.activeApp && ctx.ShowAppNav ?
|
|
3714
|
+
i0.ɵɵconditional(ctx.activeApp && ctx.ShowAppNav ? 10 : ctx.RecordTabsStyle ? 11 : -1);
|
|
3588
3715
|
i0.ɵɵadvance(4);
|
|
3589
|
-
i0.ɵɵconditional(ctx.ShowSearchBar ?
|
|
3716
|
+
i0.ɵɵconditional(ctx.ShowSearchBar ? 14 : -1);
|
|
3590
3717
|
i0.ɵɵadvance();
|
|
3591
|
-
i0.ɵɵconditional(ctx.activityItems.length > 0 ?
|
|
3718
|
+
i0.ɵɵconditional(ctx.activityItems.length > 0 ? 15 : -1);
|
|
3592
3719
|
i0.ɵɵadvance();
|
|
3593
|
-
i0.ɵɵconditional(ctx.ShowNotifications ?
|
|
3720
|
+
i0.ɵɵconditional(ctx.ShowNotifications ? 16 : -1);
|
|
3594
3721
|
i0.ɵɵadvance();
|
|
3595
|
-
i0.ɵɵconditional(ctx.leftOfUserMenuApps.length > 0 ?
|
|
3596
|
-
i0.ɵɵadvance(
|
|
3597
|
-
i0.ɵɵ
|
|
3722
|
+
i0.ɵɵconditional(ctx.leftOfUserMenuApps.length > 0 ? 17 : -1);
|
|
3723
|
+
i0.ɵɵadvance(2);
|
|
3724
|
+
i0.ɵɵattribute("aria-label", ctx.avatarAriaLabel)("aria-expanded", ctx.userMenuVisible);
|
|
3725
|
+
i0.ɵɵadvance();
|
|
3726
|
+
i0.ɵɵconditional(ctx.userImageURL ? 20 : 21);
|
|
3598
3727
|
i0.ɵɵadvance(2);
|
|
3599
|
-
i0.ɵɵconditional(ctx.userMenuVisible ?
|
|
3728
|
+
i0.ɵɵconditional(ctx.userMenuVisible ? 22 : -1);
|
|
3600
3729
|
i0.ɵɵadvance();
|
|
3601
|
-
i0.ɵɵconditional(ctx.isSearchOpen ?
|
|
3730
|
+
i0.ɵɵconditional(ctx.isSearchOpen ? 23 : -1);
|
|
3602
3731
|
i0.ɵɵadvance();
|
|
3603
3732
|
i0.ɵɵclassProp("open", ctx.isSearchOpen);
|
|
3733
|
+
i0.ɵɵattribute("inert", ctx.isSearchOpen ? null : "");
|
|
3604
3734
|
i0.ɵɵadvance(2);
|
|
3605
3735
|
i0.ɵɵproperty("Data", ctx.searchableEntities);
|
|
3606
3736
|
i0.ɵɵtwoWayProperty("ngModel", ctx.selectedEntity);
|
|
3607
3737
|
i0.ɵɵadvance(5);
|
|
3608
|
-
i0.ɵɵconditional(ctx.mobileNavOpen ?
|
|
3738
|
+
i0.ɵɵconditional(ctx.mobileNavOpen ? 31 : -1);
|
|
3609
3739
|
i0.ɵɵadvance();
|
|
3610
3740
|
i0.ɵɵclassProp("open", ctx.mobileNavOpen);
|
|
3611
|
-
i0.ɵɵ
|
|
3612
|
-
i0.ɵɵ
|
|
3741
|
+
i0.ɵɵattribute("inert", ctx.mobileNavOpen ? null : "");
|
|
3742
|
+
i0.ɵɵadvance(7);
|
|
3743
|
+
i0.ɵɵconditional(ctx.activeApp && ctx.ShowAppNav ? 39 : -1);
|
|
3613
3744
|
i0.ɵɵadvance();
|
|
3614
|
-
i0.ɵɵconditional(ctx.RecordTabsStyle ?
|
|
3745
|
+
i0.ɵɵconditional(ctx.RecordTabsStyle ? 40 : -1);
|
|
3615
3746
|
i0.ɵɵadvance(6);
|
|
3616
|
-
i0.ɵɵconditional(ctx.ShowNotifications ?
|
|
3747
|
+
i0.ɵɵconditional(ctx.ShowNotifications ? 46 : -1);
|
|
3617
3748
|
i0.ɵɵadvance();
|
|
3618
3749
|
i0.ɵɵclassProp("hide-tab-bar", !ctx.tabBarVisible);
|
|
3619
3750
|
i0.ɵɵadvance();
|
|
3620
|
-
i0.ɵɵconditional(ctx.loading ?
|
|
3621
|
-
i0.ɵɵadvance(
|
|
3622
|
-
i0.ɵɵconditional(ctx.ShowSearchBar
|
|
3751
|
+
i0.ɵɵconditional(ctx.loading ? 48 : -1);
|
|
3752
|
+
i0.ɵɵadvance(4);
|
|
3753
|
+
i0.ɵɵconditional(ctx.ShowSearchBar ? 52 : -1);
|
|
3623
3754
|
i0.ɵɵadvance();
|
|
3624
|
-
i0.ɵɵconditional(ctx.
|
|
3625
|
-
} }, dependencies: [i13.NgControlStatus, i13.NgModel, i14.MJDropdownComponent, i15.LoadingComponent, i16.SearchOverlayComponent, i16.SearchCompositeComponent, i17.RecordsHubPillComponent, i18.AppSwitcherComponent, i19.AppNavComponent, i20.TabContainerComponent, i21.AppAccessDialogComponent, i22.CommandPaletteComponent, i23.OmnibarPaletteComponent], styles: ["[_nghost-%COMP%] {\n display: block;\n height: 100%;\n width: 100%;\n overflow: hidden;\n}\n\n\n\n\n\n\n.mj-logo[_ngcontent-%COMP%] {\n width: var(--mj-logo-width, 32px);\n height: var(--mj-logo-height, 18px);\n background-image: var(--mj-logo-mark);\n background-color: var(--mj-logo-plate-bg, transparent);\n background-repeat: no-repeat;\n background-position: center;\n background-size: contain;\n border-radius: var(--mj-radius-sm, 4px);\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\n\n\n\nmj-tab-container.hide-tab-bar[_ngcontent-%COMP%] .main-region .lm_header {\n display: none;\n}\n\n\n\nmj-tab-container[_ngcontent-%COMP%]:not(.hide-tab-bar) .main-region .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%] .main-region .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 var(--mj-space-4);\n gap: var(--mj-space-4);\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: var(--mj-space-1);\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: var(--mj-space-2);\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: var(--mj-radius-md);\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: var(--mj-text-lg);\n transition: all var(--mj-transition-fast);\n position: relative;\n}\n\n.nav-bar-app-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n\n\n\n\n.nav-bar-app-btn.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n color: var(--mj-brand-primary);\n}\n\n.nav-bar-app-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n transition: transform var(--mj-transition-fast);\n margin-top: var(--mj-space-0-5); \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\n\n\n\n\n\n\n@media (min-width: 769px) {\n mj-app-nav.desktop-nav[_ngcontent-%COMP%] {\n flex: 1 1 auto;\n min-width: 0;\n }\n mj-app-nav.desktop-nav[_ngcontent-%COMP%] + .spacer[_ngcontent-%COMP%] {\n flex: 0 0 0px;\n }\n}\n\n.header-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\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: var(--mj-text-lg);\n transition: background var(--mj-transition-fast);\n}\n\n.icon-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n\n\n\n.nav-bar-app-btn[_ngcontent-%COMP%]:focus-visible, \n.icon-btn[_ngcontent-%COMP%]:focus-visible, \n.hamburger-btn[_ngcontent-%COMP%]:focus-visible, \n.user-menu[_ngcontent-%COMP%] .avatar-btn[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--mj-border-focus);\n outline-offset: 2px;\n}\n\n\n\n\n\n\n.search-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n width: 260px;\n height: 36px;\n padding: 0 var(--mj-space-2-5) 0 var(--mj-space-3-5);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n font-size: var(--mj-text-sm);\n font-family: inherit;\n cursor: pointer;\n transition: var(--mj-transition-colors);\n}\n\n.search-btn[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-border-strong);\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-secondary);\n}\n\n.search-btn[_ngcontent-%COMP%]:focus-visible {\n outline: none;\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n\n\n\n.search-btn-mobile[_ngcontent-%COMP%] {\n display: none;\n}\n\n\n\n\n.shell-search-bar[_ngcontent-%COMP%] {\n position: relative;\n width: 260px;\n z-index: 99999;\n}\n\n\n\n\n\n.shell-search-bar[_ngcontent-%COMP%] .suggest-dropdown {\n left: auto;\n right: 0;\n width: min(560px, calc(100vw - var(--mj-space-6)));\n}\n\n.search-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n flex-shrink: 0;\n}\n\n.search-btn[_ngcontent-%COMP%] .search-btn-text[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n text-align: left;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n\n\n\n\n.search-btn[_ngcontent-%COMP%] .search-btn-kbd[_ngcontent-%COMP%] {\n flex-shrink: 0;\n white-space: nowrap;\n font-family: inherit;\n font-size: 10.5px;\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-bottom-width: 2px;\n border-radius: 5px;\n padding: 1.5px var(--mj-space-1-5);\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 var(--mj-space-1);\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n font-size: 10px;\n font-weight: var(--mj-font-semibold);\n border-radius: var(--mj-radius-full);\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: var(--mj-leading-none);\n box-shadow: var(--mj-shadow-sm);\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 var(--mj-transition-fast), transform var(--mj-transition-fast);\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 var(--mj-transition-fast);\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: var(--mj-text-base);\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: var(--mj-shadow-sm);\n}\n\n.user-menu[_ngcontent-%COMP%] .avatar-btn[_ngcontent-%COMP%]:hover .avatar-img[_ngcontent-%COMP%] {\n box-shadow: var(--mj-shadow-md);\n}\n\n\n\n.user-menu-header[_ngcontent-%COMP%] {\n padding: var(--mj-space-3) var(--mj-space-4);\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: var(--mj-space-0-5);\n}\n\n.user-menu-header[_ngcontent-%COMP%] .user-name[_ngcontent-%COMP%] {\n font-weight: var(--mj-font-semibold);\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n}\n\n.user-menu-header[_ngcontent-%COMP%] .user-email[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\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: var(--mj-space-2);\n background: var(--mj-bg-surface-elevated);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\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: var(--mj-space-3);\n padding: var(--mj-space-3) var(--mj-space-4);\n cursor: pointer;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n transition: background var(--mj-transition-fast);\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: var(--mj-text-sm);\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: var(--mj-space-1) 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: var(--mj-radius-full);\n background: var(--mj-bg-surface-active);\n margin-left: auto;\n transition: background var(--mj-transition-base);\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: var(--mj-shadow-sm);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: transform var(--mj-transition-base);\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: var(--mj-radius-md);\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: var(--mj-text-xl);\n transition: background var(--mj-transition-fast);\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: var(--mj-bg-overlay);\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 var(--mj-transition-slow);\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: var(--mj-space-4) var(--mj-space-5);\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: var(--mj-font-semibold);\n font-size: var(--mj-text-base);\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: var(--mj-text-lg);\n transition: background var(--mj-transition-fast);\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: var(--mj-space-4) 0;\n}\n\n.mobile-nav-section-title[_ngcontent-%COMP%] {\n padding: var(--mj-space-2) var(--mj-space-5);\n font-size: var(--mj-text-xs);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-disabled);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n\n\n\n\n.mobile-nav-records[_ngcontent-%COMP%] {\n padding: var(--mj-space-2) var(--mj-space-3);\n border-top: 1px solid var(--mj-border-default);\n}\n.mobile-nav-records[_ngcontent-%COMP%] .records-pill[_ngcontent-%COMP%] {\n width: 100%;\n min-height: 48px; \n\n justify-content: flex-start;\n}\n\n.mobile-nav-footer[_ngcontent-%COMP%] {\n border-top: 1px solid var(--mj-border-default);\n padding: var(--mj-space-3) var(--mj-space-4);\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-1);\n}\n\n.mobile-nav-action[_ngcontent-%COMP%] {\n position: relative;\n display: flex;\n align-items: center;\n gap: var(--mj-space-3);\n padding: var(--mj-space-3) var(--mj-space-4);\n border: none;\n background: none;\n cursor: pointer;\n border-radius: var(--mj-radius-md);\n color: var(--mj-text-secondary);\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-medium);\n transition: background var(--mj-transition-fast);\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: var(--mj-text-base);\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 var(--mj-space-3);\n gap: var(--mj-space-2);\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 .header-actions[_ngcontent-%COMP%] .search-btn[_ngcontent-%COMP%] {\n flex-shrink: 0;\n }\n\n \n\n\n\n\n .search-btn[_ngcontent-%COMP%] {\n display: flex;\n width: 40px;\n height: 40px;\n padding: 0;\n justify-content: center;\n border: none;\n border-radius: 50%;\n background: none;\n }\n .search-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: var(--mj-text-lg);\n }\n .search-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n border: none;\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: var(--mj-space-3) var(--mj-space-4);\n}\n\n .settings-fullscreen-window .k-window-title {\n font-size: var(--mj-text-lg);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n}\n\n .settings-fullscreen-window .k-window-titlebar-actions {\n gap: var(--mj-space-1);\n}\n\n .settings-fullscreen-window .k-window-titlebar-action {\n width: 32px;\n height: 32px;\n border-radius: var(--mj-radius-md);\n}\n\n .settings-fullscreen-window .k-window-titlebar-action:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n .settings-fullscreen-window .k-window-content {\n padding: 0;\n overflow: auto;\n background: var(--mj-bg-page);\n}\n\n\n\n .settings-fullscreen-window .k-window-titlebar-action[title=\"Minimize\"], \n .settings-fullscreen-window .k-window-titlebar-action[title=\"Maximize\"], \n .settings-fullscreen-window .k-window-titlebar-action .k-i-window-minimize, \n .settings-fullscreen-window .k-window-titlebar-action .k-i-window-maximize, \n .settings-fullscreen-window .k-window-titlebar-action .k-i-window {\n display: none !important;\n}\n\n\n\n\n\n\n\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: var(--mj-bg-overlay);\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: var(--mj-radius-lg);\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 var(--mj-transition-base), transform var(--mj-transition-base);\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: var(--mj-space-2);\n padding: var(--mj-space-3);\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: var(--mj-space-2) var(--mj-space-3);\n font-size: var(--mj-text-sm);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-sm);\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: var(--mj-radius-md);\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: var(--mj-text-base);\n transition: background var(--mj-transition-fast);\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: var(--mj-font-semibold);\n border-radius: var(--mj-radius-full);\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: var(--mj-leading-none);\n box-shadow: var(--mj-shadow-sm);\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: var(--mj-space-7) var(--mj-space-10);\n display: flex;\n align-items: center;\n gap: var(--mj-space-4);\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 var(--mj-space-1);\n border-radius: var(--mj-radius-md);\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 10px;\n font-weight: var(--mj-font-bold);\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: var(--mj-radius-md);\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: var(--mj-space-2-5) var(--mj-space-3);\n font-weight: var(--mj-font-bold);\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: var(--mj-space-1) var(--mj-space-1-5);\n border-radius: var(--mj-radius-md);\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: var(--mj-space-1-5); }\n.activity-row[_ngcontent-%COMP%] {\n display: flex;\n gap: var(--mj-space-2-5);\n padding: var(--mj-space-2);\n border-radius: var(--mj-radius-md);\n}\n.activity-row[_ngcontent-%COMP%]:hover { background: var(--mj-bg-surface-hover); }\n.activity-row-icon[_ngcontent-%COMP%] { margin-top: var(--mj-space-0-5); 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: var(--mj-font-semibold); color: var(--mj-text-primary); }\n.activity-row-detail[_ngcontent-%COMP%] { font-size: 0.72rem; color: var(--mj-text-muted); margin-top: var(--mj-space-px); }\n.activity-bar[_ngcontent-%COMP%] {\n margin-top: var(--mj-space-1-5);\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 var(--mj-transition-slow); }"] });
|
|
3755
|
+
i0.ɵɵconditional(ctx.ShowSearchBar && !ctx.UseOmnibar ? 53 : -1);
|
|
3756
|
+
i0.ɵɵadvance();
|
|
3757
|
+
i0.ɵɵconditional(ctx.PinProgressVisible ? 54 : -1);
|
|
3758
|
+
} }, dependencies: [i13.NgControlStatus, i13.NgModel, i14.MJDropdownComponent, i15.LoadingComponent, i16.SearchOverlayComponent, i16.SearchCompositeComponent, i17.RecordsHubPillComponent, i18.AppSwitcherComponent, i19.AppNavComponent, i20.TabContainerComponent, i21.AppAccessDialogComponent, i22.CommandPaletteComponent, i23.OmnibarPaletteComponent], styles: ["[_nghost-%COMP%] {\n display: block;\n height: 100%;\n width: 100%;\n overflow: hidden;\n}\n\n\n\n\n\n.mj-logo[_ngcontent-%COMP%] {\n width: var(--mj-logo-width, 32px);\n height: var(--mj-logo-height, 18px);\n background-image: var(--mj-logo-mark);\n background-color: var(--mj-logo-plate-bg, transparent);\n background-repeat: no-repeat;\n background-position: center;\n background-size: contain;\n border-radius: var(--mj-radius-sm, 4px);\n flex-shrink: 0;\n}\n\n\n\n\n.mj-skip-link[_ngcontent-%COMP%] {\n position: absolute;\n top: var(--mj-space-2);\n left: var(--mj-space-2);\n z-index: 100000;\n padding: var(--mj-space-2) var(--mj-space-4);\n background: var(--mj-bg-surface-elevated);\n color: var(--mj-text-primary);\n border: 1px solid var(--mj-border-strong);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-lg);\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n text-decoration: none;\n transform: translateY(-200%);\n transition: transform var(--mj-transition-fast);\n}\n.mj-skip-link[_ngcontent-%COMP%]:focus, \n.mj-skip-link[_ngcontent-%COMP%]:focus-visible {\n transform: translateY(0);\n outline: var(--mj-ring-width) solid var(--mj-focus-ring-color);\n outline-offset: var(--mj-ring-offset);\n}\n\n\n\nmj-tab-container[_ngcontent-%COMP%]:focus {\n outline: none;\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.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\n\n\nmj-tab-container.hide-tab-bar[_ngcontent-%COMP%] .main-region .lm_header {\n display: none;\n}\n\n\nmj-tab-container[_ngcontent-%COMP%]:not(.hide-tab-bar) .main-region .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\nmj-tab-container.hide-tab-bar[_ngcontent-%COMP%] .main-region .lm_content {\n height: 100% !important;\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 var(--mj-space-4);\n gap: var(--mj-space-4);\n box-shadow: var(--mj-shadow-sm);\n flex-shrink: 0;\n \n\n position: relative;\n z-index: 500;\n}\n\n\n.nav-bar-apps[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-1);\n}\n\n.nav-bar-apps.left-of-switcher[_ngcontent-%COMP%] {\n \n \n}\n\n.nav-bar-apps.left-of-user-menu[_ngcontent-%COMP%] {\n margin-right: var(--mj-space-2);\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: var(--mj-radius-md);\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: var(--mj-text-lg);\n transition: all var(--mj-transition-fast);\n position: relative;\n}\n\n.nav-bar-app-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n\n\n\n.nav-bar-app-btn.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n color: var(--mj-brand-primary);\n}\n\n.nav-bar-app-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n transition: transform var(--mj-transition-fast);\n margin-top: var(--mj-space-0-5); \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\n\n\n\n\n\n@media (min-width: 769px) {\n mj-app-nav.desktop-nav[_ngcontent-%COMP%] {\n flex: 1 1 auto;\n min-width: 0;\n }\n mj-app-nav.desktop-nav[_ngcontent-%COMP%] + .spacer[_ngcontent-%COMP%] {\n flex: 0 0 0px;\n }\n}\n\n.header-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\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: var(--mj-text-lg);\n transition: background var(--mj-transition-fast);\n}\n\n.icon-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n\n\n.nav-bar-app-btn[_ngcontent-%COMP%]:focus-visible, \n.icon-btn[_ngcontent-%COMP%]:focus-visible, \n.hamburger-btn[_ngcontent-%COMP%]:focus-visible, \n.user-menu[_ngcontent-%COMP%] .avatar-btn[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--mj-border-focus);\n outline-offset: 2px;\n}\n\n\n\n\n\n.search-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n width: 260px;\n height: 36px;\n padding: 0 var(--mj-space-2-5) 0 var(--mj-space-3-5);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n font-size: var(--mj-text-sm);\n font-family: inherit;\n cursor: pointer;\n transition: var(--mj-transition-colors);\n}\n\n.search-btn[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-border-strong);\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-secondary);\n}\n\n.search-btn[_ngcontent-%COMP%]:focus-visible {\n outline: none;\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n\n\n.search-btn-mobile[_ngcontent-%COMP%] {\n display: none;\n}\n\n\n\n.shell-search-bar[_ngcontent-%COMP%] {\n position: relative;\n width: 260px;\n z-index: 99999;\n}\n\n\n\n\n.shell-search-bar[_ngcontent-%COMP%] .suggest-dropdown {\n left: auto;\n right: 0;\n width: min(560px, calc(100vw - var(--mj-space-6)));\n}\n\n.search-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n flex-shrink: 0;\n}\n\n.search-btn[_ngcontent-%COMP%] .search-btn-text[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n text-align: left;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n\n\n\n.search-btn[_ngcontent-%COMP%] .search-btn-kbd[_ngcontent-%COMP%] {\n flex-shrink: 0;\n white-space: nowrap;\n font-family: inherit;\n font-size: 10.5px;\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-bottom-width: 2px;\n border-radius: 5px;\n padding: 1.5px var(--mj-space-1-5);\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 var(--mj-space-1);\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n font-size: 10px;\n font-weight: var(--mj-font-semibold);\n border-radius: var(--mj-radius-full);\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: var(--mj-leading-none);\n box-shadow: var(--mj-shadow-sm);\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 var(--mj-transition-fast), transform var(--mj-transition-fast);\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.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 var(--mj-transition-fast);\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: var(--mj-text-base);\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: var(--mj-shadow-sm);\n}\n\n.user-menu[_ngcontent-%COMP%] .avatar-btn[_ngcontent-%COMP%]:hover .avatar-img[_ngcontent-%COMP%] {\n box-shadow: var(--mj-shadow-md);\n}\n\n\n.user-menu-header[_ngcontent-%COMP%] {\n padding: var(--mj-space-3) var(--mj-space-4);\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: var(--mj-space-0-5);\n}\n\n.user-menu-header[_ngcontent-%COMP%] .user-name[_ngcontent-%COMP%] {\n font-weight: var(--mj-font-semibold);\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n}\n\n.user-menu-header[_ngcontent-%COMP%] .user-email[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\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.user-context-menu[_ngcontent-%COMP%] {\n position: absolute;\n top: 100%;\n right: 0;\n margin-top: var(--mj-space-2);\n background: var(--mj-bg-surface-elevated);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-lg);\n min-width: 180px;\n \n\n\n max-width: min(360px, calc(100vw - 2 * var(--mj-space-4)));\n max-height: calc(100vh - 60px - 3 * var(--mj-space-2));\n max-height: calc(100dvh - 60px - 3 * var(--mj-space-2));\n z-index: 10000;\n overflow-x: hidden;\n overflow-y: auto;\n}\n\n.user-menu-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-3);\n padding: var(--mj-space-3) var(--mj-space-4);\n cursor: pointer;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n transition: background var(--mj-transition-fast);\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: var(--mj-text-sm);\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: var(--mj-space-1) 0;\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.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: var(--mj-radius-full);\n background: var(--mj-bg-surface-active);\n margin-left: auto;\n transition: background var(--mj-transition-base);\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: var(--mj-shadow-sm);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: transform var(--mj-transition-base);\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.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.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.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.hamburger-btn[_ngcontent-%COMP%] {\n display: none;\n width: 40px;\n height: 40px;\n border-radius: var(--mj-radius-md);\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: var(--mj-text-xl);\n transition: background var(--mj-transition-fast);\n}\n.hamburger-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\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: var(--mj-bg-overlay);\n z-index: 9998;\n}\n\n\n\n\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 visibility: hidden;\n transition: transform var(--mj-transition-slow), visibility 0s linear 300ms;\n}\n.mobile-nav-drawer.open[_ngcontent-%COMP%] {\n transform: translateX(0);\n visibility: visible;\n transition: transform var(--mj-transition-slow), visibility 0s linear 0s;\n}\n\n\n@media (prefers-reduced-motion: reduce) {\n .mobile-nav-drawer[_ngcontent-%COMP%], \n .mobile-nav-drawer.open[_ngcontent-%COMP%] {\n transition: none;\n }\n}\n\n.mobile-nav-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: var(--mj-space-4) var(--mj-space-5);\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: var(--mj-font-semibold);\n font-size: var(--mj-text-base);\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: var(--mj-text-lg);\n transition: background var(--mj-transition-fast);\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: var(--mj-space-4) 0;\n}\n\n.mobile-nav-section-title[_ngcontent-%COMP%] {\n padding: var(--mj-space-2) var(--mj-space-5);\n font-size: var(--mj-text-xs);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-disabled);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n\n\n\n.mobile-nav-records[_ngcontent-%COMP%] {\n padding: var(--mj-space-2) var(--mj-space-3);\n border-top: 1px solid var(--mj-border-default);\n}\n.mobile-nav-records[_ngcontent-%COMP%] .records-pill[_ngcontent-%COMP%] {\n width: 100%;\n min-height: 48px; \n justify-content: flex-start;\n}\n\n.mobile-nav-footer[_ngcontent-%COMP%] {\n border-top: 1px solid var(--mj-border-default);\n padding: var(--mj-space-3) var(--mj-space-4);\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-1);\n}\n\n.mobile-nav-action[_ngcontent-%COMP%] {\n position: relative;\n display: flex;\n align-items: center;\n gap: var(--mj-space-3);\n padding: var(--mj-space-3) var(--mj-space-4);\n border: none;\n background: none;\n cursor: pointer;\n border-radius: var(--mj-radius-md);\n color: var(--mj-text-secondary);\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-medium);\n transition: background var(--mj-transition-fast);\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: var(--mj-text-base);\n width: 20px;\n text-align: center;\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 var(--mj-space-3);\n gap: var(--mj-space-2);\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 .header-actions[_ngcontent-%COMP%] .search-btn[_ngcontent-%COMP%] {\n flex-shrink: 0;\n }\n\n \n\n\n\n .search-btn[_ngcontent-%COMP%] {\n display: flex;\n width: 40px;\n height: 40px;\n padding: 0;\n justify-content: center;\n border: none;\n border-radius: 50%;\n background: none;\n }\n .search-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: var(--mj-text-lg);\n }\n .search-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n border: none;\n }\n}\n\n\n .settings-fullscreen-window {\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: var(--mj-space-3) var(--mj-space-4);\n}\n\n .settings-fullscreen-window .k-window-title {\n font-size: var(--mj-text-lg);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n}\n\n .settings-fullscreen-window .k-window-titlebar-actions {\n gap: var(--mj-space-1);\n}\n\n .settings-fullscreen-window .k-window-titlebar-action {\n width: 32px;\n height: 32px;\n border-radius: var(--mj-radius-md);\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 .settings-fullscreen-window .k-window-titlebar-action[title=\"Minimize\"], \n .settings-fullscreen-window .k-window-titlebar-action[title=\"Maximize\"], \n .settings-fullscreen-window .k-window-titlebar-action .k-i-window-minimize, \n .settings-fullscreen-window .k-window-titlebar-action .k-i-window-maximize, \n .settings-fullscreen-window .k-window-titlebar-action .k-i-window {\n display: none !important;\n}\n\n\n\n\n\n\n\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: var(--mj-bg-overlay);\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 right: 16px;\n width: 480px;\n max-width: calc(100vw - 32px);\n background: var(--mj-bg-surface-elevated);\n border-radius: var(--mj-radius-lg);\n box-shadow: var(--mj-shadow-xl);\n z-index: 10000;\n opacity: 0;\n transform: translateY(-10px);\n pointer-events: none;\n visibility: hidden;\n transition: opacity var(--mj-transition-base), transform var(--mj-transition-base), visibility 0s linear 200ms;\n}\n\n.search-popup.open[_ngcontent-%COMP%] {\n opacity: 1;\n transform: translateY(0);\n pointer-events: all;\n visibility: visible;\n transition: opacity var(--mj-transition-base), transform var(--mj-transition-base), visibility 0s linear 0s;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .search-popup[_ngcontent-%COMP%], \n .search-popup.open[_ngcontent-%COMP%] {\n transition: none;\n }\n}\n\n.search-popup-content[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n padding: var(--mj-space-3);\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: var(--mj-space-2) var(--mj-space-3);\n font-size: var(--mj-text-sm);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-sm);\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: var(--mj-radius-md);\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: var(--mj-text-base);\n transition: background var(--mj-transition-fast);\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.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: var(--mj-font-semibold);\n border-radius: var(--mj-radius-full);\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: var(--mj-leading-none);\n box-shadow: var(--mj-shadow-sm);\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.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: var(--mj-space-7) var(--mj-space-10);\n display: flex;\n align-items: center;\n gap: var(--mj-space-4);\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.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 var(--mj-space-1);\n border-radius: var(--mj-radius-md);\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 10px;\n font-weight: var(--mj-font-bold);\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: var(--mj-radius-md);\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: var(--mj-space-2-5) var(--mj-space-3);\n font-weight: var(--mj-font-bold);\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: var(--mj-space-1) var(--mj-space-1-5);\n border-radius: var(--mj-radius-md);\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: var(--mj-space-1-5); }\n.activity-row[_ngcontent-%COMP%] {\n display: flex;\n gap: var(--mj-space-2-5);\n padding: var(--mj-space-2);\n border-radius: var(--mj-radius-md);\n}\n.activity-row[_ngcontent-%COMP%]:hover { background: var(--mj-bg-surface-hover); }\n.activity-row-icon[_ngcontent-%COMP%] { margin-top: var(--mj-space-0-5); 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: var(--mj-font-semibold); color: var(--mj-text-primary); }\n.activity-row-detail[_ngcontent-%COMP%] { font-size: 0.72rem; color: var(--mj-text-muted); margin-top: var(--mj-space-px); }\n.activity-bar[_ngcontent-%COMP%] {\n margin-top: var(--mj-space-1-5);\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 var(--mj-transition-slow); }"] });
|
|
3626
3759
|
}
|
|
3627
3760
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ShellComponent, [{
|
|
3628
3761
|
type: Component,
|
|
3629
|
-
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 [attr.aria-current]=\"IsActiveApp(app) ? 'true' : null\"\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, and\n removable per deployment via 'Shell.AppSwitcher.Enabled') -->\n @if (!appSwitchingLocked && ShowAppSwitcher) {\n <mj-app-switcher\n [activeApp]=\"activeApp\"\n [isViewingSystemTab]=\"isViewingSystemTab\"\n [loadingAppId]=\"loadingAppId\"\n [SwitcherStyle]=\"AppSwitcherStyle\"\n [Provider]=\"Provider\"\n (appSelected)=\"onAppSwitch($event)\">\n </mj-app-switcher>\n }\n\n <!-- App Navigation (desktop only; removable per deployment via 'Shell.AppNav.Enabled') -->\n @if (activeApp && ShowAppNav) {\n <mj-app-nav\n class=\"desktop-nav\"\n [app]=\"activeApp\"\n [OverflowEnabled]=\"true\"\n (navItemClick)=\"onNavItemClick($event)\"\n (navItemDismiss)=\"onNavItemDismiss($event)\">\n <!-- Records style: persistent Records pill \u2014 projected into the nav\n row's trailing slot so it sits pipe-separated right after the\n app's own items, styled as a nav pill. Appears only while any\n record is open; resumes the last-viewed record on click. -->\n @if (RecordTabsStyle) {\n <mj-records-hub-pill></mj-records-hub-pill>\n }\n </mj-app-nav>\n } @else if (RecordTabsStyle) {\n <!-- Reachability: when the app nav doesn't render (AppNav disabled per\n deployment, or no active app), open records must STILL have a way\n back \u2014 render the pill standalone in the header. -->\n <mj-records-hub-pill class=\"desktop-nav\"></mj-records-hub-pill>\n }\n\n <!-- Spacer -->\n <div class=\"spacer\"></div>\n <!-- Actions (activity, notifications, user menu) -->\n <div class=\"header-actions\">\n <!-- Universal Search \u2014 right-anchored with the action cluster, static width\n (2026-07 review consensus: visible when space permits, never resizes).\n Omnibar ON: a button styled as an input \u2014 clicking (or Ctrl/Cmd+K) opens\n the modal palette; typing happens there. Collapses to the icon circle at\n the mobile breakpoint.\n Omnibar OFF: a REAL inline input (mj-search-composite) \u2014 results attach\n beneath it as a suggest dropdown with a \"See all results\" footer. On\n mobile the composite hides and an icon button opens the Spotlight\n overlay instead (same slot, same collapse point). -->\n @if (ShowSearchBar) {\n @if (UseOmnibar) {\n <button class=\"search-btn\" title=\"Search everything\"\n [attr.aria-label]=\"'Search everything (' + OmnibarShortcutLabel + ')'\"\n (click)=\"OnHeaderSearchClick()\">\n <i class=\"fa-solid fa-magnifying-glass\"></i>\n <span class=\"search-btn-text desktop-only\">Search everything</span>\n <kbd class=\"search-btn-kbd desktop-only\" aria-hidden=\"true\">{{ OmnibarShortcutLabel }}</kbd>\n </button>\n } @else {\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 [ShowPromo]=\"ShowOmnibarPromo\"\n [PromoText]=\"OmnibarPromoText\"\n (ResultSelected)=\"OnSearchResultSelected($event)\"\n (SearchSubmitted)=\"OnSearchSubmitted($event)\"\n (SeeAllRequested)=\"OnSeeAllSearch($event)\"\n (RecentRecordSelected)=\"OnSearchResultSelected($event)\"\n (PromoAccepted)=\"OnOmnibarPromoAccepted($event)\"\n (PromoDismissed)=\"OnOmnibarPromoDismissed()\">\n </mj-search-composite>\n </div>\n <button class=\"search-btn search-btn-mobile\" title=\"Search everything\"\n [attr.aria-label]=\"'Search everything (' + OmnibarShortcutLabel + ')'\"\n (click)=\"OnHeaderSearchClick()\">\n <i class=\"fa-solid fa-magnifying-glass\"></i>\n </button>\n }\n }\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 @if (ShowNotifications) {\n <button class=\"icon-btn desktop-only notification-btn\" title=\"Notifications\" (click)=\"showNotifications()\">\n <i class=\"fa-solid fa-bell\"></i>\n @if (unreadNotificationCount > 0) {\n <span class=\"notification-badge\">\n {{ unreadNotificationCount > 99 ? '99+' : unreadNotificationCount }}\n </span>\n }\n </button>\n }\n <!-- Nav Bar Apps: Left of User Menu -->\n @if (leftOfUserMenuApps.length > 0) {\n <div class=\"nav-bar-apps left-of-user-menu\">\n @for (app of leftOfUserMenuApps; track app) {\n <button\n class=\"nav-bar-app-btn\"\n [class.active]=\"IsActiveApp(app)\"\n [attr.aria-current]=\"IsActiveApp(app) ? 'true' : null\"\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 && ShowAppNav) {\n <div class=\"mobile-nav-content\">\n <div class=\"mobile-nav-section-title\">{{ activeApp.Name }}</div>\n <mj-app-nav\n [app]=\"activeApp\"\n [OverflowEnabled]=\"false\"\n (navItemClick)=\"onNavItemClick($event)\"\n (navItemDismiss)=\"onNavItemDismiss($event)\">\n </mj-app-nav>\n </div>\n }\n <!-- Records style: the desktop pill lives in the (mobile-hidden) app nav,\n so the drawer carries its own entry \u2014 without it, open records are\n unreachable on mobile except by re-opening them. Resumes the\n last-viewed record and closes the drawer. -->\n @if (RecordTabsStyle) {\n <div class=\"mobile-nav-records\">\n <mj-records-hub-pill (Activated)=\"closeMobileNav()\"></mj-records-hub-pill>\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 @if (ShowNotifications) {\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 }\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<!-- Unified command palette (Shell.Omnibar.Enabled) -->\n<mj-omnibar-palette #omnibarPalette (SettingsRequested)=\"OnPaletteSettingsRequested()\"></mj-omnibar-palette>\n\n<!-- Legacy universal search as a Spotlight-style overlay \u2014 omnibar-off MOBILE only\n (on desktop the inline header composite owns the experience; this opens from\n the mobile icon or Ctrl/Cmd+K when the composite isn't visible).\n The shell owns the Ctrl/Cmd+K chord, so the overlay's own global shortcut is off. -->\n@if (ShowSearchBar && !UseOmnibar) {\n <mj-search-overlay\n [(IsOpen)]=\"LegacySearchOpen\"\n Placeholder=\"Search everything...\"\n [EnableGlobalShortcut]=\"false\"\n [ShowPromo]=\"ShowOmnibarPromo\"\n [PromoText]=\"OmnibarPromoText\"\n (ResultSelected)=\"OnOverlayResultSelected($event)\"\n (SeeAllRequested)=\"OnOverlaySeeAll($event)\"\n (PromoAccepted)=\"OnOmnibarPromoAccepted($event)\"\n (PromoDismissed)=\"OnOmnibarPromoDismissed()\">\n </mj-search-overlay>\n}\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 tokens for theme switching & white-labeling.\n Geometry follows --mj-logo-width/-height so a differently-shaped org mark fits;\n --mj-logo-plate-bg is set by the theme engine only when a single-variant logo needs\n a legibility plate in the mode it wasn't designed for (org-theming Phase 4). */\n.mj-logo {\n width: var(--mj-logo-width, 32px);\n height: var(--mj-logo-height, 18px);\n background-image: var(--mj-logo-mark);\n background-color: var(--mj-logo-plate-bg, transparent);\n background-repeat: no-repeat;\n background-position: center;\n background-size: contain;\n border-radius: var(--mj-radius-sm, 4px);\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 \u2014 scoped to the MAIN\n region: the RECORDS region is a separate Golden Layout whose tab strip is\n its whole point (switching between open records) and must never be hidden\n by the main bar's visibility policy. */\nmj-tab-container.hide-tab-bar ::ng-deep .main-region .lm_header {\n display: none;\n}\n\n/* Show tab headers when multiple tabs */\nmj-tab-container:not(.hide-tab-bar) ::ng-deep .main-region .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 .main-region .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 var(--mj-space-4);\n gap: var(--mj-space-4);\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: var(--mj-space-1);\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: var(--mj-space-2);\n}\n\n.nav-bar-app-btn {\n --app-color: var(--mj-text-muted);\n width: 40px;\n height: 40px;\n border-radius: var(--mj-radius-md);\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: var(--mj-text-lg);\n transition: all var(--mj-transition-fast);\n position: relative;\n}\n\n.nav-bar-app-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n/* Active = brand-primary (matches nav pills + switcher items); the app's\n metadata color is reserved for identity accents, never state.\n Shared active-tint recipe. */\n.nav-bar-app-btn.active {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n color: var(--mj-brand-primary);\n}\n\n.nav-bar-app-btn i {\n transition: transform var(--mj-transition-fast);\n margin-top: var(--mj-space-0-5); /* 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/* Priority+ overflow support: on desktop the app nav owns the header's free\n middle space (so it knows exactly how much room its items have) and the\n spacer stands down. On mobile the nav is display:none'd, so the spacer's\n flex: 1 keeps the action cluster right-aligned. When the nav isn't rendered\n at all (app-locked sessions, Shell.AppNav.Enabled off), the sibling selector\n doesn't match and the spacer behaves as before. */\n@media (min-width: 769px) {\n mj-app-nav.desktop-nav {\n flex: 1 1 auto;\n min-width: 0;\n }\n mj-app-nav.desktop-nav + .spacer {\n flex: 0 0 0px;\n }\n}\n\n.header-actions {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\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: var(--mj-text-lg);\n transition: background var(--mj-transition-fast);\n}\n\n.icon-btn:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n/* Keyboard focus parity for all header controls (the search bar already has\n its own ring at .search-btn:focus-visible). */\n.nav-bar-app-btn:focus-visible,\n.icon-btn:focus-visible,\n.hamburger-btn:focus-visible,\n.user-menu .avatar-btn:focus-visible {\n outline: 2px solid var(--mj-border-focus);\n outline-offset: 2px;\n}\n\n/* Universal search: a static-width bar styled as an input, anchored on the\n right with the action cluster. Deliberately NOT resizable on hover/focus \u2014\n chrome that shifts on interaction was rejected in the 2026-07 review. It's a\n button (typing happens in the overlay it opens), so no focus/caret styling. */\n.search-btn {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n width: 260px;\n height: 36px;\n padding: 0 var(--mj-space-2-5) 0 var(--mj-space-3-5);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n font-size: var(--mj-text-sm);\n font-family: inherit;\n cursor: pointer;\n transition: var(--mj-transition-colors);\n}\n\n.search-btn:hover {\n border-color: var(--mj-border-strong);\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-secondary);\n}\n\n.search-btn:focus-visible {\n outline: none;\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n/* Omnibar-off mobile trigger: hidden on desktop (the inline composite renders\n instead); the 768px block flips it on as the icon circle. */\n.search-btn-mobile {\n display: none;\n}\n\n/* Omnibar-off desktop: the inline search composite, same slot + width as the\n omnibar bar so the opt-in toggle doesn't move the header. */\n.shell-search-bar {\n position: relative;\n width: 260px;\n z-index: 99999;\n}\n\n/* The suggest dropdown needs more width than its 260px anchor. Pin it to the\n anchor's right edge and let it grow leftward \u2014 the bar is right-anchored, so\n leftward growth stays on screen. */\n.shell-search-bar ::ng-deep .suggest-dropdown {\n left: auto;\n right: 0;\n width: min(560px, calc(100vw - var(--mj-space-6)));\n}\n\n.search-btn i {\n font-size: var(--mj-text-sm);\n flex-shrink: 0;\n}\n\n.search-btn .search-btn-text {\n flex: 1;\n min-width: 0;\n text-align: left;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* kbd chip: deliberately mirrors the omnibar palette's .ob-kbd chrome\n (10.5px / 5px radius / bottom-heavy border) so the affordance and the\n surface it summons read as one system. */\n.search-btn .search-btn-kbd {\n flex-shrink: 0;\n white-space: nowrap;\n font-family: inherit;\n font-size: 10.5px;\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-bottom-width: 2px;\n border-radius: 5px;\n padding: 1.5px var(--mj-space-1-5);\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 var(--mj-space-1);\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n font-size: 10px;\n font-weight: var(--mj-font-semibold);\n border-radius: var(--mj-radius-full);\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: var(--mj-leading-none);\n box-shadow: var(--mj-shadow-sm);\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 var(--mj-transition-fast), transform var(--mj-transition-fast);\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 var(--mj-transition-fast);\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: var(--mj-text-base);\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: var(--mj-shadow-sm);\n}\n\n.user-menu .avatar-btn:hover .avatar-img {\n box-shadow: var(--mj-shadow-md);\n}\n\n/* User Menu Header */\n.user-menu-header {\n padding: var(--mj-space-3) var(--mj-space-4);\n background: var(--mj-bg-surface-sunken);\n}\n\n.user-menu-header .user-info {\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-0-5);\n}\n\n.user-menu-header .user-name {\n font-weight: var(--mj-font-semibold);\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n}\n\n.user-menu-header .user-email {\n font-size: var(--mj-text-xs);\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: var(--mj-space-2);\n background: var(--mj-bg-surface-elevated);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\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: var(--mj-space-3);\n padding: var(--mj-space-3) var(--mj-space-4);\n cursor: pointer;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n transition: background var(--mj-transition-fast);\n}\n\n.user-menu-item i {\n width: 18px;\n text-align: center;\n color: var(--mj-text-muted);\n font-size: var(--mj-text-sm);\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: var(--mj-space-1) 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: var(--mj-radius-full);\n background: var(--mj-bg-surface-active);\n margin-left: auto;\n transition: background var(--mj-transition-base);\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: var(--mj-shadow-sm);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: transform var(--mj-transition-base);\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: var(--mj-radius-md);\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: var(--mj-text-xl);\n transition: background var(--mj-transition-fast);\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: var(--mj-bg-overlay);\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 var(--mj-transition-slow);\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: var(--mj-space-4) var(--mj-space-5);\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: var(--mj-font-semibold);\n font-size: var(--mj-text-base);\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: var(--mj-text-lg);\n transition: background var(--mj-transition-fast);\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: var(--mj-space-4) 0;\n}\n\n.mobile-nav-section-title {\n padding: var(--mj-space-2) var(--mj-space-5);\n font-size: var(--mj-text-xs);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-disabled);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n/* Records entry in the mobile drawer (records-style record opens) \u2014\n the desktop pill lives in the mobile-hidden app nav, so the drawer\n carries its own touch-friendly instance. */\n.mobile-nav-records {\n padding: var(--mj-space-2) var(--mj-space-3);\n border-top: 1px solid var(--mj-border-default);\n}\n.mobile-nav-records .records-pill {\n width: 100%;\n min-height: 48px; /* Touch-target parity with drawer nav items */\n justify-content: flex-start;\n}\n\n.mobile-nav-footer {\n border-top: 1px solid var(--mj-border-default);\n padding: var(--mj-space-3) var(--mj-space-4);\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-1);\n}\n\n.mobile-nav-action {\n position: relative;\n display: flex;\n align-items: center;\n gap: var(--mj-space-3);\n padding: var(--mj-space-3) var(--mj-space-4);\n border: none;\n background: none;\n cursor: pointer;\n border-radius: var(--mj-radius-md);\n color: var(--mj-text-secondary);\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-medium);\n transition: background var(--mj-transition-fast);\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: var(--mj-text-base);\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 var(--mj-space-3);\n gap: var(--mj-space-2);\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 .header-actions .search-btn {\n flex-shrink: 0;\n }\n\n /* Search bar collapses to the icon-only circle on small viewports \u2014\n the placeholder text + kbd chip are already hidden via .desktop-only.\n The omnibar-off mobile trigger (.search-btn-mobile) becomes visible here;\n its .desktop-only composite sibling is hidden by the rule above. */\n .search-btn {\n display: flex;\n width: 40px;\n height: 40px;\n padding: 0;\n justify-content: center;\n border: none;\n border-radius: 50%;\n background: none;\n }\n .search-btn i {\n font-size: var(--mj-text-lg);\n }\n .search-btn:hover {\n background: var(--mj-bg-surface-hover);\n border: none;\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: var(--mj-space-3) var(--mj-space-4);\n}\n\n::ng-deep .settings-fullscreen-window .k-window-title {\n font-size: var(--mj-text-lg);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n}\n\n::ng-deep .settings-fullscreen-window .k-window-titlebar-actions {\n gap: var(--mj-space-1);\n}\n\n::ng-deep .settings-fullscreen-window .k-window-titlebar-action {\n width: 32px;\n height: 32px;\n border-radius: var(--mj-radius-md);\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/* Universal search is a right-anchored bar affordance in header-actions\n (2026-07 design review round 2): both experiences still open as overlays \u2014\n the bar is a trigger, not an inline input. Icon-only under 768px. */\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: var(--mj-bg-overlay);\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: var(--mj-radius-lg);\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 var(--mj-transition-base), transform var(--mj-transition-base);\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: var(--mj-space-2);\n padding: var(--mj-space-3);\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: var(--mj-space-2) var(--mj-space-3);\n font-size: var(--mj-text-sm);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-sm);\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: var(--mj-radius-md);\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: var(--mj-text-base);\n transition: background var(--mj-transition-fast);\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: var(--mj-font-semibold);\n border-radius: var(--mj-radius-full);\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: var(--mj-leading-none);\n box-shadow: var(--mj-shadow-sm);\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: var(--mj-space-7) var(--mj-space-10);\n display: flex;\n align-items: center;\n gap: var(--mj-space-4);\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 var(--mj-space-1);\n border-radius: var(--mj-radius-md);\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 10px;\n font-weight: var(--mj-font-bold);\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: var(--mj-radius-md);\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: var(--mj-space-2-5) var(--mj-space-3);\n font-weight: var(--mj-font-bold);\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: var(--mj-space-1) var(--mj-space-1-5);\n border-radius: var(--mj-radius-md);\n}\n.activity-clear:hover { color: var(--mj-text-primary); background: var(--mj-bg-surface-hover); }\n.activity-list { overflow-y: auto; padding: var(--mj-space-1-5); }\n.activity-row {\n display: flex;\n gap: var(--mj-space-2-5);\n padding: var(--mj-space-2);\n border-radius: var(--mj-radius-md);\n}\n.activity-row:hover { background: var(--mj-bg-surface-hover); }\n.activity-row-icon { margin-top: var(--mj-space-0-5); 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: var(--mj-font-semibold); color: var(--mj-text-primary); }\n.activity-row-detail { font-size: 0.72rem; color: var(--mj-text-muted); margin-top: var(--mj-space-px); }\n.activity-bar {\n margin-top: var(--mj-space-1-5);\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 var(--mj-transition-slow); }\n\n"] }]
|
|
3762
|
+
args: [{ standalone: false, selector: 'mj-shell', template: "<div class=\"shell-container\" [class.hidden]=\"loading\" [class.tabs-visible]=\"tabBarVisible\">\n <!-- Skip link (WCAG 2.4.1) \u2014 MUST stay the first focusable element in the shell.\n Consuming apps that added their own skip link should remove it on upgrade. -->\n <a class=\"mj-skip-link\" href=\"#mj-main-content\" (click)=\"skipToMainContent($event)\">Skip to main content</a>\n\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\" #mobileNavToggle (click)=\"toggleMobileNav()\" title=\"Menu\"\n aria-label=\"Menu\" [attr.aria-expanded]=\"mobileNavOpen\" aria-controls=\"mj-mobile-nav-drawer\">\n <i class=\"fa-solid fa-bars\" aria-hidden=\"true\"></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 [attr.aria-current]=\"IsActiveApp(app) ? 'true' : null\"\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, and\n removable per deployment via 'Shell.AppSwitcher.Enabled') -->\n @if (!appSwitchingLocked && ShowAppSwitcher) {\n <mj-app-switcher\n [activeApp]=\"activeApp\"\n [isViewingSystemTab]=\"isViewingSystemTab\"\n [loadingAppId]=\"loadingAppId\"\n [SwitcherStyle]=\"AppSwitcherStyle\"\n [Provider]=\"Provider\"\n (appSelected)=\"onAppSwitch($event)\">\n </mj-app-switcher>\n }\n\n <!-- App Navigation (desktop only; removable per deployment via 'Shell.AppNav.Enabled') -->\n @if (activeApp && ShowAppNav) {\n <mj-app-nav\n class=\"desktop-nav\"\n [app]=\"activeApp\"\n [OverflowEnabled]=\"true\"\n (navItemClick)=\"onNavItemClick($event)\"\n (navItemDismiss)=\"onNavItemDismiss($event)\">\n <!-- Records style: persistent Records pill \u2014 projected into the nav\n row's trailing slot so it sits pipe-separated right after the\n app's own items, styled as a nav pill. Appears only while any\n record is open; resumes the last-viewed record on click. -->\n @if (RecordTabsStyle) {\n <mj-records-hub-pill></mj-records-hub-pill>\n }\n </mj-app-nav>\n } @else if (RecordTabsStyle) {\n <!-- Reachability: when the app nav doesn't render (AppNav disabled per\n deployment, or no active app), open records must STILL have a way\n back \u2014 render the pill standalone in the header. -->\n <mj-records-hub-pill class=\"desktop-nav\"></mj-records-hub-pill>\n }\n\n <!-- Spacer -->\n <div class=\"spacer\"></div>\n <!-- Actions (activity, notifications, user menu) -->\n <div class=\"header-actions\">\n <!-- Universal Search \u2014 right-anchored with the action cluster, static width\n (2026-07 review consensus: visible when space permits, never resizes).\n Omnibar ON: a button styled as an input \u2014 clicking (or Ctrl/Cmd+K) opens\n the modal palette; typing happens there. Collapses to the icon circle at\n the mobile breakpoint.\n Omnibar OFF: a REAL inline input (mj-search-composite) \u2014 results attach\n beneath it as a suggest dropdown with a \"See all results\" footer. On\n mobile the composite hides and an icon button opens the Spotlight\n overlay instead (same slot, same collapse point). -->\n @if (ShowSearchBar) {\n @if (UseOmnibar) {\n <button class=\"search-btn\" title=\"Search everything\"\n [attr.aria-label]=\"'Search everything (' + OmnibarShortcutLabel + ')'\"\n (click)=\"OnHeaderSearchClick()\">\n <i class=\"fa-solid fa-magnifying-glass\"></i>\n <span class=\"search-btn-text desktop-only\">Search everything</span>\n <kbd class=\"search-btn-kbd desktop-only\" aria-hidden=\"true\">{{ OmnibarShortcutLabel }}</kbd>\n </button>\n } @else {\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 [ShowPromo]=\"ShowOmnibarPromo\"\n [PromoText]=\"OmnibarPromoText\"\n (ResultSelected)=\"OnSearchResultSelected($event)\"\n (SearchSubmitted)=\"OnSearchSubmitted($event)\"\n (SeeAllRequested)=\"OnSeeAllSearch($event)\"\n (RecentRecordSelected)=\"OnSearchResultSelected($event)\"\n (PromoAccepted)=\"OnOmnibarPromoAccepted($event)\"\n (PromoDismissed)=\"OnOmnibarPromoDismissed()\">\n </mj-search-composite>\n </div>\n <button class=\"search-btn search-btn-mobile\" title=\"Search everything\"\n [attr.aria-label]=\"'Search everything (' + OmnibarShortcutLabel + ')'\"\n (click)=\"OnHeaderSearchClick()\">\n <i class=\"fa-solid fa-magnifying-glass\"></i>\n </button>\n }\n }\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 @if (ShowNotifications) {\n <button class=\"icon-btn desktop-only notification-btn\" title=\"Notifications\" (click)=\"showNotifications()\">\n <i class=\"fa-solid fa-bell\"></i>\n @if (unreadNotificationCount > 0) {\n <span class=\"notification-badge\">\n {{ unreadNotificationCount > 99 ? '99+' : unreadNotificationCount }}\n </span>\n }\n </button>\n }\n <!-- Nav Bar Apps: Left of User Menu -->\n @if (leftOfUserMenuApps.length > 0) {\n <div class=\"nav-bar-apps left-of-user-menu\">\n @for (app of leftOfUserMenuApps; track app) {\n <button\n class=\"nav-bar-app-btn\"\n [class.active]=\"IsActiveApp(app)\"\n [attr.aria-current]=\"IsActiveApp(app) ? 'true' : null\"\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 [attr.aria-label]=\"avatarAriaLabel\"\n [attr.aria-expanded]=\"userMenuVisible\">\n @if (userImageURL) {\n <img [src]=\"userImageURL\" alt=\"\" aria-hidden=\"true\" class=\"avatar-img\" />\n } @else {\n <div class=\"icon-fallback\" aria-hidden=\"true\">\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\" [attr.inert]=\"isSearchOpen ? null : ''\">\n <div class=\"search-popup-content\" (click)=\"$event.stopPropagation()\">\n <mj-dropdown\n [Data]=\"searchableEntities\"\n TextField=\"Name\"\n ValueField=\"ID\"\n AriaLabel=\"Search in\"\n class=\"search-entity-dropdown\"\n [(ngModel)]=\"selectedEntity\">\n </mj-dropdown>\n <input\n type=\"text\"\n #searchInput\n placeholder=\"Search...\"\n aria-label=\"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\" id=\"mj-mobile-nav-drawer\" #mobileNavDrawer\n [class.open]=\"mobileNavOpen\" [attr.inert]=\"mobileNavOpen ? null : ''\">\n <div class=\"mobile-nav-header\">\n <span>Navigation</span>\n <button class=\"close-btn\" (click)=\"closeMobileNav()\" aria-label=\"Close navigation\">\n <i class=\"fa-solid fa-xmark\" aria-hidden=\"true\"></i>\n </button>\n </div>\n @if (activeApp && ShowAppNav) {\n <div class=\"mobile-nav-content\">\n <div class=\"mobile-nav-section-title\">{{ activeApp.Name }}</div>\n <mj-app-nav\n [app]=\"activeApp\"\n [OverflowEnabled]=\"false\"\n (navItemClick)=\"onNavItemClick($event)\"\n (navItemDismiss)=\"onNavItemDismiss($event)\">\n </mj-app-nav>\n </div>\n }\n <!-- Records style: the desktop pill lives in the (mobile-hidden) app nav,\n so the drawer carries its own entry \u2014 without it, open records are\n unreachable on mobile except by re-opening them. Resumes the\n last-viewed record and closes the drawer. -->\n @if (RecordTabsStyle) {\n <div class=\"mobile-nav-records\">\n <mj-records-hub-pill (Activated)=\"closeMobileNav()\"></mj-records-hub-pill>\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 @if (ShowNotifications) {\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 }\n </div>\n </div>\n\n <!-- Tab Container - with dynamic tab bar visibility -->\n <mj-tab-container\n id=\"mj-main-content\"\n role=\"main\"\n tabindex=\"-1\"\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<!-- Unified command palette (Shell.Omnibar.Enabled). Rendered only while the search bar is:\n when Instance Config or the host's chrome policy hides search, the palette must not\n remain reachable through Ctrl/Cmd+K. -->\n@if (ShowSearchBar) {\n <mj-omnibar-palette #omnibarPalette (SettingsRequested)=\"OnPaletteSettingsRequested()\"></mj-omnibar-palette>\n}\n\n<!-- Legacy universal search as a Spotlight-style overlay \u2014 omnibar-off MOBILE only\n (on desktop the inline header composite owns the experience; this opens from\n the mobile icon or Ctrl/Cmd+K when the composite isn't visible).\n The shell owns the Ctrl/Cmd+K chord, so the overlay's own global shortcut is off. -->\n@if (ShowSearchBar && !UseOmnibar) {\n <mj-search-overlay\n [(IsOpen)]=\"LegacySearchOpen\"\n Placeholder=\"Search everything...\"\n [EnableGlobalShortcut]=\"false\"\n [ShowPromo]=\"ShowOmnibarPromo\"\n [PromoText]=\"OmnibarPromoText\"\n (ResultSelected)=\"OnOverlayResultSelected($event)\"\n (SeeAllRequested)=\"OnOverlaySeeAll($event)\"\n (PromoAccepted)=\"OnOmnibarPromoAccepted($event)\"\n (PromoDismissed)=\"OnOmnibarPromoDismissed()\">\n </mj-search-overlay>\n}\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 tokens for theme switching & white-labeling.\n Geometry follows --mj-logo-width/-height so a differently-shaped org mark fits;\n --mj-logo-plate-bg is set by the theme engine only when a single-variant logo needs\n a legibility plate in the mode it wasn't designed for (org-theming Phase 4). */\n.mj-logo {\n width: var(--mj-logo-width, 32px);\n height: var(--mj-logo-height, 18px);\n background-image: var(--mj-logo-mark);\n background-color: var(--mj-logo-plate-bg, transparent);\n background-repeat: no-repeat;\n background-position: center;\n background-size: contain;\n border-radius: var(--mj-radius-sm, 4px);\n flex-shrink: 0;\n}\n\n/* Skip link (WCAG 2.4.1) \u2014 off-screen until focused, then pinned over the header.\n It is the first focusable element in the shell; consuming apps should drop their\n own skip link on upgrade rather than stacking a second one in front of this. */\n.mj-skip-link {\n position: absolute;\n top: var(--mj-space-2);\n left: var(--mj-space-2);\n z-index: 100000;\n padding: var(--mj-space-2) var(--mj-space-4);\n background: var(--mj-bg-surface-elevated);\n color: var(--mj-text-primary);\n border: 1px solid var(--mj-border-strong);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-lg);\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n text-decoration: none;\n transform: translateY(-200%);\n transition: transform var(--mj-transition-fast);\n}\n.mj-skip-link:focus,\n.mj-skip-link:focus-visible {\n transform: translateY(0);\n outline: var(--mj-ring-width) solid var(--mj-focus-ring-color);\n outline-offset: var(--mj-ring-offset);\n}\n\n/* The main landmark is also the skip-link target; focusing it programmatically must\n not paint a ring on a region the user did not tab to. */\nmj-tab-container:focus {\n outline: none;\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 \u2014 scoped to the MAIN\n region: the RECORDS region is a separate Golden Layout whose tab strip is\n its whole point (switching between open records) and must never be hidden\n by the main bar's visibility policy. */\nmj-tab-container.hide-tab-bar ::ng-deep .main-region .lm_header {\n display: none;\n}\n\n/* Show tab headers when multiple tabs */\nmj-tab-container:not(.hide-tab-bar) ::ng-deep .main-region .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 .main-region .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 var(--mj-space-4);\n gap: var(--mj-space-4);\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: var(--mj-space-1);\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: var(--mj-space-2);\n}\n\n.nav-bar-app-btn {\n --app-color: var(--mj-text-muted);\n width: 40px;\n height: 40px;\n border-radius: var(--mj-radius-md);\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: var(--mj-text-lg);\n transition: all var(--mj-transition-fast);\n position: relative;\n}\n\n.nav-bar-app-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n/* Active = brand-primary (matches nav pills + switcher items); the app's\n metadata color is reserved for identity accents, never state.\n Shared active-tint recipe. */\n.nav-bar-app-btn.active {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n color: var(--mj-brand-primary);\n}\n\n.nav-bar-app-btn i {\n transition: transform var(--mj-transition-fast);\n margin-top: var(--mj-space-0-5); /* 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/* Priority+ overflow support: on desktop the app nav owns the header's free\n middle space (so it knows exactly how much room its items have) and the\n spacer stands down. On mobile the nav is display:none'd, so the spacer's\n flex: 1 keeps the action cluster right-aligned. When the nav isn't rendered\n at all (app-locked sessions, Shell.AppNav.Enabled off), the sibling selector\n doesn't match and the spacer behaves as before. */\n@media (min-width: 769px) {\n mj-app-nav.desktop-nav {\n flex: 1 1 auto;\n min-width: 0;\n }\n mj-app-nav.desktop-nav + .spacer {\n flex: 0 0 0px;\n }\n}\n\n.header-actions {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\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: var(--mj-text-lg);\n transition: background var(--mj-transition-fast);\n}\n\n.icon-btn:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n/* Keyboard focus parity for all header controls (the search bar already has\n its own ring at .search-btn:focus-visible). */\n.nav-bar-app-btn:focus-visible,\n.icon-btn:focus-visible,\n.hamburger-btn:focus-visible,\n.user-menu .avatar-btn:focus-visible {\n outline: 2px solid var(--mj-border-focus);\n outline-offset: 2px;\n}\n\n/* Universal search: a static-width bar styled as an input, anchored on the\n right with the action cluster. Deliberately NOT resizable on hover/focus \u2014\n chrome that shifts on interaction was rejected in the 2026-07 review. It's a\n button (typing happens in the overlay it opens), so no focus/caret styling. */\n.search-btn {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n width: 260px;\n height: 36px;\n padding: 0 var(--mj-space-2-5) 0 var(--mj-space-3-5);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n font-size: var(--mj-text-sm);\n font-family: inherit;\n cursor: pointer;\n transition: var(--mj-transition-colors);\n}\n\n.search-btn:hover {\n border-color: var(--mj-border-strong);\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-secondary);\n}\n\n.search-btn:focus-visible {\n outline: none;\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n/* Omnibar-off mobile trigger: hidden on desktop (the inline composite renders\n instead); the 768px block flips it on as the icon circle. */\n.search-btn-mobile {\n display: none;\n}\n\n/* Omnibar-off desktop: the inline search composite, same slot + width as the\n omnibar bar so the opt-in toggle doesn't move the header. */\n.shell-search-bar {\n position: relative;\n width: 260px;\n z-index: 99999;\n}\n\n/* The suggest dropdown needs more width than its 260px anchor. Pin it to the\n anchor's right edge and let it grow leftward \u2014 the bar is right-anchored, so\n leftward growth stays on screen. */\n.shell-search-bar ::ng-deep .suggest-dropdown {\n left: auto;\n right: 0;\n width: min(560px, calc(100vw - var(--mj-space-6)));\n}\n\n.search-btn i {\n font-size: var(--mj-text-sm);\n flex-shrink: 0;\n}\n\n.search-btn .search-btn-text {\n flex: 1;\n min-width: 0;\n text-align: left;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* kbd chip: deliberately mirrors the omnibar palette's .ob-kbd chrome\n (10.5px / 5px radius / bottom-heavy border) so the affordance and the\n surface it summons read as one system. */\n.search-btn .search-btn-kbd {\n flex-shrink: 0;\n white-space: nowrap;\n font-family: inherit;\n font-size: 10.5px;\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-muted);\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-bottom-width: 2px;\n border-radius: 5px;\n padding: 1.5px var(--mj-space-1-5);\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 var(--mj-space-1);\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n font-size: 10px;\n font-weight: var(--mj-font-semibold);\n border-radius: var(--mj-radius-full);\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: var(--mj-leading-none);\n box-shadow: var(--mj-shadow-sm);\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 var(--mj-transition-fast), transform var(--mj-transition-fast);\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 var(--mj-transition-fast);\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: var(--mj-text-base);\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: var(--mj-shadow-sm);\n}\n\n.user-menu .avatar-btn:hover .avatar-img {\n box-shadow: var(--mj-shadow-md);\n}\n\n/* User Menu Header */\n.user-menu-header {\n padding: var(--mj-space-3) var(--mj-space-4);\n background: var(--mj-bg-surface-sunken);\n}\n\n.user-menu-header .user-info {\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-0-5);\n}\n\n.user-menu-header .user-name {\n font-weight: var(--mj-font-semibold);\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n}\n\n.user-menu-header .user-email {\n font-size: var(--mj-text-xs);\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: var(--mj-space-2);\n background: var(--mj-bg-surface-elevated);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-lg);\n min-width: 180px;\n /* Never wider than the viewport, never taller than what is left below the 60px header:\n a short window (or a phone) used to leave the bottom items unreachable, because the\n menu had no height limit and clipped instead of scrolling. */\n max-width: min(360px, calc(100vw - 2 * var(--mj-space-4)));\n max-height: calc(100vh - 60px - 3 * var(--mj-space-2));\n max-height: calc(100dvh - 60px - 3 * var(--mj-space-2));\n z-index: 10000;\n overflow-x: hidden;\n overflow-y: auto;\n}\n\n.user-menu-item {\n display: flex;\n align-items: center;\n gap: var(--mj-space-3);\n padding: var(--mj-space-3) var(--mj-space-4);\n cursor: pointer;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n transition: background var(--mj-transition-fast);\n}\n\n.user-menu-item i {\n width: 18px;\n text-align: center;\n color: var(--mj-text-muted);\n font-size: var(--mj-text-sm);\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: var(--mj-space-1) 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: var(--mj-radius-full);\n background: var(--mj-bg-surface-active);\n margin-left: auto;\n transition: background var(--mj-transition-base);\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: var(--mj-shadow-sm);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: transform var(--mj-transition-base);\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: var(--mj-radius-md);\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: var(--mj-text-xl);\n transition: background var(--mj-transition-fast);\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: var(--mj-bg-overlay);\n z-index: 9998;\n}\n\n/* Mobile Navigation Drawer */\n/* `visibility` is transitioned alongside `transform` so the closed drawer is genuinely\n hidden \u2014 off-screen alone leaves its controls hit-testable and visible to\n checkVisibility(), which is what let 6 of its 8 controls keep taking focus. The\n delay holds visibility through the slide-out, then drops it; opening is instant\n (0s) so the drawer is present for the whole slide-in. `inert` (set in the template)\n is the actual focus guard; this keeps the CSS from disagreeing with it. */\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 visibility: hidden;\n transition: transform var(--mj-transition-slow), visibility 0s linear 300ms;\n}\n.mobile-nav-drawer.open {\n transform: translateX(0);\n visibility: visible;\n transition: transform var(--mj-transition-slow), visibility 0s linear 0s;\n}\n\n/* Reduced motion: no slide, so nothing to hold visibility open for. */\n@media (prefers-reduced-motion: reduce) {\n .mobile-nav-drawer,\n .mobile-nav-drawer.open {\n transition: none;\n }\n}\n\n.mobile-nav-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: var(--mj-space-4) var(--mj-space-5);\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: var(--mj-font-semibold);\n font-size: var(--mj-text-base);\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: var(--mj-text-lg);\n transition: background var(--mj-transition-fast);\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: var(--mj-space-4) 0;\n}\n\n.mobile-nav-section-title {\n padding: var(--mj-space-2) var(--mj-space-5);\n font-size: var(--mj-text-xs);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-disabled);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n/* Records entry in the mobile drawer (records-style record opens) \u2014\n the desktop pill lives in the mobile-hidden app nav, so the drawer\n carries its own touch-friendly instance. */\n.mobile-nav-records {\n padding: var(--mj-space-2) var(--mj-space-3);\n border-top: 1px solid var(--mj-border-default);\n}\n.mobile-nav-records .records-pill {\n width: 100%;\n min-height: 48px; /* Touch-target parity with drawer nav items */\n justify-content: flex-start;\n}\n\n.mobile-nav-footer {\n border-top: 1px solid var(--mj-border-default);\n padding: var(--mj-space-3) var(--mj-space-4);\n display: flex;\n flex-direction: column;\n gap: var(--mj-space-1);\n}\n\n.mobile-nav-action {\n position: relative;\n display: flex;\n align-items: center;\n gap: var(--mj-space-3);\n padding: var(--mj-space-3) var(--mj-space-4);\n border: none;\n background: none;\n cursor: pointer;\n border-radius: var(--mj-radius-md);\n color: var(--mj-text-secondary);\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-medium);\n transition: background var(--mj-transition-fast);\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: var(--mj-text-base);\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 var(--mj-space-3);\n gap: var(--mj-space-2);\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 .header-actions .search-btn {\n flex-shrink: 0;\n }\n\n /* Search bar collapses to the icon-only circle on small viewports \u2014\n the placeholder text + kbd chip are already hidden via .desktop-only.\n The omnibar-off mobile trigger (.search-btn-mobile) becomes visible here;\n its .desktop-only composite sibling is hidden by the rule above. */\n .search-btn {\n display: flex;\n width: 40px;\n height: 40px;\n padding: 0;\n justify-content: center;\n border: none;\n border-radius: 50%;\n background: none;\n }\n .search-btn i {\n font-size: var(--mj-text-lg);\n }\n .search-btn:hover {\n background: var(--mj-bg-surface-hover);\n border: none;\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: var(--mj-space-3) var(--mj-space-4);\n}\n\n::ng-deep .settings-fullscreen-window .k-window-title {\n font-size: var(--mj-text-lg);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n}\n\n::ng-deep .settings-fullscreen-window .k-window-titlebar-actions {\n gap: var(--mj-space-1);\n}\n\n::ng-deep .settings-fullscreen-window .k-window-titlebar-action {\n width: 32px;\n height: 32px;\n border-radius: var(--mj-radius-md);\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/* Universal search is a right-anchored bar affordance in header-actions\n (2026-07 design review round 2): both experiences still open as overlays \u2014\n the bar is a trigger, not an inline input. Icon-only under 768px. */\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: var(--mj-bg-overlay);\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: var(--mj-radius-lg);\n box-shadow: var(--mj-shadow-xl);\n z-index: 10000;\n opacity: 0;\n transform: translateY(-10px);\n pointer-events: none;\n visibility: hidden;\n transition: opacity var(--mj-transition-base), transform var(--mj-transition-base), visibility 0s linear 200ms;\n}\n\n.search-popup.open {\n opacity: 1;\n transform: translateY(0);\n pointer-events: all;\n visibility: visible;\n transition: opacity var(--mj-transition-base), transform var(--mj-transition-base), visibility 0s linear 0s;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .search-popup,\n .search-popup.open {\n transition: none;\n }\n}\n\n.search-popup-content {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n padding: var(--mj-space-3);\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: var(--mj-space-2) var(--mj-space-3);\n font-size: var(--mj-text-sm);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-sm);\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: var(--mj-radius-md);\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: var(--mj-text-base);\n transition: background var(--mj-transition-fast);\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: var(--mj-font-semibold);\n border-radius: var(--mj-radius-full);\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: var(--mj-leading-none);\n box-shadow: var(--mj-shadow-sm);\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: var(--mj-space-7) var(--mj-space-10);\n display: flex;\n align-items: center;\n gap: var(--mj-space-4);\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 var(--mj-space-1);\n border-radius: var(--mj-radius-md);\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 10px;\n font-weight: var(--mj-font-bold);\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: var(--mj-radius-md);\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: var(--mj-space-2-5) var(--mj-space-3);\n font-weight: var(--mj-font-bold);\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: var(--mj-space-1) var(--mj-space-1-5);\n border-radius: var(--mj-radius-md);\n}\n.activity-clear:hover { color: var(--mj-text-primary); background: var(--mj-bg-surface-hover); }\n.activity-list { overflow-y: auto; padding: var(--mj-space-1-5); }\n.activity-row {\n display: flex;\n gap: var(--mj-space-2-5);\n padding: var(--mj-space-2);\n border-radius: var(--mj-radius-md);\n}\n.activity-row:hover { background: var(--mj-bg-surface-hover); }\n.activity-row-icon { margin-top: var(--mj-space-0-5); 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: var(--mj-font-semibold); color: var(--mj-text-primary); }\n.activity-row-detail { font-size: 0.72rem; color: var(--mj-text-muted); margin-top: var(--mj-space-px); }\n.activity-bar {\n margin-top: var(--mj-space-1-5);\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 var(--mj-transition-slow); }\n\n"] }]
|
|
3630
3763
|
}], () => [{ 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: [{
|
|
3631
3764
|
type: ViewChild,
|
|
3632
3765
|
args: ['searchInput']
|
|
3766
|
+
}], mobileNavDrawer: [{
|
|
3767
|
+
type: ViewChild,
|
|
3768
|
+
args: ['mobileNavDrawer']
|
|
3769
|
+
}], mobileNavToggle: [{
|
|
3770
|
+
type: ViewChild,
|
|
3771
|
+
args: ['mobileNavToggle']
|
|
3633
3772
|
}], omnibarPalette: [{
|
|
3634
3773
|
type: ViewChild,
|
|
3635
3774
|
args: ['omnibarPalette']
|
|
@@ -3652,5 +3791,5 @@ export class ShellComponent extends BaseAngularComponent {
|
|
|
3652
3791
|
type: HostListener,
|
|
3653
3792
|
args: ['document:click']
|
|
3654
3793
|
}] }); })();
|
|
3655
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ShellComponent, { className: "ShellComponent", filePath: "src/lib/shell/shell.component.ts", lineNumber:
|
|
3794
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ShellComponent, { className: "ShellComponent", filePath: "src/lib/shell/shell.component.ts", lineNumber: 58 }); })();
|
|
3656
3795
|
//# sourceMappingURL=shell.component.js.map
|