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