@memberjunction/ng-explorer-core 5.30.0 → 5.31.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 +9 -0
- package/dist/app-routing.module.d.ts.map +1 -1
- package/dist/app-routing.module.js +13 -1
- 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 +5 -3
- package/dist/generated/lazy-feature-config.js.map +1 -1
- package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.d.ts +2 -1
- package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.d.ts.map +1 -1
- package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.js +12 -11
- package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.js.map +1 -1
- package/dist/lib/guards/entities.guard.d.ts +2 -1
- package/dist/lib/guards/entities.guard.d.ts.map +1 -1
- package/dist/lib/guards/entities.guard.js +14 -1
- package/dist/lib/guards/entities.guard.js.map +1 -1
- package/dist/lib/oauth/oauth-callback.component.d.ts +2 -1
- package/dist/lib/oauth/oauth-callback.component.d.ts.map +1 -1
- package/dist/lib/oauth/oauth-callback.component.js +7 -6
- package/dist/lib/oauth/oauth-callback.component.js.map +1 -1
- package/dist/lib/resource-wrappers/artifact-resource.component.js +2 -3
- package/dist/lib/resource-wrappers/artifact-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/chat-collections-resource.component.js +3 -3
- package/dist/lib/resource-wrappers/chat-collections-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/chat-conversations-resource.component.js +4 -4
- package/dist/lib/resource-wrappers/chat-conversations-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/chat-tasks-resource.component.js +1 -2
- package/dist/lib/resource-wrappers/chat-tasks-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/dashboard-resource.component.js +5 -5
- package/dist/lib/resource-wrappers/dashboard-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/list-detail-resource.component.js +2 -2
- package/dist/lib/resource-wrappers/list-detail-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/query-resource.component.js +2 -2
- package/dist/lib/resource-wrappers/query-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/record-resource.component.d.ts +2 -2
- package/dist/lib/resource-wrappers/record-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/record-resource.component.js +8 -7
- package/dist/lib/resource-wrappers/record-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/search-results-resource.component.js +3 -3
- package/dist/lib/resource-wrappers/search-results-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/view-resource.component.d.ts +1 -1
- package/dist/lib/resource-wrappers/view-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/view-resource.component.js +3 -3
- package/dist/lib/resource-wrappers/view-resource.component.js.map +1 -1
- package/dist/lib/services/startup-validation.service.d.ts +9 -0
- package/dist/lib/services/startup-validation.service.d.ts.map +1 -1
- package/dist/lib/services/startup-validation.service.js +13 -1
- package/dist/lib/services/startup-validation.service.js.map +1 -1
- package/dist/lib/shell/components/tabs/tab-container.component.d.ts +2 -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 +7 -5
- package/dist/lib/shell/components/tabs/tab-container.component.js.map +1 -1
- package/dist/lib/shell/shell.component.d.ts +5 -2
- package/dist/lib/shell/shell.component.d.ts.map +1 -1
- package/dist/lib/shell/shell.component.js +43 -27
- package/dist/lib/shell/shell.component.js.map +1 -1
- package/dist/lib/single-dashboard/Components/add-item/add-item.component.d.ts +3 -2
- 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 +8 -6
- package/dist/lib/single-dashboard/Components/add-item/add-item.component.js.map +1 -1
- package/dist/lib/single-dashboard/single-dashboard.component.js +1 -2
- package/dist/lib/single-dashboard/single-dashboard.component.js.map +1 -1
- package/dist/lib/single-list-detail/single-list-detail.component.d.ts +2 -1
- package/dist/lib/single-list-detail/single-list-detail.component.d.ts.map +1 -1
- package/dist/lib/single-list-detail/single-list-detail.component.js +18 -16
- package/dist/lib/single-list-detail/single-list-detail.component.js.map +1 -1
- package/dist/lib/single-record/single-record.component.d.ts +2 -1
- package/dist/lib/single-record/single-record.component.d.ts.map +1 -1
- package/dist/lib/single-record/single-record.component.js +7 -5
- package/dist/lib/single-record/single-record.component.js.map +1 -1
- package/dist/lib/single-search-result/single-search-result.component.d.ts +2 -1
- package/dist/lib/single-search-result/single-search-result.component.d.ts.map +1 -1
- package/dist/lib/single-search-result/single-search-result.component.js +8 -6
- package/dist/lib/single-search-result/single-search-result.component.js.map +1 -1
- package/dist/lib/user-notifications/user-notifications.component.d.ts +2 -1
- package/dist/lib/user-notifications/user-notifications.component.d.ts.map +1 -1
- package/dist/lib/user-notifications/user-notifications.component.js +9 -7
- package/dist/lib/user-notifications/user-notifications.component.js.map +1 -1
- package/dist/lib/user-profile/user-profile.component.d.ts +2 -1
- package/dist/lib/user-profile/user-profile.component.d.ts.map +1 -1
- package/dist/lib/user-profile/user-profile.component.js +6 -5
- package/dist/lib/user-profile/user-profile.component.js.map +1 -1
- package/package.json +42 -41
|
@@ -2,14 +2,15 @@ import { Component, ViewChild, HostListener } from '@angular/core';
|
|
|
2
2
|
import { NavigationEnd } from '@angular/router';
|
|
3
3
|
import { combineLatest, Subject } from 'rxjs';
|
|
4
4
|
import { filter, takeUntil } from 'rxjs/operators';
|
|
5
|
-
import {
|
|
5
|
+
import { LogStatus, StartupManager, CompositeKey } from '@memberjunction/core';
|
|
6
6
|
import { MJEventType, MJGlobal, uuidv4, UUIDsEqual } from '@memberjunction/global';
|
|
7
|
-
import { EventCodes, SYSTEM_APP_ID } from '@memberjunction/ng-shared';
|
|
7
|
+
import { EventCodes, SharedService, SYSTEM_APP_ID } from '@memberjunction/ng-shared';
|
|
8
8
|
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
12
|
import { InstanceConfigEngine } from '@memberjunction/core-entities';
|
|
13
|
+
import { BaseAngularComponent } from '@memberjunction/ng-base-types';
|
|
13
14
|
import * as i0 from "@angular/core";
|
|
14
15
|
import * as i1 from "@memberjunction/ng-base-application";
|
|
15
16
|
import * as i2 from "@memberjunction/ng-shared";
|
|
@@ -18,18 +19,19 @@ import * as i4 from "@memberjunction/ng-auth-services";
|
|
|
18
19
|
import * as i5 from "@memberjunction/ng-user-avatar";
|
|
19
20
|
import * as i6 from "./services/settings-dialog.service";
|
|
20
21
|
import * as i7 from "./services/user-sharing-center-dialog.service";
|
|
21
|
-
import * as i8 from "../
|
|
22
|
-
import * as i9 from "
|
|
23
|
-
import * as i10 from "@memberjunction/ng-
|
|
24
|
-
import * as i11 from "@
|
|
25
|
-
import * as i12 from "@
|
|
26
|
-
import * as i13 from "@memberjunction/ng-
|
|
27
|
-
import * as i14 from "@memberjunction/ng-
|
|
28
|
-
import * as i15 from "
|
|
29
|
-
import * as i16 from "./components/header/app-
|
|
30
|
-
import * as i17 from "./components/
|
|
31
|
-
import * as i18 from "./components/
|
|
32
|
-
import * as i19 from "
|
|
22
|
+
import * as i8 from "../services/startup-validation.service";
|
|
23
|
+
import * as i9 from "../command-palette/command-palette.service";
|
|
24
|
+
import * as i10 from "@memberjunction/ng-file-storage";
|
|
25
|
+
import * as i11 from "@memberjunction/ng-feedback";
|
|
26
|
+
import * as i12 from "@angular/forms";
|
|
27
|
+
import * as i13 from "@memberjunction/ng-ui-components";
|
|
28
|
+
import * as i14 from "@memberjunction/ng-shared-generic";
|
|
29
|
+
import * as i15 from "@memberjunction/ng-search";
|
|
30
|
+
import * as i16 from "./components/header/app-switcher.component";
|
|
31
|
+
import * as i17 from "./components/header/app-nav.component";
|
|
32
|
+
import * as i18 from "./components/tabs/tab-container.component";
|
|
33
|
+
import * as i19 from "./components/dialogs/app-access-dialog.component";
|
|
34
|
+
import * as i20 from "../command-palette/command-palette.component";
|
|
33
35
|
const _c0 = ["searchInput"];
|
|
34
36
|
const _c1 = ["shellSearchComposite"];
|
|
35
37
|
const _c2 = ["appAccessDialog"];
|
|
@@ -345,7 +347,7 @@ function ShellComponent_Conditional_51_Template(rf, ctx) { if (rf & 1) {
|
|
|
345
347
|
* - Golden Layout-based tab container
|
|
346
348
|
* - Unified workspace state management
|
|
347
349
|
*/
|
|
348
|
-
export class ShellComponent {
|
|
350
|
+
export class ShellComponent extends BaseAngularComponent {
|
|
349
351
|
appManager;
|
|
350
352
|
workspaceManager;
|
|
351
353
|
layoutManager;
|
|
@@ -361,6 +363,7 @@ export class ShellComponent {
|
|
|
361
363
|
viewContainerRef;
|
|
362
364
|
titleService;
|
|
363
365
|
developerModeService;
|
|
366
|
+
startupValidationService;
|
|
364
367
|
commandPaletteService;
|
|
365
368
|
themeService;
|
|
366
369
|
homePinService;
|
|
@@ -452,7 +455,8 @@ export class ShellComponent {
|
|
|
452
455
|
return this.appManager.GetNavBarApps('Left of User Menu')
|
|
453
456
|
.filter(app => !(app.HideNavBarIconWhenActive && UUIDsEqual(app.ID, this.activeApp?.ID)));
|
|
454
457
|
}
|
|
455
|
-
constructor(appManager, workspaceManager, layoutManager, tabService, navigationService, route, router, authBase, cdr, userAvatarService, settingsDialogService, userSharingCenterDialogService, viewContainerRef, titleService, developerModeService, commandPaletteService, themeService, homePinService, fileOpenService, feedbackDialogService, feedbackService) {
|
|
458
|
+
constructor(appManager, workspaceManager, layoutManager, tabService, navigationService, route, router, authBase, cdr, userAvatarService, settingsDialogService, userSharingCenterDialogService, viewContainerRef, titleService, developerModeService, startupValidationService, commandPaletteService, themeService, homePinService, fileOpenService, feedbackDialogService, feedbackService) {
|
|
459
|
+
super();
|
|
456
460
|
this.appManager = appManager;
|
|
457
461
|
this.workspaceManager = workspaceManager;
|
|
458
462
|
this.layoutManager = layoutManager;
|
|
@@ -468,12 +472,24 @@ export class ShellComponent {
|
|
|
468
472
|
this.viewContainerRef = viewContainerRef;
|
|
469
473
|
this.titleService = titleService;
|
|
470
474
|
this.developerModeService = developerModeService;
|
|
475
|
+
this.startupValidationService = startupValidationService;
|
|
471
476
|
this.commandPaletteService = commandPaletteService;
|
|
472
477
|
this.themeService = themeService;
|
|
473
478
|
this.homePinService = homePinService;
|
|
474
479
|
this.fileOpenService = fileOpenService;
|
|
475
480
|
this.feedbackDialogService = feedbackDialogService;
|
|
476
481
|
this.feedbackService = feedbackService;
|
|
482
|
+
// Thread the active provider into the bootstrap services that need provider
|
|
483
|
+
// context. They each fall back to Metadata.Provider when no explicit provider
|
|
484
|
+
// is set, so this is a no-op for single-provider apps but enables correct
|
|
485
|
+
// behavior in multi-provider setups.
|
|
486
|
+
const providerForServices = this.ProviderToUse;
|
|
487
|
+
this.appManager.Provider = providerForServices;
|
|
488
|
+
this.workspaceManager.Provider = providerForServices;
|
|
489
|
+
this.developerModeService.Provider = providerForServices;
|
|
490
|
+
this.startupValidationService.Provider = providerForServices;
|
|
491
|
+
if (SharedService.Instance)
|
|
492
|
+
SharedService.Instance.Provider = providerForServices;
|
|
477
493
|
// Initialize theme immediately so loading UI shows correct colors from the start
|
|
478
494
|
this.activeTheme = getActiveTheme();
|
|
479
495
|
// Initialize animation based on theme configuration
|
|
@@ -532,7 +548,7 @@ export class ShellComponent {
|
|
|
532
548
|
LogStatus('InstanceConfigEngine initialization skipped (not critical)');
|
|
533
549
|
});
|
|
534
550
|
// Get current user
|
|
535
|
-
const md =
|
|
551
|
+
const md = this.ProviderToUse;
|
|
536
552
|
const user = md.CurrentUser;
|
|
537
553
|
if (!user) {
|
|
538
554
|
throw new Error('No current user found');
|
|
@@ -666,7 +682,7 @@ export class ShellComponent {
|
|
|
666
682
|
// Listen for avatar updates from settings page
|
|
667
683
|
this.subscriptions.push(MJGlobal.Instance.GetEventListener(false).subscribe(async (updateEvent) => {
|
|
668
684
|
if (updateEvent.eventCode === EventCodes.AvatarUpdated) {
|
|
669
|
-
const md =
|
|
685
|
+
const md = this.ProviderToUse;
|
|
670
686
|
const currentUserInfo = md.CurrentUser;
|
|
671
687
|
const userEntity = await md.GetEntityObject('MJ: Users');
|
|
672
688
|
await userEntity.Load(currentUserInfo.ID);
|
|
@@ -1973,7 +1989,7 @@ export class ShellComponent {
|
|
|
1973
1989
|
const feedbackEnabled = await this.feedbackService.IsEnabled();
|
|
1974
1990
|
// Build context for the menu
|
|
1975
1991
|
const context = {
|
|
1976
|
-
user:
|
|
1992
|
+
user: this.ProviderToUse.CurrentUser,
|
|
1977
1993
|
userEntity: this.userEntity,
|
|
1978
1994
|
shell: this,
|
|
1979
1995
|
viewContainerRef: this.viewContainerRef,
|
|
@@ -2210,7 +2226,7 @@ export class ShellComponent {
|
|
|
2210
2226
|
const recordId = config['recordId'];
|
|
2211
2227
|
if (!entityName || !recordId)
|
|
2212
2228
|
return null;
|
|
2213
|
-
const md =
|
|
2229
|
+
const md = this.ProviderToUse;
|
|
2214
2230
|
const entityInfo = md.Entities.find(e => e.Name === entityName);
|
|
2215
2231
|
if (!entityInfo)
|
|
2216
2232
|
return null;
|
|
@@ -2353,7 +2369,7 @@ export class ShellComponent {
|
|
|
2353
2369
|
*/
|
|
2354
2370
|
async loadUserAvatar(currentUserInfo) {
|
|
2355
2371
|
try {
|
|
2356
|
-
const md =
|
|
2372
|
+
const md = this.ProviderToUse;
|
|
2357
2373
|
this.userName = currentUserInfo.FirstLast || currentUserInfo.Name || 'User';
|
|
2358
2374
|
this.userEmail = currentUserInfo.Email || '';
|
|
2359
2375
|
// Load the full MJUserEntity to access avatar fields
|
|
@@ -2441,7 +2457,7 @@ export class ShellComponent {
|
|
|
2441
2457
|
* Load searchable entities from metadata
|
|
2442
2458
|
*/
|
|
2443
2459
|
async loadSearchableEntities() {
|
|
2444
|
-
const md =
|
|
2460
|
+
const md = this.ProviderToUse;
|
|
2445
2461
|
this.searchableEntities = md.Entities.filter((e) => e.AllowUserSearchAPI).sort((a, b) => a.Name.localeCompare(b.Name));
|
|
2446
2462
|
if (this.searchableEntities.length > 0) {
|
|
2447
2463
|
this.selectedEntity = this.searchableEntities[0];
|
|
@@ -2854,7 +2870,7 @@ export class ShellComponent {
|
|
|
2854
2870
|
this.cdr.detectChanges();
|
|
2855
2871
|
}
|
|
2856
2872
|
}
|
|
2857
|
-
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(i7.UserSharingCenterDialogService), i0.ɵɵdirectiveInject(i0.ViewContainerRef), i0.ɵɵdirectiveInject(i2.TitleService), i0.ɵɵdirectiveInject(i2.DeveloperModeService), i0.ɵɵdirectiveInject(i8.CommandPaletteService), i0.ɵɵdirectiveInject(i2.ThemeService), i0.ɵɵdirectiveInject(i2.HomeAppPinService), i0.ɵɵdirectiveInject(
|
|
2873
|
+
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(i7.UserSharingCenterDialogService), i0.ɵɵdirectiveInject(i0.ViewContainerRef), i0.ɵɵdirectiveInject(i2.TitleService), i0.ɵɵdirectiveInject(i2.DeveloperModeService), i0.ɵɵdirectiveInject(i8.StartupValidationService), i0.ɵɵdirectiveInject(i9.CommandPaletteService), i0.ɵɵdirectiveInject(i2.ThemeService), i0.ɵɵdirectiveInject(i2.HomeAppPinService), i0.ɵɵdirectiveInject(i10.FileOpenService), i0.ɵɵdirectiveInject(i11.FeedbackDialogService), i0.ɵɵdirectiveInject(i11.FeedbackService)); };
|
|
2858
2874
|
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ShellComponent, selectors: [["mj-shell"]], viewQuery: function ShellComponent_Query(rf, ctx) { if (rf & 1) {
|
|
2859
2875
|
i0.ɵɵviewQuery(_c0, 5)(_c1, 5)(TabContainerComponent, 5)(_c2, 5);
|
|
2860
2876
|
} if (rf & 2) {
|
|
@@ -2865,7 +2881,7 @@ export class ShellComponent {
|
|
|
2865
2881
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.appAccessDialog = _t.first);
|
|
2866
2882
|
} }, hostBindings: function ShellComponent_HostBindings(rf, ctx) { if (rf & 1) {
|
|
2867
2883
|
i0.ɵɵlistener("keydown", function ShellComponent_keydown_HostBindingHandler($event) { return ctx.OnGlobalKeydown($event); }, i0.ɵɵresolveDocument);
|
|
2868
|
-
} }, 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) {
|
|
2884
|
+
} }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], 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) {
|
|
2869
2885
|
const _r1 = i0.ɵɵgetCurrentView();
|
|
2870
2886
|
i0.ɵɵelementStart(0, "div", 3)(1, "header", 4);
|
|
2871
2887
|
i0.ɵɵelement(2, "div", 5);
|
|
@@ -2978,12 +2994,12 @@ export class ShellComponent {
|
|
|
2978
2994
|
i0.ɵɵconditional(ctx.loading ? 47 : -1);
|
|
2979
2995
|
i0.ɵɵadvance(4);
|
|
2980
2996
|
i0.ɵɵconditional(ctx.PinProgressVisible ? 51 : -1);
|
|
2981
|
-
} }, dependencies: [i11.NgControlStatus, i11.NgModel, i12.MJDropdownComponent, i13.LoadingComponent, i14.SearchCompositeComponent, i15.AppSwitcherComponent, i16.AppNavComponent, i17.TabContainerComponent, i18.AppAccessDialogComponent, i19.CommandPaletteComponent], styles: ["[_nghost-%COMP%] {\n display: block;\n height: 100%;\n width: 100%;\n overflow: hidden;\n}\n\n\n\n.mj-logo[_ngcontent-%COMP%] {\n width: 32px;\n height: 18px;\n background-image: var(--mj-logo-mark);\n background-repeat: no-repeat;\n background-position: center;\n background-size: contain;\n flex-shrink: 0;\n}\n\n.shell-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n overflow: hidden;\n position: relative;\n}\n\n\n\n\n.shell-container.hidden[_ngcontent-%COMP%] {\n visibility: hidden;\n position: absolute;\n pointer-events: none;\n}\n\nmj-tab-container[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n transition: all 0.2s ease-in-out;\n}\n\n\n\nmj-tab-container.hide-tab-bar[_ngcontent-%COMP%] .lm_header {\n display: none;\n}\n\n\n\nmj-tab-container[_ngcontent-%COMP%]:not(.hide-tab-bar) .lm_header {\n opacity: 1;\n max-height: 40px;\n transition: opacity 0.2s ease-in-out, max-height 0.2s ease-in-out;\n}\n\n\n\nmj-tab-container.hide-tab-bar[_ngcontent-%COMP%] .lm_content {\n height: 100% !important;\n}\n\n\n\nmj-tab-container[_ngcontent-%COMP%] .lm_stack {\n transition: all 0.2s ease-in-out;\n}\n\n.shell-header[_ngcontent-%COMP%] {\n height: 60px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n display: flex;\n align-items: center;\n padding: 0 16px;\n gap: 16px;\n box-shadow: var(--mj-shadow-sm);\n flex-shrink: 0;\n \n\n\n position: relative;\n z-index: 500;\n}\n\n\n\n.nav-bar-apps[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.nav-bar-apps.left-of-switcher[_ngcontent-%COMP%] {\n \n\n \n\n}\n\n.nav-bar-apps.left-of-user-menu[_ngcontent-%COMP%] {\n margin-right: 8px;\n}\n\n.nav-bar-app-btn[_ngcontent-%COMP%] {\n --app-color: var(--mj-text-muted);\n width: 40px;\n height: 40px;\n border-radius: 10px;\n border: none;\n background: transparent;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-secondary);\n font-size: 18px;\n transition: all 0.15s ease;\n position: relative;\n}\n\n.nav-bar-app-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--app-color) 15%, transparent);\n color: var(--app-color);\n}\n\n.nav-bar-app-btn.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--app-color) 20%, transparent);\n color: var(--app-color);\n}\n\n.nav-bar-app-btn.active[_ngcontent-%COMP%]::after {\n content: '';\n position: absolute;\n bottom: 6px;\n left: 50%;\n transform: translateX(-50%);\n width: 16px;\n height: 3px;\n background: var(--app-color);\n border-radius: 2px;\n}\n\n.nav-bar-app-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n transition: transform 0.15s ease;\n margin-top: 2px; \n\n}\n\n.nav-bar-app-btn[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n transform: scale(1.1);\n}\n\n.spacer[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.header-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.icon-btn[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n border-radius: 50%;\n border: none;\n background: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 18px;\n transition: background 0.15s;\n}\n\n.icon-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n\n\n.notification-btn[_ngcontent-%COMP%] {\n position: relative;\n}\n\n.notification-badge[_ngcontent-%COMP%] {\n position: absolute;\n top: 4px;\n right: 4px;\n min-width: 16px;\n height: 16px;\n padding: 0 4px;\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n font-size: 10px;\n font-weight: 600;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n}\n\n.user-menu[_ngcontent-%COMP%] {\n position: relative;\n}\n\n.user-menu[_ngcontent-%COMP%] .avatar-btn[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n border-radius: 50%;\n border: none;\n background: transparent;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: box-shadow 0.15s, transform 0.15s;\n padding: 0;\n overflow: hidden;\n}\n\n.user-menu[_ngcontent-%COMP%] .avatar-btn[_ngcontent-%COMP%]:hover {\n transform: scale(1.05);\n}\n\n\n\n.user-menu[_ngcontent-%COMP%] .avatar-btn[_ngcontent-%COMP%] .icon-fallback[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n border-radius: 50%;\n border: 2px solid var(--mj-border-default);\n background: var(--mj-bg-surface-hover);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: border-color 0.15s;\n}\n\n.user-menu[_ngcontent-%COMP%] .avatar-btn[_ngcontent-%COMP%]:hover .icon-fallback[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n}\n\n.user-menu[_ngcontent-%COMP%] .avatar-btn[_ngcontent-%COMP%] .icon-fallback[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 16px;\n}\n\n\n\n.user-menu[_ngcontent-%COMP%] .avatar-btn[_ngcontent-%COMP%] .avatar-img[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n border-radius: 50%;\n object-fit: cover;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);\n}\n\n.user-menu[_ngcontent-%COMP%] .avatar-btn[_ngcontent-%COMP%]:hover .avatar-img[_ngcontent-%COMP%] {\n box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);\n}\n\n\n\n.user-menu-header[_ngcontent-%COMP%] {\n padding: 12px 16px;\n background: var(--mj-bg-surface-sunken);\n}\n\n.user-menu-header[_ngcontent-%COMP%] .user-info[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.user-menu-header[_ngcontent-%COMP%] .user-name[_ngcontent-%COMP%] {\n font-weight: 600;\n font-size: 14px;\n color: var(--mj-text-primary);\n}\n\n.user-menu-header[_ngcontent-%COMP%] .user-email[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.user-menu-header[_ngcontent-%COMP%] .user-subtitle[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n font-style: italic;\n}\n\n\n\n.user-context-menu[_ngcontent-%COMP%] {\n position: absolute;\n top: 100%;\n right: 0;\n margin-top: 8px;\n background: var(--mj-bg-surface-elevated);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n box-shadow: var(--mj-shadow-lg);\n min-width: 180px;\n z-index: 10000;\n overflow: hidden;\n}\n\n.user-menu-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px;\n cursor: pointer;\n font-size: 14px;\n color: var(--mj-text-primary);\n transition: background 0.15s;\n}\n\n.user-menu-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n width: 18px;\n text-align: center;\n color: var(--mj-text-muted);\n font-size: 14px;\n}\n\n.user-menu-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.user-menu-item.danger[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.user-menu-item.danger[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.user-menu-item.danger[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface-elevated));\n}\n\n.user-menu-divider[_ngcontent-%COMP%] {\n height: 1px;\n background: var(--mj-border-default);\n margin: 4px 0;\n}\n\n\n\n.user-menu-item.disabled[_ngcontent-%COMP%] {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.user-menu-item.disabled[_ngcontent-%COMP%]:hover {\n background: transparent;\n}\n\n\n\n.theme-toggle-item[_ngcontent-%COMP%] {\n cursor: pointer;\n}\n\n.theme-toggle-track[_ngcontent-%COMP%] {\n position: relative;\n width: 40px;\n height: 22px;\n border-radius: 11px;\n background: var(--mj-bg-surface-active);\n margin-left: auto;\n transition: background 0.2s ease;\n flex-shrink: 0;\n}\n\n.theme-toggle-track.dark[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n}\n\n.theme-toggle-thumb[_ngcontent-%COMP%] {\n position: absolute;\n top: 2px;\n left: 2px;\n width: 18px;\n height: 18px;\n border-radius: 50%;\n background: var(--mj-bg-surface);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: transform 0.2s ease;\n}\n\n.theme-toggle-track.dark[_ngcontent-%COMP%] .theme-toggle-thumb[_ngcontent-%COMP%] {\n transform: translateX(18px);\n}\n\n.theme-toggle-icon[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--mj-text-muted);\n}\n\n.theme-toggle-track.dark[_ngcontent-%COMP%] .theme-toggle-icon[_ngcontent-%COMP%] {\n color: var(--mj-text-inverse);\n}\n\n\n\n.user-menu-item[_ngcontent-%COMP%] .menu-shortcut[_ngcontent-%COMP%] {\n margin-left: auto;\n font-size: 11px;\n color: var(--mj-text-disabled);\n font-family: monospace;\n}\n\n\n\n.user-context-menu.menu-fade[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_menuFadeIn 0.15s ease-out;\n}\n\n.user-context-menu.menu-slide[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_menuSlideIn 0.2s ease-out;\n}\n\n@keyframes _ngcontent-%COMP%_menuFadeIn {\n from {\n opacity: 0;\n transform: translateY(-8px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n@keyframes _ngcontent-%COMP%_menuSlideIn {\n from {\n opacity: 0;\n transform: translateY(-16px) scale(0.95);\n }\n to {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n}\n\n.shell-loading[_ngcontent-%COMP%] {\n 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: absolute;\n top: 60px; \n\n right: 16px;\n width: 480px;\n max-width: calc(100vw - 32px);\n background: var(--mj-bg-surface-elevated);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-xl);\n z-index: 10000;\n opacity: 0;\n transform: translateY(-10px);\n pointer-events: none;\n transition: opacity 0.2s ease, transform 0.2s ease;\n}\n\n.search-popup.open[_ngcontent-%COMP%] {\n opacity: 1;\n transform: translateY(0);\n pointer-events: all;\n}\n\n.search-popup-content[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px;\n}\n\n.search-entity-dropdown[_ngcontent-%COMP%] {\n min-width: 140px;\n max-width: 180px;\n flex-shrink: 0;\n}\n\n.search-input[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n height: 40px;\n padding: 8px 12px;\n font-size: 14px;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n outline: none;\n display: block !important;\n box-sizing: border-box;\n}\n\n.search-input[_ngcontent-%COMP%]:focus {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.search-submit-btn[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n border-radius: 8px;\n border: none;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 16px;\n transition: background 0.15s;\n flex-shrink: 0;\n}\n\n.search-submit-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary-hover);\n}\n\n.search-submit-btn[_ngcontent-%COMP%]:active {\n background: var(--mj-brand-primary-hover);\n}\n\n\n\n.notification-badge-mobile[_ngcontent-%COMP%] {\n position: absolute;\n top: 8px;\n right: 8px;\n min-width: 18px;\n height: 18px;\n padding: 0 5px;\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n font-size: 11px;\n font-weight: 600;\n border-radius: 9px;\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n}\n\n\n\n@media (max-width: 768px) {\n .search-popup[_ngcontent-%COMP%] {\n top: 60px;\n left: 16px;\n right: 16px;\n width: auto;\n max-width: none;\n }\n\n .search-popup-content[_ngcontent-%COMP%] {\n flex-wrap: wrap;\n }\n\n .search-entity-dropdown[_ngcontent-%COMP%] {\n width: 100%;\n }\n\n .search-input[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n }\n}\n\n\n\n\n\n.pin-progress-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: color-mix(in srgb, var(--mj-text-primary) 40%, transparent);\n z-index: 100000;\n display: flex;\n align-items: center;\n justify-content: center;\n animation: _ngcontent-%COMP%_pinBackdropIn 0.2s ease;\n}\n\n@keyframes _ngcontent-%COMP%_pinBackdropIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n.pin-progress-modal[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border-radius: var(--mj-radius-xl);\n padding: 28px 40px;\n display: flex;\n align-items: center;\n gap: 16px;\n box-shadow: 0 16px 48px color-mix(in srgb, var(--mj-text-primary) 30%, transparent);\n animation: _ngcontent-%COMP%_pinModalIn 0.25s ease;\n}\n\n@keyframes _ngcontent-%COMP%_pinModalIn {\n from { opacity: 0; transform: scale(0.9) translateY(8px); }\n to { opacity: 1; transform: scale(1) translateY(0); }\n}\n\n.pin-progress-text[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-medium);\n color: var(--mj-text-secondary);\n white-space: nowrap;\n}"] });
|
|
2997
|
+
} }, dependencies: [i12.NgControlStatus, i12.NgModel, i13.MJDropdownComponent, i14.LoadingComponent, i15.SearchCompositeComponent, i16.AppSwitcherComponent, i17.AppNavComponent, i18.TabContainerComponent, i19.AppAccessDialogComponent, i20.CommandPaletteComponent], styles: ["[_nghost-%COMP%] {\n display: block;\n height: 100%;\n width: 100%;\n overflow: hidden;\n}\n\n\n\n.mj-logo[_ngcontent-%COMP%] {\n width: 32px;\n height: 18px;\n background-image: var(--mj-logo-mark);\n background-repeat: no-repeat;\n background-position: center;\n background-size: contain;\n flex-shrink: 0;\n}\n\n.shell-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n overflow: hidden;\n position: relative;\n}\n\n\n\n\n.shell-container.hidden[_ngcontent-%COMP%] {\n visibility: hidden;\n position: absolute;\n pointer-events: none;\n}\n\nmj-tab-container[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n transition: all 0.2s ease-in-out;\n}\n\n\n\nmj-tab-container.hide-tab-bar[_ngcontent-%COMP%] .lm_header {\n display: none;\n}\n\n\n\nmj-tab-container[_ngcontent-%COMP%]:not(.hide-tab-bar) .lm_header {\n opacity: 1;\n max-height: 40px;\n transition: opacity 0.2s ease-in-out, max-height 0.2s ease-in-out;\n}\n\n\n\nmj-tab-container.hide-tab-bar[_ngcontent-%COMP%] .lm_content {\n height: 100% !important;\n}\n\n\n\nmj-tab-container[_ngcontent-%COMP%] .lm_stack {\n transition: all 0.2s ease-in-out;\n}\n\n.shell-header[_ngcontent-%COMP%] {\n height: 60px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n display: flex;\n align-items: center;\n padding: 0 16px;\n gap: 16px;\n box-shadow: var(--mj-shadow-sm);\n flex-shrink: 0;\n \n\n\n position: relative;\n z-index: 500;\n}\n\n\n\n.nav-bar-apps[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.nav-bar-apps.left-of-switcher[_ngcontent-%COMP%] {\n \n\n \n\n}\n\n.nav-bar-apps.left-of-user-menu[_ngcontent-%COMP%] {\n margin-right: 8px;\n}\n\n.nav-bar-app-btn[_ngcontent-%COMP%] {\n --app-color: var(--mj-text-muted);\n width: 40px;\n height: 40px;\n border-radius: 10px;\n border: none;\n background: transparent;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-secondary);\n font-size: 18px;\n transition: all 0.15s ease;\n position: relative;\n}\n\n.nav-bar-app-btn[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--app-color) 15%, transparent);\n color: var(--app-color);\n}\n\n.nav-bar-app-btn.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--app-color) 20%, transparent);\n color: var(--app-color);\n}\n\n.nav-bar-app-btn.active[_ngcontent-%COMP%]::after {\n content: '';\n position: absolute;\n bottom: 6px;\n left: 50%;\n transform: translateX(-50%);\n width: 16px;\n height: 3px;\n background: var(--app-color);\n border-radius: 2px;\n}\n\n.nav-bar-app-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n transition: transform 0.15s ease;\n margin-top: 2px; \n\n}\n\n.nav-bar-app-btn[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n transform: scale(1.1);\n}\n\n.spacer[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.header-actions[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.icon-btn[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n border-radius: 50%;\n border: none;\n background: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 18px;\n transition: background 0.15s;\n}\n\n.icon-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n\n\n.notification-btn[_ngcontent-%COMP%] {\n position: relative;\n}\n\n.notification-badge[_ngcontent-%COMP%] {\n position: absolute;\n top: 4px;\n right: 4px;\n min-width: 16px;\n height: 16px;\n padding: 0 4px;\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n font-size: 10px;\n font-weight: 600;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n}\n\n.user-menu[_ngcontent-%COMP%] {\n position: relative;\n}\n\n.user-menu[_ngcontent-%COMP%] .avatar-btn[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n border-radius: 50%;\n border: none;\n background: transparent;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: box-shadow 0.15s, transform 0.15s;\n padding: 0;\n overflow: hidden;\n}\n\n.user-menu[_ngcontent-%COMP%] .avatar-btn[_ngcontent-%COMP%]:hover {\n transform: scale(1.05);\n}\n\n\n\n.user-menu[_ngcontent-%COMP%] .avatar-btn[_ngcontent-%COMP%] .icon-fallback[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n border-radius: 50%;\n border: 2px solid var(--mj-border-default);\n background: var(--mj-bg-surface-hover);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: border-color 0.15s;\n}\n\n.user-menu[_ngcontent-%COMP%] .avatar-btn[_ngcontent-%COMP%]:hover .icon-fallback[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n}\n\n.user-menu[_ngcontent-%COMP%] .avatar-btn[_ngcontent-%COMP%] .icon-fallback[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 16px;\n}\n\n\n\n.user-menu[_ngcontent-%COMP%] .avatar-btn[_ngcontent-%COMP%] .avatar-img[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n border-radius: 50%;\n object-fit: cover;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);\n}\n\n.user-menu[_ngcontent-%COMP%] .avatar-btn[_ngcontent-%COMP%]:hover .avatar-img[_ngcontent-%COMP%] {\n box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);\n}\n\n\n\n.user-menu-header[_ngcontent-%COMP%] {\n padding: 12px 16px;\n background: var(--mj-bg-surface-sunken);\n}\n\n.user-menu-header[_ngcontent-%COMP%] .user-info[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.user-menu-header[_ngcontent-%COMP%] .user-name[_ngcontent-%COMP%] {\n font-weight: 600;\n font-size: 14px;\n color: var(--mj-text-primary);\n}\n\n.user-menu-header[_ngcontent-%COMP%] .user-email[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.user-menu-header[_ngcontent-%COMP%] .user-subtitle[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n font-style: italic;\n}\n\n\n\n.user-context-menu[_ngcontent-%COMP%] {\n position: absolute;\n top: 100%;\n right: 0;\n margin-top: 8px;\n background: var(--mj-bg-surface-elevated);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n box-shadow: var(--mj-shadow-lg);\n min-width: 180px;\n z-index: 10000;\n overflow: hidden;\n}\n\n.user-menu-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px;\n cursor: pointer;\n font-size: 14px;\n color: var(--mj-text-primary);\n transition: background 0.15s;\n}\n\n.user-menu-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n width: 18px;\n text-align: center;\n color: var(--mj-text-muted);\n font-size: 14px;\n}\n\n.user-menu-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.user-menu-item.danger[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.user-menu-item.danger[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.user-menu-item.danger[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface-elevated));\n}\n\n.user-menu-divider[_ngcontent-%COMP%] {\n height: 1px;\n background: var(--mj-border-default);\n margin: 4px 0;\n}\n\n\n\n.user-menu-item.disabled[_ngcontent-%COMP%] {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.user-menu-item.disabled[_ngcontent-%COMP%]:hover {\n background: transparent;\n}\n\n\n\n.theme-toggle-item[_ngcontent-%COMP%] {\n cursor: pointer;\n}\n\n.theme-toggle-track[_ngcontent-%COMP%] {\n position: relative;\n width: 40px;\n height: 22px;\n border-radius: 11px;\n background: var(--mj-bg-surface-active);\n margin-left: auto;\n transition: background 0.2s ease;\n flex-shrink: 0;\n}\n\n.theme-toggle-track.dark[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n}\n\n.theme-toggle-thumb[_ngcontent-%COMP%] {\n position: absolute;\n top: 2px;\n left: 2px;\n width: 18px;\n height: 18px;\n border-radius: 50%;\n background: var(--mj-bg-surface);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: transform 0.2s ease;\n}\n\n.theme-toggle-track.dark[_ngcontent-%COMP%] .theme-toggle-thumb[_ngcontent-%COMP%] {\n transform: translateX(18px);\n}\n\n.theme-toggle-icon[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--mj-text-muted);\n}\n\n.theme-toggle-track.dark[_ngcontent-%COMP%] .theme-toggle-icon[_ngcontent-%COMP%] {\n color: var(--mj-text-inverse);\n}\n\n\n\n.user-menu-item[_ngcontent-%COMP%] .menu-shortcut[_ngcontent-%COMP%] {\n margin-left: auto;\n font-size: 11px;\n color: var(--mj-text-disabled);\n font-family: monospace;\n}\n\n\n\n.user-context-menu.menu-fade[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_menuFadeIn 0.15s ease-out;\n}\n\n.user-context-menu.menu-slide[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_menuSlideIn 0.2s ease-out;\n}\n\n@keyframes _ngcontent-%COMP%_menuFadeIn {\n from {\n opacity: 0;\n transform: translateY(-8px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n@keyframes _ngcontent-%COMP%_menuSlideIn {\n from {\n opacity: 0;\n transform: translateY(-16px) scale(0.95);\n }\n to {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n}\n\n.shell-loading[_ngcontent-%COMP%] {\n 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: absolute;\n top: 60px; \n\n right: 16px;\n width: 480px;\n max-width: calc(100vw - 32px);\n background: var(--mj-bg-surface-elevated);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-xl);\n z-index: 10000;\n opacity: 0;\n transform: translateY(-10px);\n pointer-events: none;\n transition: opacity 0.2s ease, transform 0.2s ease;\n}\n\n.search-popup.open[_ngcontent-%COMP%] {\n opacity: 1;\n transform: translateY(0);\n pointer-events: all;\n}\n\n.search-popup-content[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px;\n}\n\n.search-entity-dropdown[_ngcontent-%COMP%] {\n min-width: 140px;\n max-width: 180px;\n flex-shrink: 0;\n}\n\n.search-input[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n height: 40px;\n padding: 8px 12px;\n font-size: 14px;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n outline: none;\n display: block !important;\n box-sizing: border-box;\n}\n\n.search-input[_ngcontent-%COMP%]:focus {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.search-submit-btn[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n border-radius: 8px;\n border: none;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 16px;\n transition: background 0.15s;\n flex-shrink: 0;\n}\n\n.search-submit-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary-hover);\n}\n\n.search-submit-btn[_ngcontent-%COMP%]:active {\n background: var(--mj-brand-primary-hover);\n}\n\n\n\n.notification-badge-mobile[_ngcontent-%COMP%] {\n position: absolute;\n top: 8px;\n right: 8px;\n min-width: 18px;\n height: 18px;\n padding: 0 5px;\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n font-size: 11px;\n font-weight: 600;\n border-radius: 9px;\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n}\n\n\n\n@media (max-width: 768px) {\n .search-popup[_ngcontent-%COMP%] {\n top: 60px;\n left: 16px;\n right: 16px;\n width: auto;\n max-width: none;\n }\n\n .search-popup-content[_ngcontent-%COMP%] {\n flex-wrap: wrap;\n }\n\n .search-entity-dropdown[_ngcontent-%COMP%] {\n width: 100%;\n }\n\n .search-input[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n }\n}\n\n\n\n\n\n.pin-progress-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: color-mix(in srgb, var(--mj-text-primary) 40%, transparent);\n z-index: 100000;\n display: flex;\n align-items: center;\n justify-content: center;\n animation: _ngcontent-%COMP%_pinBackdropIn 0.2s ease;\n}\n\n@keyframes _ngcontent-%COMP%_pinBackdropIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n.pin-progress-modal[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border-radius: var(--mj-radius-xl);\n padding: 28px 40px;\n display: flex;\n align-items: center;\n gap: 16px;\n box-shadow: 0 16px 48px color-mix(in srgb, var(--mj-text-primary) 30%, transparent);\n animation: _ngcontent-%COMP%_pinModalIn 0.25s ease;\n}\n\n@keyframes _ngcontent-%COMP%_pinModalIn {\n from { opacity: 0; transform: scale(0.9) translateY(8px); }\n to { opacity: 1; transform: scale(1) translateY(0); }\n}\n\n.pin-progress-text[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-medium);\n color: var(--mj-text-secondary);\n white-space: nowrap;\n}"] });
|
|
2982
2998
|
}
|
|
2983
2999
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ShellComponent, [{
|
|
2984
3000
|
type: Component,
|
|
2985
3001
|
args: [{ standalone: false, selector: 'mj-shell', template: "<div class=\"shell-container\" [class.hidden]=\"loading\" [class.tabs-visible]=\"tabBarVisible\">\n <!-- Header -->\n <header class=\"shell-header\">\n <!-- MJ Logo -->\n <div class=\"mj-logo\" title=\"MemberJunction\"></div>\n\n <!-- Mobile Hamburger Button -->\n <button class=\"hamburger-btn\" (click)=\"toggleMobileNav()\" title=\"Menu\">\n <i class=\"fa-solid fa-bars\"></i>\n </button>\n\n <!-- Nav Bar Apps: Left of App Switcher -->\n @if (leftOfSwitcherApps.length > 0) {\n <div class=\"nav-bar-apps left-of-switcher\">\n @for (app of leftOfSwitcherApps; track app) {\n <button\n class=\"nav-bar-app-btn\"\n [class.active]=\"IsActiveApp(app)\"\n [title]=\"app.Name\"\n [style.--app-color]=\"app.GetColor()\"\n (click)=\"onNavBarAppClick(app, $event)\"\n (dblclick)=\"onNavBarAppDblClick(app, $event)\">\n <i [class]=\"app.Icon\"></i>\n </button>\n }\n </div>\n }\n\n <!-- App Switcher -->\n <mj-app-switcher\n [activeApp]=\"activeApp\"\n [isViewingSystemTab]=\"isViewingSystemTab\"\n [loadingAppId]=\"loadingAppId\"\n (appSelected)=\"onAppSwitch($event)\">\n </mj-app-switcher>\n\n <!-- App Navigation (desktop only) -->\n @if (activeApp) {\n <mj-app-nav\n class=\"desktop-nav\"\n [app]=\"activeApp\"\n (navItemClick)=\"onNavItemClick($event)\"\n (navItemDismiss)=\"onNavItemDismiss($event)\">\n </mj-app-nav>\n }\n\n <!-- Universal Search Bar -->\n @if (ShowSearchBar) {\n <div class=\"shell-search-bar desktop-only\">\n <mj-search-composite\n #shellSearchComposite\n Placeholder=\"Search everything...\"\n [ShowShortcutHint]=\"true\"\n [EnablePreview]=\"ShowSearchPreview\"\n [EnableRecent]=\"true\"\n [MaxPreviewResults]=\"8\"\n (ResultSelected)=\"OnSearchResultSelected($event)\"\n (SearchSubmitted)=\"OnSearchSubmitted($event)\"\n (SeeAllRequested)=\"OnSeeAllSearch($event)\">\n </mj-search-composite>\n </div>\n }\n <!-- Spacer -->\n <div class=\"spacer\"></div>\n <!-- Actions (notifications, user menu) -->\n <div class=\"header-actions\">\n <button class=\"icon-btn desktop-only notification-btn\" title=\"Notifications\" (click)=\"showNotifications()\">\n <i class=\"fa-solid fa-bell\"></i>\n @if (unreadNotificationCount > 0) {\n <span class=\"notification-badge\">\n {{ unreadNotificationCount > 99 ? '99+' : unreadNotificationCount }}\n </span>\n }\n </button>\n <!-- Nav Bar Apps: Left of User Menu -->\n @if (leftOfUserMenuApps.length > 0) {\n <div class=\"nav-bar-apps left-of-user-menu\">\n @for (app of leftOfUserMenuApps; track app) {\n <button\n class=\"nav-bar-app-btn\"\n [class.active]=\"IsActiveApp(app)\"\n [title]=\"app.Name\"\n [style.--app-color]=\"app.GetColor()\"\n (click)=\"onNavBarAppClick(app, $event)\"\n (dblclick)=\"onNavBarAppDblClick(app, $event)\">\n <i [class]=\"app.Icon\"></i>\n </button>\n }\n </div>\n }\n\n <div class=\"user-menu\">\n <button class=\"avatar-btn\" (click)=\"toggleUserMenu($event)\">\n @if (userImageURL) {\n <img [src]=\"userImageURL\" alt=\"User avatar\" class=\"avatar-img\" />\n } @else {\n <div class=\"icon-fallback\">\n <i [class]=\"userIconClass || 'fa-solid fa-user'\"></i>\n </div>\n }\n </button>\n <!-- User Context Menu (Dynamic) -->\n @if (userMenuVisible) {\n <div class=\"user-context-menu\"\n [class.menu-fade]=\"getUserMenuOptions()?.animationStyle === 'fade'\"\n [class.menu-slide]=\"getUserMenuOptions()?.animationStyle === 'slide'\">\n <!-- User Header -->\n @if (getUserMenuOptions()?.showUserName) {\n <div class=\"user-menu-header\">\n <div class=\"user-info\">\n <span class=\"user-name\">{{ getUserDisplayInfo()?.name || userName }}</span>\n @if (getUserMenuOptions()?.showUserEmail && getUserDisplayInfo()?.email) {\n <span class=\"user-email\">\n {{ getUserDisplayInfo()?.email }}\n </span>\n }\n @if (getUserDisplayInfo()?.subtitle) {\n <span class=\"user-subtitle\">{{ getUserDisplayInfo()?.subtitle }}</span>\n }\n </div>\n </div>\n <div class=\"user-menu-divider\"></div>\n }\n <!-- Dynamic Menu Items -->\n @for (element of userMenuElements; track element) {\n <!-- Divider -->\n @if (isMenuDivider(element)) {\n <div class=\"user-menu-divider\"></div>\n }\n <!-- Menu Item -->\n @if (!isMenuDivider(element)) {\n @if (asMenuItem(element); as item) {\n @if (item.id === 'toggle-theme') {\n <div class=\"user-menu-item theme-toggle-item\"\n [title]=\"item.tooltip || ''\"\n (click)=\"onUserMenuItemClick(item.id)\">\n <i [class]=\"item.icon\"></i>\n <span class=\"menu-label\">{{ item.label }}</span>\n <div class=\"theme-toggle-track\" [class.dark]=\"IsDarkMode\">\n <div class=\"theme-toggle-thumb\">\n <i [class]=\"IsDarkMode ? 'fa-solid fa-moon' : 'fa-solid fa-sun'\" class=\"theme-toggle-icon\"></i>\n </div>\n </div>\n </div>\n } @else {\n <div class=\"user-menu-item\"\n [class.disabled]=\"!item.enabled\"\n [class.danger]=\"item.cssClass === 'danger'\"\n [style.color]=\"item.color || null\"\n [title]=\"item.tooltip || ''\"\n (click)=\"item.enabled && onUserMenuItemClick(item.id)\">\n <i [class]=\"item.icon\"></i>\n <span class=\"menu-label\">{{ item.label }}</span>\n @if (item.shortcut) {\n <span class=\"menu-shortcut\">{{ item.shortcut }}</span>\n }\n </div>\n }\n }\n }\n }\n </div>\n }\n </div>\n </div>\n </header>\n\n <!-- Search Popup -->\n @if (isSearchOpen) {\n <div class=\"search-popup-overlay\" (click)=\"closeSearch()\"></div>\n }\n <div class=\"search-popup\" [class.open]=\"isSearchOpen\">\n <div class=\"search-popup-content\" (click)=\"$event.stopPropagation()\">\n <mj-dropdown\n [Data]=\"searchableEntities\"\n TextField=\"Name\"\n ValueField=\"ID\"\n class=\"search-entity-dropdown\"\n [(ngModel)]=\"selectedEntity\">\n </mj-dropdown>\n <input\n type=\"text\"\n #searchInput\n placeholder=\"Search...\"\n class=\"mj-input search-input\"\n (keydown.enter)=\"onSearch($event)\"\n />\n <button class=\"search-submit-btn\" (click)=\"onSearch($event)\" title=\"Search\">\n <i class=\"fa-solid fa-search\"></i>\n </button>\n </div>\n </div>\n\n <!-- Mobile Navigation Drawer -->\n @if (mobileNavOpen) {\n <div class=\"mobile-nav-overlay\" (click)=\"closeMobileNav()\"></div>\n }\n <div class=\"mobile-nav-drawer\" [class.open]=\"mobileNavOpen\">\n <div class=\"mobile-nav-header\">\n <span>Navigation</span>\n <button class=\"close-btn\" (click)=\"closeMobileNav()\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n @if (activeApp) {\n <div class=\"mobile-nav-content\">\n <div class=\"mobile-nav-section-title\">{{ activeApp.Name }}</div>\n <mj-app-nav\n [app]=\"activeApp\"\n (navItemClick)=\"onNavItemClick($event)\"\n (navItemDismiss)=\"onNavItemDismiss($event)\">\n </mj-app-nav>\n </div>\n }\n <div class=\"mobile-nav-footer\">\n <button class=\"mobile-nav-action\" title=\"Search\" (click)=\"toggleSearch(); closeMobileNav()\">\n <i class=\"fa-solid fa-search\"></i>\n <span>Search</span>\n </button>\n <button class=\"mobile-nav-action\" title=\"Notifications\" (click)=\"showNotifications(); closeMobileNav()\">\n <i class=\"fa-solid fa-bell\"></i>\n <span>Notifications</span>\n @if (unreadNotificationCount > 0) {\n <span class=\"notification-badge-mobile\">\n {{ unreadNotificationCount > 99 ? '99+' : unreadNotificationCount }}\n </span>\n }\n </button>\n </div>\n </div>\n\n <!-- Tab Container - with dynamic tab bar visibility -->\n <mj-tab-container\n [class.hide-tab-bar]=\"!tabBarVisible\"\n (firstResourceLoadComplete)=\"onFirstResourceLoadComplete()\"\n (layoutInitError)=\"handleLayoutError()\">\n </mj-tab-container>\n</div>\n\n<!-- Loading State -->\n@if (loading) {\n <div class=\"shell-loading\">\n <mj-loading\n [text]=\"currentLoadingText\"\n [textColor]=\"currentLoadingTextColor\"\n [logoColor]=\"currentLoadingColor\"\n [logoGradient]=\"currentLoadingGradient\"\n [animation]=\"currentLoadingAnimation\"\n size=\"large\">\n </mj-loading>\n @if (ShowResetOption) {\n <div class=\"loading-reset-panel\">\n <p class=\"loading-reset-message\">\n <i class=\"fa-regular fa-clock\"></i>\n Taking longer than expected\n </p>\n <p class=\"loading-reset-hint\">\n This can happen after updates or due to cached data issues.\n </p>\n <button class=\"loading-reset-btn\" (click)=\"ResetApplication()\">\n <i class=\"fa-solid fa-arrows-rotate\"></i>\n Reset\n </button>\n </div>\n }\n </div>\n}\n\n<!-- App Access Error Dialog -->\n<mj-app-access-dialog\n #appAccessDialog\n (result)=\"onAppAccessDialogResult($event)\">\n</mj-app-access-dialog>\n\n<!-- Command Palette -->\n<mj-command-palette (AppSelected)=\"onAppSwitch($event)\"></mj-command-palette>\n\n<!-- Pin Progress Overlay -->\n@if (PinProgressVisible) {\n <div class=\"pin-progress-backdrop\">\n <div class=\"pin-progress-modal\">\n <mj-loading [showText]=\"false\" size=\"small\"></mj-loading>\n <span class=\"pin-progress-text\">{{ PinProgressText }}</span>\n </div>\n </div>\n}\n", styles: [":host {\n display: block;\n height: 100%;\n width: 100%;\n overflow: hidden;\n}\n\n/* MJ Logo - uses design token for theme switching & white-labeling */\n.mj-logo {\n width: 32px;\n height: 18px;\n background-image: var(--mj-logo-mark);\n background-repeat: no-repeat;\n background-position: center;\n background-size: contain;\n flex-shrink: 0;\n}\n\n.shell-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n overflow: hidden;\n position: relative;\n}\n\n/* Hide shell container while loading - allows tab container to render and load\n first resource in background while shell loading indicator is visible */\n.shell-container.hidden {\n visibility: hidden;\n position: absolute;\n pointer-events: none;\n}\n\nmj-tab-container {\n flex: 1;\n min-height: 0;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n transition: all 0.2s ease-in-out;\n}\n\n/* Hide Golden Layout tab headers when only one tab */\nmj-tab-container.hide-tab-bar ::ng-deep .lm_header {\n display: none;\n}\n\n/* Show tab headers when multiple tabs */\nmj-tab-container:not(.hide-tab-bar) ::ng-deep .lm_header {\n opacity: 1;\n max-height: 40px;\n transition: opacity 0.2s ease-in-out, max-height 0.2s ease-in-out;\n}\n\n/* Adjust content area height when tabs hidden */\nmj-tab-container.hide-tab-bar ::ng-deep .lm_content {\n height: 100% !important;\n}\n\n/* Ensure smooth transitions */\nmj-tab-container ::ng-deep .lm_stack {\n transition: all 0.2s ease-in-out;\n}\n\n.shell-header {\n height: 60px;\n background: var(--mj-bg-surface);\n border-bottom: 1px solid var(--mj-border-default);\n display: flex;\n align-items: center;\n padding: 0 16px;\n gap: 16px;\n box-shadow: var(--mj-shadow-sm);\n flex-shrink: 0;\n /* Creates a stacking context so children (search bar z-index: 99999, dropdown)\n are contained within this level. Modal overlays (z-index: 1000+) sit above. */\n position: relative;\n z-index: 500;\n}\n\n/* Nav Bar Apps - permanent app icons in the header */\n.nav-bar-apps {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.nav-bar-apps.left-of-switcher {\n /* No extra margin - header gap handles spacing */\n /* This prevents the app switcher from shifting when icons are hidden */\n}\n\n.nav-bar-apps.left-of-user-menu {\n margin-right: 8px;\n}\n\n.nav-bar-app-btn {\n --app-color: var(--mj-text-muted);\n width: 40px;\n height: 40px;\n border-radius: 10px;\n border: none;\n background: transparent;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-secondary);\n font-size: 18px;\n transition: all 0.15s ease;\n position: relative;\n}\n\n.nav-bar-app-btn:hover {\n background: color-mix(in srgb, var(--app-color) 15%, transparent);\n color: var(--app-color);\n}\n\n.nav-bar-app-btn.active {\n background: color-mix(in srgb, var(--app-color) 20%, transparent);\n color: var(--app-color);\n}\n\n.nav-bar-app-btn.active::after {\n content: '';\n position: absolute;\n bottom: 6px;\n left: 50%;\n transform: translateX(-50%);\n width: 16px;\n height: 3px;\n background: var(--app-color);\n border-radius: 2px;\n}\n\n.nav-bar-app-btn i {\n transition: transform 0.15s ease;\n margin-top: 2px; /* Align with app switcher icon */\n}\n\n.nav-bar-app-btn:hover i {\n transform: scale(1.1);\n}\n\n.spacer {\n flex: 1;\n}\n\n.header-actions {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.icon-btn {\n width: 40px;\n height: 40px;\n border-radius: 50%;\n border: none;\n background: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 18px;\n transition: background 0.15s;\n}\n\n.icon-btn:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n/* Notification button with badge */\n.notification-btn {\n position: relative;\n}\n\n.notification-badge {\n position: absolute;\n top: 4px;\n right: 4px;\n min-width: 16px;\n height: 16px;\n padding: 0 4px;\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n font-size: 10px;\n font-weight: 600;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n}\n\n.user-menu {\n position: relative;\n}\n\n.user-menu .avatar-btn {\n width: 36px;\n height: 36px;\n border-radius: 50%;\n border: none;\n background: transparent;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: box-shadow 0.15s, transform 0.15s;\n padding: 0;\n overflow: hidden;\n}\n\n.user-menu .avatar-btn:hover {\n transform: scale(1.05);\n}\n\n/* Icon fallback styling - shows gray circle with icon */\n.user-menu .avatar-btn .icon-fallback {\n width: 100%;\n height: 100%;\n border-radius: 50%;\n border: 2px solid var(--mj-border-default);\n background: var(--mj-bg-surface-hover);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: border-color 0.15s;\n}\n\n.user-menu .avatar-btn:hover .icon-fallback {\n border-color: var(--mj-brand-primary);\n}\n\n.user-menu .avatar-btn .icon-fallback i {\n color: var(--mj-text-muted);\n font-size: 16px;\n}\n\n/* Avatar image - replaces the gray circle entirely */\n.user-menu .avatar-btn .avatar-img {\n width: 100%;\n height: 100%;\n border-radius: 50%;\n object-fit: cover;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);\n}\n\n.user-menu .avatar-btn:hover .avatar-img {\n box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);\n}\n\n/* User Menu Header */\n.user-menu-header {\n padding: 12px 16px;\n background: var(--mj-bg-surface-sunken);\n}\n\n.user-menu-header .user-info {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.user-menu-header .user-name {\n font-weight: 600;\n font-size: 14px;\n color: var(--mj-text-primary);\n}\n\n.user-menu-header .user-email {\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.user-menu-header .user-subtitle {\n font-size: 11px;\n color: var(--mj-text-muted);\n font-style: italic;\n}\n\n/* User Context Menu */\n.user-context-menu {\n position: absolute;\n top: 100%;\n right: 0;\n margin-top: 8px;\n background: var(--mj-bg-surface-elevated);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n box-shadow: var(--mj-shadow-lg);\n min-width: 180px;\n z-index: 10000;\n overflow: hidden;\n}\n\n.user-menu-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px;\n cursor: pointer;\n font-size: 14px;\n color: var(--mj-text-primary);\n transition: background 0.15s;\n}\n\n.user-menu-item i {\n width: 18px;\n text-align: center;\n color: var(--mj-text-muted);\n font-size: 14px;\n}\n\n.user-menu-item:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.user-menu-item.danger {\n color: var(--mj-status-error);\n}\n\n.user-menu-item.danger i {\n color: var(--mj-status-error);\n}\n\n.user-menu-item.danger:hover {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface-elevated));\n}\n\n.user-menu-divider {\n height: 1px;\n background: var(--mj-border-default);\n margin: 4px 0;\n}\n\n/* Menu item disabled state */\n.user-menu-item.disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.user-menu-item.disabled:hover {\n background: transparent;\n}\n\n/* Theme Toggle Switch */\n.theme-toggle-item {\n cursor: pointer;\n}\n\n.theme-toggle-track {\n position: relative;\n width: 40px;\n height: 22px;\n border-radius: 11px;\n background: var(--mj-bg-surface-active);\n margin-left: auto;\n transition: background 0.2s ease;\n flex-shrink: 0;\n}\n\n.theme-toggle-track.dark {\n background: var(--mj-brand-primary);\n}\n\n.theme-toggle-thumb {\n position: absolute;\n top: 2px;\n left: 2px;\n width: 18px;\n height: 18px;\n border-radius: 50%;\n background: var(--mj-bg-surface);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: transform 0.2s ease;\n}\n\n.theme-toggle-track.dark .theme-toggle-thumb {\n transform: translateX(18px);\n}\n\n.theme-toggle-icon {\n font-size: 10px;\n color: var(--mj-text-muted);\n}\n\n.theme-toggle-track.dark .theme-toggle-icon {\n color: var(--mj-text-inverse);\n}\n\n/* Menu shortcut hint */\n.user-menu-item .menu-shortcut {\n margin-left: auto;\n font-size: 11px;\n color: var(--mj-text-disabled);\n font-family: monospace;\n}\n\n/* Menu animations */\n.user-context-menu.menu-fade {\n animation: menuFadeIn 0.15s ease-out;\n}\n\n.user-context-menu.menu-slide {\n animation: menuSlideIn 0.2s ease-out;\n}\n\n@keyframes menuFadeIn {\n from {\n opacity: 0;\n transform: translateY(-8px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n@keyframes menuSlideIn {\n from {\n opacity: 0;\n transform: translateY(-16px) scale(0.95);\n }\n to {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n}\n\n.shell-loading {\n 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: absolute;\n top: 60px; /* Below header */\n right: 16px;\n width: 480px;\n max-width: calc(100vw - 32px);\n background: var(--mj-bg-surface-elevated);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-xl);\n z-index: 10000;\n opacity: 0;\n transform: translateY(-10px);\n pointer-events: none;\n transition: opacity 0.2s ease, transform 0.2s ease;\n}\n\n.search-popup.open {\n opacity: 1;\n transform: translateY(0);\n pointer-events: all;\n}\n\n.search-popup-content {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px;\n}\n\n.search-entity-dropdown {\n min-width: 140px;\n max-width: 180px;\n flex-shrink: 0;\n}\n\n.search-input {\n flex: 1;\n min-width: 0;\n height: 40px;\n padding: 8px 12px;\n font-size: 14px;\n border: 1px solid var(--mj-border-default);\n border-radius: 4px;\n outline: none;\n display: block !important;\n box-sizing: border-box;\n}\n\n.search-input:focus {\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.search-submit-btn {\n width: 40px;\n height: 40px;\n border-radius: 8px;\n border: none;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 16px;\n transition: background 0.15s;\n flex-shrink: 0;\n}\n\n.search-submit-btn:hover {\n background: var(--mj-brand-primary-hover);\n}\n\n.search-submit-btn:active {\n background: var(--mj-brand-primary-hover);\n}\n\n/* Mobile notification badge */\n.notification-badge-mobile {\n position: absolute;\n top: 8px;\n right: 8px;\n min-width: 18px;\n height: 18px;\n padding: 0 5px;\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n font-size: 11px;\n font-weight: 600;\n border-radius: 9px;\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\n}\n\n/* Mobile-specific search popup adjustments */\n@media (max-width: 768px) {\n .search-popup {\n top: 60px;\n left: 16px;\n right: 16px;\n width: auto;\n max-width: none;\n }\n\n .search-popup-content {\n flex-wrap: wrap;\n }\n\n .search-entity-dropdown {\n width: 100%;\n }\n\n .search-input {\n flex: 1;\n min-width: 0;\n }\n}\n\n/* ========================================\n PIN PROGRESS OVERLAY\n ======================================== */\n.pin-progress-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: color-mix(in srgb, var(--mj-text-primary) 40%, transparent);\n z-index: 100000;\n display: flex;\n align-items: center;\n justify-content: center;\n animation: pinBackdropIn 0.2s ease;\n}\n\n@keyframes pinBackdropIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n.pin-progress-modal {\n background: var(--mj-bg-surface);\n border-radius: var(--mj-radius-xl);\n padding: 28px 40px;\n display: flex;\n align-items: center;\n gap: 16px;\n box-shadow: 0 16px 48px color-mix(in srgb, var(--mj-text-primary) 30%, transparent);\n animation: pinModalIn 0.25s ease;\n}\n\n@keyframes pinModalIn {\n from { opacity: 0; transform: scale(0.9) translateY(8px); }\n to { opacity: 1; transform: scale(1) translateY(0); }\n}\n\n.pin-progress-text {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-medium);\n color: var(--mj-text-secondary);\n white-space: nowrap;\n}"] }]
|
|
2986
|
-
}], () => [{ 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: i7.UserSharingCenterDialogService }, { type: i0.ViewContainerRef }, { type: i2.TitleService }, { type: i2.DeveloperModeService }, { type: i8.CommandPaletteService }, { type: i2.ThemeService }, { type: i2.HomeAppPinService }, { type:
|
|
3002
|
+
}], () => [{ 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: i7.UserSharingCenterDialogService }, { type: i0.ViewContainerRef }, { type: i2.TitleService }, { type: i2.DeveloperModeService }, { type: i8.StartupValidationService }, { type: i9.CommandPaletteService }, { type: i2.ThemeService }, { type: i2.HomeAppPinService }, { type: i10.FileOpenService }, { type: i11.FeedbackDialogService }, { type: i11.FeedbackService }], { searchInput: [{
|
|
2987
3003
|
type: ViewChild,
|
|
2988
3004
|
args: ['searchInput']
|
|
2989
3005
|
}], shellSearchComposite: [{
|
|
@@ -3002,5 +3018,5 @@ export class ShellComponent {
|
|
|
3002
3018
|
type: HostListener,
|
|
3003
3019
|
args: ['document:keydown', ['$event']]
|
|
3004
3020
|
}] }); })();
|
|
3005
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ShellComponent, { className: "ShellComponent", filePath: "src/lib/shell/shell.component.ts", lineNumber:
|
|
3021
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ShellComponent, { className: "ShellComponent", filePath: "src/lib/shell/shell.component.ts", lineNumber: 51 }); })();
|
|
3006
3022
|
//# sourceMappingURL=shell.component.js.map
|