@rxap/layout 18.0.3-dev.0 → 18.1.0-dev.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/CHANGELOG.md +16 -0
- package/README.md +280 -1
- package/compodoc/changelog.html +13 -0
- package/compodoc/components/AppsButtonComponent.html +185 -153
- package/compodoc/components/BaseLayoutComponent.html +351 -0
- package/compodoc/components/DefaultHeaderComponent.html +545 -0
- package/compodoc/components/FooterComponent.html +58 -79
- package/compodoc/components/HeaderComponent.html +49 -294
- package/compodoc/components/LanguageSelectorComponent.html +6 -54
- package/compodoc/components/LayoutComponent.html +69 -464
- package/compodoc/components/MinimalLayoutComponent.html +349 -0
- package/compodoc/components/NavigationComponent.html +116 -312
- package/compodoc/components/NavigationItemComponent.html +130 -361
- package/compodoc/components/NavigationProgressBarComponent.html +41 -107
- package/compodoc/components/ReleaseInfoComponent.html +536 -0
- package/compodoc/components/SettingsButtonComponent.html +186 -225
- package/compodoc/components/SidenavComponent.html +566 -142
- package/compodoc/components/SidenavToggleButtonComponent.html +71 -91
- package/compodoc/components/SignOutComponent.html +7 -60
- package/compodoc/components/UserProfileIconComponent.html +97 -161
- package/compodoc/dependencies.html +11 -25
- package/compodoc/directives/FooterDirective-1.html +293 -0
- package/compodoc/directives/FooterDirective.html +8 -86
- package/compodoc/directives/HeaderDirective.html +293 -0
- package/compodoc/index.html +183 -1
- package/compodoc/injectables/ExternalAppsService.html +1274 -0
- package/compodoc/injectables/FooterService.html +573 -0
- package/compodoc/injectables/HeaderService.html +576 -0
- package/compodoc/injectables/LayoutService.html +899 -0
- package/compodoc/injectables/LogoService.html +411 -0
- package/compodoc/injectables/NavigationService.html +46 -57
- package/compodoc/interfaces/ReleaseInfoModule.html +385 -0
- package/compodoc/interfaces/SettingsMenuItem.html +385 -0
- package/compodoc/js/menu-wc.js +24 -40
- package/compodoc/js/menu-wc_es5.js +1 -1
- package/compodoc/js/search/search_index.js +2 -2
- package/compodoc/miscellaneous/functions.html +544 -1
- package/compodoc/miscellaneous/typealiases.html +40 -2
- package/compodoc/miscellaneous/variables.html +100 -9
- package/compodoc/overview.html +2 -10
- package/compodoc/properties.html +1 -1
- package/docs/assets/highlight.css +42 -0
- package/docs/assets/navigation.js +1 -1
- package/docs/assets/search.js +1 -1
- package/docs/classes/AppsButtonComponent.html +8 -8
- package/docs/classes/BaseLayoutComponent.html +2 -0
- package/docs/classes/DefaultHeaderComponent.html +7 -0
- package/docs/classes/ExternalAppsService.html +18 -0
- package/docs/classes/FooterComponent.html +5 -3
- package/docs/classes/FooterDirective.html +2 -2
- package/docs/classes/FooterService.html +14 -0
- package/docs/classes/HeaderComponent.html +6 -8
- package/docs/classes/HeaderDirective.html +8 -0
- package/docs/classes/HeaderService.html +14 -0
- package/docs/classes/LayoutComponent.html +4 -12
- package/docs/classes/LayoutService.html +20 -0
- package/docs/classes/LogoService.html +7 -0
- package/docs/classes/MinimalLayoutComponent.html +2 -0
- package/docs/classes/NavigationComponent.html +7 -8
- package/docs/classes/NavigationItemComponent.html +6 -9
- package/docs/classes/NavigationProgressBarComponent.html +3 -3
- package/docs/classes/NavigationService.html +3 -3
- package/docs/classes/ReleaseInfoComponent.html +6 -0
- package/docs/classes/SettingsButtonComponent.html +6 -11
- package/docs/classes/SidenavComponent.html +17 -5
- package/docs/classes/SidenavFooterDirective.html +2 -2
- package/docs/classes/SidenavHeaderDirective.html +2 -2
- package/docs/classes/SidenavToggleButtonComponent.html +4 -3
- package/docs/classes/UserProfileIconComponent.html +5 -4
- package/docs/documentation.json +8546 -8346
- package/docs/functions/IsNavigationDividerItem.html +1 -1
- package/docs/functions/IsNavigationInsertItem.html +1 -1
- package/docs/functions/IsNavigationItem.html +1 -1
- package/docs/functions/provideLayout.html +1 -0
- package/docs/functions/widthDefaultHeaderComponent.html +1 -0
- package/docs/functions/withFooterComponents.html +1 -0
- package/docs/functions/withHeaderComponents.html +1 -0
- package/docs/functions/withNavigationConfig.html +1 -0
- package/docs/functions/withNavigationInserts.html +1 -0
- package/docs/functions/withReleaseInfoModules.html +1 -0
- package/docs/functions/withSettingsMenuItems.html +1 -0
- package/docs/index.html +74 -2
- package/docs/interfaces/NavigationDividerItem.html +2 -2
- package/docs/interfaces/NavigationInsertItem.html +2 -2
- package/docs/interfaces/NavigationItem.html +2 -2
- package/docs/interfaces/NavigationStatus.html +2 -2
- package/docs/interfaces/ReleaseInfoModule.html +4 -0
- package/docs/interfaces/SettingsMenuItem.html +4 -0
- package/docs/modules.html +29 -17
- package/docs/types/ExternalApps.html +1 -0
- package/docs/types/ExtractUsernameFromProfileFn.html +1 -1
- package/docs/types/Navigation.html +1 -1
- package/docs/types/NavigationWithInserts.html +1 -1
- package/docs/types/SettingsMenuItemComponent.html +1 -0
- package/docs/variables/EXTRACT_USERNAME_FROM_PROFILE.html +1 -1
- package/docs/variables/RXAP_EXTERNAL_APP_FILTER.html +1 -0
- package/docs/variables/RXAP_FOOTER_COMPONENT.html +1 -1
- package/docs/variables/RXAP_HEADER_COMPONENT.html +1 -1
- package/docs/variables/RXAP_LAYOUT_APPS_GRID.html +1 -1
- package/docs/variables/RXAP_LOGO_CONFIG.html +1 -1
- package/docs/variables/RXAP_NAVIGATION_CONFIG.html +1 -1
- package/docs/variables/RXAP_NAVIGATION_CONFIG_INSERTS.html +1 -1
- package/docs/variables/RXAP_RELEASE_INFO_MODULE.html +1 -0
- package/docs/variables/RXAP_SETTINGS_MENU_ITEM.html +1 -0
- package/docs/variables/RXAP_SETTINGS_MENU_ITEM_COMPONENT.html +1 -0
- package/esm2022/index.mjs +35 -40
- package/esm2022/lib/base-layout/base-layout.component.mjs +16 -0
- package/esm2022/lib/default-header/apps-button/apps-button.component.mjs +38 -0
- package/esm2022/lib/default-header/default-header.component.mjs +32 -0
- package/esm2022/lib/default-header/settings-button/settings-button.component.mjs +73 -0
- package/esm2022/lib/default-header/sidenav-toggle-button/sidenav-toggle-button.component.mjs +24 -0
- package/esm2022/lib/default-header/user-profile-icon/user-profile-icon.component.mjs +35 -0
- package/esm2022/lib/external-apps.service.mjs +97 -0
- package/esm2022/lib/footer/footer.component.mjs +13 -13
- package/esm2022/lib/footer/footer.directive.mjs +30 -0
- package/esm2022/lib/footer.service.mjs +58 -0
- package/esm2022/lib/header/header.component.mjs +17 -65
- package/esm2022/lib/header/header.directive.mjs +30 -0
- package/esm2022/lib/header.service.mjs +60 -0
- package/esm2022/lib/layout/layout.component.mjs +33 -47
- package/esm2022/lib/layout.service.mjs +93 -0
- package/esm2022/lib/logo.service.mjs +23 -0
- package/esm2022/lib/minimal-layout/minimal-layout.component.mjs +14 -0
- package/esm2022/lib/navigation/navigation-item/navigation-item.component.mjs +30 -64
- package/esm2022/lib/navigation/navigation.component.mjs +22 -48
- package/esm2022/lib/navigation-progress-bar/navigation-progress-bar.component.mjs +23 -0
- package/esm2022/lib/navigation.service.mjs +141 -0
- package/esm2022/lib/provide.mjs +73 -0
- package/esm2022/lib/release-info/release-info.component.mjs +28 -0
- package/esm2022/lib/sidenav/sidenav.component.mjs +50 -33
- package/esm2022/lib/tokens.mjs +9 -1
- package/esm2022/lib/types.mjs +1 -1
- package/fesm2022/rxap-layout.mjs +845 -833
- package/fesm2022/rxap-layout.mjs.map +1 -1
- package/index.d.ts +18 -19
- package/lib/base-layout/base-layout.component.d.ts +5 -0
- package/lib/default-header/apps-button/apps-button.component.d.ts +15 -0
- package/lib/default-header/default-header.component.d.ts +11 -0
- package/lib/{header → default-header}/settings-button/settings-button.component.d.ts +6 -14
- package/lib/{header → default-header}/sidenav-toggle-button/sidenav-toggle-button.component.d.ts +3 -5
- package/lib/default-header/user-profile-icon/user-profile-icon.component.d.ts +10 -0
- package/lib/external-apps.service.d.ts +25 -0
- package/lib/footer/footer.component.d.ts +3 -3
- package/lib/{footer.directive.d.ts → footer/footer.directive.d.ts} +2 -4
- package/lib/footer.service.d.ts +32 -0
- package/lib/header/header.component.d.ts +6 -12
- package/lib/header/header.directive.d.ts +12 -0
- package/lib/header.service.d.ts +34 -0
- package/lib/layout/layout.component.d.ts +4 -17
- package/lib/layout.service.d.ts +26 -0
- package/lib/logo.service.d.ts +10 -0
- package/lib/minimal-layout/minimal-layout.component.d.ts +5 -0
- package/lib/navigation/navigation-item/navigation-item.component.d.ts +10 -18
- package/lib/navigation/navigation.component.d.ts +10 -15
- package/lib/{header/navigation-progress-bar → navigation-progress-bar}/navigation-progress-bar.component.d.ts +1 -3
- package/lib/{navigation/navigation.service.d.ts → navigation.service.d.ts} +4 -5
- package/lib/provide.d.ts +12 -0
- package/lib/release-info/release-info.component.d.ts +9 -0
- package/lib/sidenav/sidenav.component.d.ts +18 -6
- package/lib/tokens.d.ts +11 -3
- package/lib/types.d.ts +15 -4
- package/package.json +32 -66
- package/theme.css +1 -1
- package/docs/classes/AppUrlService.html +0 -13
- package/docs/classes/AuthenticationServiceMock.html +0 -3
- package/docs/classes/LanguageSelectorComponent.html +0 -3
- package/docs/classes/LayoutComponentService.html +0 -15
- package/docs/classes/ReplaceRouterPathsPipe.html +0 -4
- package/docs/classes/ReplaceRouterPathsService.html +0 -3
- package/docs/classes/ResetButtonComponent.html +0 -3
- package/docs/classes/SidenavComponentService.html +0 -5
- package/docs/classes/SignOutComponent.html +0 -4
- package/docs/classes/ToggleWindowSidenavButtonComponent.html +0 -5
- package/docs/classes/VersionComponent.html +0 -7
- package/docs/classes/WindowContainerSidenavComponent.html +0 -10
- package/docs/interfaces/ExternalApps.html +0 -8
- package/docs/interfaces/LogoConfig.html +0 -4
- package/esm2022/lib/app-url.service.mjs +0 -78
- package/esm2022/lib/authentication.service.mock.mjs +0 -13
- package/esm2022/lib/footer.directive.mjs +0 -40
- package/esm2022/lib/header/apps-button/apps-button.component.mjs +0 -46
- package/esm2022/lib/header/language-selector/language-selector.component.mjs +0 -35
- package/esm2022/lib/header/navigation-progress-bar/navigation-progress-bar.component.mjs +0 -30
- package/esm2022/lib/header/reset-button/reset-button.component.mjs +0 -23
- package/esm2022/lib/header/settings-button/settings-button.component.mjs +0 -87
- package/esm2022/lib/header/sidenav-toggle-button/sidenav-toggle-button.component.mjs +0 -26
- package/esm2022/lib/header/sign-out/sign-out.component.mjs +0 -23
- package/esm2022/lib/header/user-profile-icon/user-profile-icon.component.mjs +0 -45
- package/esm2022/lib/layout/layout.component.service.mjs +0 -77
- package/esm2022/lib/navigation/navigation.service.mjs +0 -145
- package/esm2022/lib/navigation/replace-router-paths.pipe.mjs +0 -22
- package/esm2022/lib/navigation/replace-router-paths.service.mjs +0 -15
- package/esm2022/lib/sidenav/sidenav.component.service.mjs +0 -22
- package/esm2022/lib/sidenav/version/version.component.mjs +0 -28
- package/esm2022/lib/toggle-window-sidenav-button/toggle-window-sidenav-button.component.mjs +0 -30
- package/esm2022/lib/window-container-sidenav/window-container-sidenav.component.mjs +0 -54
- package/lib/app-url.service.d.ts +0 -29
- package/lib/authentication.service.mock.d.ts +0 -6
- package/lib/header/apps-button/apps-button.component.d.ts +0 -16
- package/lib/header/language-selector/language-selector.component.d.ts +0 -8
- package/lib/header/reset-button/reset-button.component.d.ts +0 -8
- package/lib/header/sign-out/sign-out.component.d.ts +0 -9
- package/lib/header/user-profile-icon/user-profile-icon.component.d.ts +0 -15
- package/lib/layout/layout.component.service.d.ts +0 -25
- package/lib/navigation/replace-router-paths.pipe.d.ts +0 -11
- package/lib/navigation/replace-router-paths.service.d.ts +0 -7
- package/lib/sidenav/sidenav.component.service.d.ts +0 -11
- package/lib/sidenav/version/version.component.d.ts +0 -14
- package/lib/toggle-window-sidenav-button/toggle-window-sidenav-button.component.d.ts +0 -9
- package/lib/window-container-sidenav/window-container-sidenav.component.d.ts +0 -17
package/fesm2022/rxap-layout.mjs
CHANGED
|
@@ -1,151 +1,36 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
import * as
|
|
6
|
-
import {
|
|
7
|
-
import
|
|
8
|
-
import {
|
|
9
|
-
import
|
|
10
|
-
import {
|
|
11
|
-
import
|
|
12
|
-
import {
|
|
13
|
-
import * as i3 from '@angular/material/button';
|
|
14
|
-
import { MatButtonModule } from '@angular/material/button';
|
|
15
|
-
import * as i1$2 from '@rxap/config';
|
|
2
|
+
import { TemplateRef, Directive, Inject, InjectionToken, inject, signal, computed, isDevMode, Injectable, effect, INJECTOR, Optional, input, ElementRef, Renderer2, Component, ChangeDetectionStrategy, ViewEncapsulation, forwardRef, runInInjectionContext, viewChild, contentChild, ViewContainerRef, Injector, LOCALE_ID } from '@angular/core';
|
|
3
|
+
import { NgIf, NgClass, NgFor, AsyncPipe, NgStyle, NgTemplateOutlet, NgOptimizedImage } from '@angular/common';
|
|
4
|
+
import { MatIconButton, MatButton, MatButtonModule, MatAnchor } from '@angular/material/button';
|
|
5
|
+
import * as i3 from '@angular/material/divider';
|
|
6
|
+
import { MatDividerModule, MatDivider } from '@angular/material/divider';
|
|
7
|
+
import * as i2 from '@angular/material/icon';
|
|
8
|
+
import { MatIconModule, MatIcon } from '@angular/material/icon';
|
|
9
|
+
import { MatSidenav, MatSidenavContainer, MatSidenavContent, MatSidenavModule } from '@angular/material/sidenav';
|
|
10
|
+
import { Router, NavigationEnd, RouterLinkActive, RouterLink, RouterOutlet, NavigationStart, NavigationCancel } from '@angular/router';
|
|
11
|
+
import { MediaMatcher } from '@angular/cdk/layout';
|
|
12
|
+
import { toSignal } from '@angular/core/rxjs-interop';
|
|
16
13
|
import { ConfigService } from '@rxap/config';
|
|
17
|
-
import
|
|
18
|
-
import {
|
|
19
|
-
import
|
|
14
|
+
import { ObserveCurrentThemeDensity, ThemeService } from '@rxap/ngx-theme';
|
|
15
|
+
import { Observable, ReplaySubject, of, from, combineLatest, Subscription, debounceTime } from 'rxjs';
|
|
16
|
+
import * as i2$1 from '@angular/cdk/portal';
|
|
17
|
+
import { ComponentPortal, PortalModule, CdkPortalOutlet, TemplatePortal } from '@angular/cdk/portal';
|
|
18
|
+
import { coerceArray, JoinPath } from '@rxap/utilities';
|
|
19
|
+
import { switchMap, catchError, map, filter, startWith, tap } from 'rxjs/operators';
|
|
20
20
|
import { trigger, transition, style, animate } from '@angular/animations';
|
|
21
|
-
import * as
|
|
22
|
-
import {
|
|
23
|
-
import * as i6 from '@angular/cdk/overlay';
|
|
24
|
-
import { Overlay } from '@angular/cdk/overlay';
|
|
21
|
+
import * as i1 from '@angular/material/core';
|
|
22
|
+
import { MatRippleModule } from '@angular/material/core';
|
|
25
23
|
import { IconDirective } from '@rxap/material-directives/icon';
|
|
26
|
-
import
|
|
27
|
-
import {
|
|
28
|
-
import
|
|
29
|
-
import
|
|
30
|
-
import
|
|
31
|
-
import
|
|
32
|
-
import
|
|
33
|
-
import {
|
|
34
|
-
import
|
|
35
|
-
import { MatSidenav, MatSidenavModule } from '@angular/material/sidenav';
|
|
36
|
-
import { RXAP_ENVIRONMENT, DetermineReleaseName } from '@rxap/environment';
|
|
37
|
-
import * as i2$6 from '@rxap/icon';
|
|
38
|
-
import { StatusIndicatorComponent } from '@rxap/ngx-status-check';
|
|
39
|
-
import * as i1$7 from '@rxap/ngx-user';
|
|
40
|
-
import { UserSettingsThemeService, IsThemeDensity, ThemeDensity } from '@rxap/ngx-user';
|
|
41
|
-
import * as i2$2 from '@angular/material/toolbar';
|
|
42
|
-
import { MatToolbarModule } from '@angular/material/toolbar';
|
|
43
|
-
import * as i5 from '@angular/forms';
|
|
44
|
-
import { FormsModule } from '@angular/forms';
|
|
45
|
-
import * as i2$5 from '@angular/material/form-field';
|
|
46
|
-
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
47
|
-
import * as i3$2 from '@angular/material/select';
|
|
48
|
-
import { MatSelectModule } from '@angular/material/select';
|
|
49
|
-
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
|
50
|
-
import { DataSourceCollectionDirective } from '@rxap/data-source/directive';
|
|
51
|
-
import { StopPropagationDirective } from '@rxap/directives';
|
|
52
|
-
import * as i2$3 from '@rxap/authorization';
|
|
24
|
+
import { MatDialog } from '@angular/material/dialog';
|
|
25
|
+
import { DetermineReleaseName, RXAP_ENVIRONMENT, EnvironmentComponent } from '@rxap/environment';
|
|
26
|
+
import { MatProgressBar } from '@angular/material/progress-bar';
|
|
27
|
+
import * as i1$1 from '@angular/material/toolbar';
|
|
28
|
+
import { MatToolbarModule, MatToolbar, MatToolbarRow } from '@angular/material/toolbar';
|
|
29
|
+
import * as i1$2 from '@angular/material/menu';
|
|
30
|
+
import { MatMenuModule, MatMenu, MatMenuTrigger, MatMenuItem } from '@angular/material/menu';
|
|
31
|
+
import { UserSettingsThemeService, IsThemeDensity, ThemeDensity, UserProfileDataSource } from '@rxap/ngx-user';
|
|
32
|
+
import { PubSubService } from '@rxap/ngx-pub-sub';
|
|
53
33
|
import { ClickOnLink } from '@rxap/browser-utilities';
|
|
54
|
-
import * as i2$4 from '@rxap/authentication';
|
|
55
|
-
import * as i1$4 from '@angular/material/progress-bar';
|
|
56
|
-
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
|
57
|
-
import * as i3$3 from '@rxap/ngx-changelog';
|
|
58
|
-
import * as i1$5 from '@rxap/ngx-localize';
|
|
59
|
-
|
|
60
|
-
class WindowContainerSidenavComponent {
|
|
61
|
-
constructor(service) {
|
|
62
|
-
this.service = service;
|
|
63
|
-
this.portals = new Map();
|
|
64
|
-
this.subscription = new Subscription();
|
|
65
|
-
}
|
|
66
|
-
ngOnInit() {
|
|
67
|
-
const components = this.service.getAll();
|
|
68
|
-
for (const component of components) {
|
|
69
|
-
this.add(component);
|
|
70
|
-
}
|
|
71
|
-
this.subscription.add(this.service.add$.pipe(tap(component => this.add(component))).subscribe());
|
|
72
|
-
this.subscription.add(this.service.remove$.pipe(tap(component => this.remove(component))).subscribe());
|
|
73
|
-
}
|
|
74
|
-
ngOnDestroy() {
|
|
75
|
-
this.subscription.unsubscribe();
|
|
76
|
-
}
|
|
77
|
-
trackBy(index, id) {
|
|
78
|
-
return id;
|
|
79
|
-
}
|
|
80
|
-
add(component) {
|
|
81
|
-
if (this.portals.has(component.id)) {
|
|
82
|
-
throw new Error(`Component portal with id ${component.id} already exists`);
|
|
83
|
-
}
|
|
84
|
-
const portal = new ComponentPortal(component.component, component.viewContainerRef, component.injector, component.componentFactoryResolver);
|
|
85
|
-
this.portals.set(component.id, portal);
|
|
86
|
-
}
|
|
87
|
-
remove(component) {
|
|
88
|
-
if (this.portals.has(component.id)) {
|
|
89
|
-
const portal = this.portals.get(component.id);
|
|
90
|
-
this.portals.delete(component.id);
|
|
91
|
-
portal.detach();
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: WindowContainerSidenavComponent, deps: [{ token: WindowContainerSidenavService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
95
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.0.1", type: WindowContainerSidenavComponent, isStandalone: true, selector: "rxap-window-container-sidenav", ngImport: i0, template: "<div class=\"flex flex-col gap-4 p-2\">\n\n <div *ngFor=\"let portalId of portals.keys(); trackBy: trackBy\" class=\"grow-0\">\n <ng-template [cdkPortalOutlet]=\"portals.get(portalId)\"></ng-template>\n </div>\n\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "ngmodule", type: PortalModule }, { kind: "directive", type: i1.CdkPortalOutlet, selector: "[cdkPortalOutlet]", inputs: ["cdkPortalOutlet"], outputs: ["attached"], exportAs: ["cdkPortalOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
96
|
-
}
|
|
97
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: WindowContainerSidenavComponent, decorators: [{
|
|
98
|
-
type: Component,
|
|
99
|
-
args: [{ selector: 'rxap-window-container-sidenav', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [NgFor, PortalModule], template: "<div class=\"flex flex-col gap-4 p-2\">\n\n <div *ngFor=\"let portalId of portals.keys(); trackBy: trackBy\" class=\"grow-0\">\n <ng-template [cdkPortalOutlet]=\"portals.get(portalId)\"></ng-template>\n </div>\n\n</div>\n" }]
|
|
100
|
-
}], ctorParameters: () => [{ type: i1$1.WindowContainerSidenavService, decorators: [{
|
|
101
|
-
type: Inject,
|
|
102
|
-
args: [WindowContainerSidenavService]
|
|
103
|
-
}] }] });
|
|
104
|
-
|
|
105
|
-
class ToggleWindowSidenavButtonComponent {
|
|
106
|
-
constructor() {
|
|
107
|
-
this.openWindowSidenav = false;
|
|
108
|
-
this.openWindowSidenavChange = new EventEmitter();
|
|
109
|
-
}
|
|
110
|
-
toggle() {
|
|
111
|
-
this.openWindowSidenav = !this.openWindowSidenav;
|
|
112
|
-
this.openWindowSidenavChange.emit(this.openWindowSidenav);
|
|
113
|
-
}
|
|
114
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: ToggleWindowSidenavButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
115
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.0.1", type: ToggleWindowSidenavButtonComponent, isStandalone: true, selector: "rxap-toggle-window-sidenav-button", inputs: { openWindowSidenav: "openWindowSidenav" }, outputs: { openWindowSidenavChange: "openWindowSidenavChange" }, host: { classAttribute: "rxap-toggle-window-sidenav-button" }, ngImport: i0, template: "<div class=\"toggle-button\">\n <button (click)=\"toggle()\" mat-icon-button>\n <ng-template [ngIfElse]=\"hide\" [ngIf]=\"!openWindowSidenav\">\n <mat-icon svgIcon=\"arrow-left-bold\"></mat-icon>\n </ng-template>\n <ng-template #hide>\n <mat-icon svgIcon=\"arrow-right-bold\"></mat-icon>\n </ng-template>\n </button>\n</div>\n", styles: [".toggle-button{position:absolute;top:70px;right:0;z-index:10000;border-radius:15px 0 0 15px;border:1px solid black;background:#000}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
116
|
-
}
|
|
117
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: ToggleWindowSidenavButtonComponent, decorators: [{
|
|
118
|
-
type: Component,
|
|
119
|
-
args: [{ selector: 'rxap-toggle-window-sidenav-button', changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
120
|
-
class: 'rxap-toggle-window-sidenav-button',
|
|
121
|
-
}, standalone: true, imports: [MatButtonModule, NgIf, MatIconModule], template: "<div class=\"toggle-button\">\n <button (click)=\"toggle()\" mat-icon-button>\n <ng-template [ngIfElse]=\"hide\" [ngIf]=\"!openWindowSidenav\">\n <mat-icon svgIcon=\"arrow-left-bold\"></mat-icon>\n </ng-template>\n <ng-template #hide>\n <mat-icon svgIcon=\"arrow-right-bold\"></mat-icon>\n </ng-template>\n </button>\n</div>\n", styles: [".toggle-button{position:absolute;top:70px;right:0;z-index:10000;border-radius:15px 0 0 15px;border:1px solid black;background:#000}\n"] }]
|
|
122
|
-
}], propDecorators: { openWindowSidenav: [{
|
|
123
|
-
type: Input
|
|
124
|
-
}], openWindowSidenavChange: [{
|
|
125
|
-
type: Output
|
|
126
|
-
}] } });
|
|
127
|
-
|
|
128
|
-
class VersionComponent {
|
|
129
|
-
constructor(version) {
|
|
130
|
-
this.version = version;
|
|
131
|
-
}
|
|
132
|
-
ngOnInit() {
|
|
133
|
-
this.modules = this.version.get();
|
|
134
|
-
this.subscription = this.version.update$.pipe(tap(() => this.modules = this.version.get())).subscribe();
|
|
135
|
-
}
|
|
136
|
-
ngOnDestroy() {
|
|
137
|
-
this.subscription?.unsubscribe();
|
|
138
|
-
}
|
|
139
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: VersionComponent, deps: [{ token: VersionService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
140
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.0.1", type: VersionComponent, isStandalone: true, selector: "rxap-version", ngImport: i0, template: "<div class=\"version flex flex-col gap-2\">\n <div *ngFor=\"let module of modules | keyvalue\" class=\"flex flex-col\">\n <span class=\"name grow-0\">{{module.value.name}}</span>\n <span class=\"semantic grow-0\">{{module.value.semantic}}</span>\n <span class=\"hash grow-0\">{{module.value.hash}}</span>\n </div>\n</div>\n", styles: [".version{width:100%;font-size:9px;padding:8px}.version .name{padding-bottom:12px;font-size:10px}\n"], dependencies: [{ kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "pipe", type: KeyValuePipe, name: "keyvalue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
141
|
-
}
|
|
142
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: VersionComponent, decorators: [{
|
|
143
|
-
type: Component,
|
|
144
|
-
args: [{ selector: 'rxap-version', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [NgFor, KeyValuePipe], template: "<div class=\"version flex flex-col gap-2\">\n <div *ngFor=\"let module of modules | keyvalue\" class=\"flex flex-col\">\n <span class=\"name grow-0\">{{module.value.name}}</span>\n <span class=\"semantic grow-0\">{{module.value.semantic}}</span>\n <span class=\"hash grow-0\">{{module.value.hash}}</span>\n </div>\n</div>\n", styles: [".version{width:100%;font-size:9px;padding:8px}.version .name{padding-bottom:12px;font-size:10px}\n"] }]
|
|
145
|
-
}], ctorParameters: () => [{ type: i1$1.VersionService, decorators: [{
|
|
146
|
-
type: Inject,
|
|
147
|
-
args: [VersionService]
|
|
148
|
-
}] }] });
|
|
149
34
|
|
|
150
35
|
class SidenavFooterDirective {
|
|
151
36
|
constructor(template) {
|
|
@@ -183,170 +68,212 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImpor
|
|
|
183
68
|
args: [TemplateRef]
|
|
184
69
|
}] }] });
|
|
185
70
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
71
|
+
const RXAP_NAVIGATION_CONFIG = new InjectionToken('rxap/layout/navigation-config');
|
|
72
|
+
const RXAP_NAVIGATION_CONFIG_INSERTS = new InjectionToken('rxap/layout/navigation-config-inserts');
|
|
73
|
+
const RXAP_FOOTER_COMPONENT = new InjectionToken('rxap/layout/footer-component');
|
|
74
|
+
const RXAP_HEADER_COMPONENT = new InjectionToken('rxap/layout/header-component');
|
|
75
|
+
const RXAP_LOGO_CONFIG = new InjectionToken('rxap/layout/logo-config');
|
|
76
|
+
const RXAP_LAYOUT_APPS_GRID = new InjectionToken('rxap/layout/apps-grid');
|
|
77
|
+
const RXAP_EXTERNAL_APP_FILTER = new InjectionToken('rxap/layout/app-config-filter');
|
|
78
|
+
const EXTRACT_USERNAME_FROM_PROFILE = new InjectionToken('extract-username-from-profile', {
|
|
79
|
+
providedIn: 'root',
|
|
80
|
+
factory: () => (profile) => (profile ? profile.username ?? profile.email ?? profile.name : null) ?? null,
|
|
81
|
+
});
|
|
82
|
+
const RXAP_RELEASE_INFO_MODULE = new InjectionToken('rxap/layout/release-info-module');
|
|
83
|
+
const RXAP_SETTINGS_MENU_ITEM_COMPONENT = new InjectionToken('rxap/layout/settings-menu-item-component');
|
|
84
|
+
const RXAP_SETTINGS_MENU_ITEM = new InjectionToken('rxap/layout/settings-menu-item');
|
|
85
|
+
|
|
86
|
+
class FooterService {
|
|
87
|
+
constructor() {
|
|
88
|
+
this.components = coerceArray(inject(RXAP_FOOTER_COMPONENT, { optional: true }));
|
|
89
|
+
/**
|
|
90
|
+
* Represents an array of `Portal` objects with unknown type.
|
|
91
|
+
*/
|
|
92
|
+
this.portals = signal(this.components.map(component => new ComponentPortal(component)));
|
|
93
|
+
/**
|
|
94
|
+
* Computes the count of portals.
|
|
95
|
+
*
|
|
96
|
+
* @returns {number} The count of portals.
|
|
97
|
+
*/
|
|
98
|
+
this.portalCount = computed(() => this.portals().length);
|
|
191
99
|
}
|
|
192
|
-
|
|
193
|
-
|
|
100
|
+
/**
|
|
101
|
+
* Adds a portal to the list of portals.
|
|
102
|
+
*
|
|
103
|
+
* @param {Portal<unknown>} portal - The portal to be added.
|
|
104
|
+
*
|
|
105
|
+
* @return {void}
|
|
106
|
+
*/
|
|
107
|
+
pushPortal(portal) {
|
|
108
|
+
if (!this.portals().includes(portal)) {
|
|
109
|
+
this.portals.update(portals => [...portals, portal]);
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
if (isDevMode()) {
|
|
113
|
+
console.warn('Can not add the same portal multiple times');
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Removes a portal from the list of portals.
|
|
119
|
+
*
|
|
120
|
+
* @param {Portal<unknown>} portal - The portal to be removed.
|
|
121
|
+
* @return {void}
|
|
122
|
+
*/
|
|
123
|
+
removePortal(portal) {
|
|
124
|
+
const index = this.portals().indexOf(portal);
|
|
125
|
+
if (index !== -1) {
|
|
126
|
+
this.portals.update(portals => {
|
|
127
|
+
portals.splice(index, 1);
|
|
128
|
+
return portals.slice();
|
|
129
|
+
});
|
|
130
|
+
}
|
|
194
131
|
}
|
|
195
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type:
|
|
196
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type:
|
|
132
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: FooterService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
133
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: FooterService }); }
|
|
197
134
|
}
|
|
198
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type:
|
|
199
|
-
type: Injectable
|
|
200
|
-
|
|
201
|
-
}], ctorParameters: () => [{ type: i1$2.ConfigService }] });
|
|
135
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: FooterService, decorators: [{
|
|
136
|
+
type: Injectable
|
|
137
|
+
}] });
|
|
202
138
|
|
|
203
|
-
class
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
this.
|
|
218
|
-
this.level = 0;
|
|
219
|
-
this._isActive = false;
|
|
220
|
-
this.children = null;
|
|
221
|
-
this.active = signal(false);
|
|
222
|
-
this._subscription = new Subscription();
|
|
139
|
+
class HeaderService {
|
|
140
|
+
constructor() {
|
|
141
|
+
this.components = coerceArray(inject(RXAP_HEADER_COMPONENT, { optional: true }));
|
|
142
|
+
/**
|
|
143
|
+
* Represents an array of `Portal` objects with unknown type.
|
|
144
|
+
*
|
|
145
|
+
* @typedef {Array<Portal<unknown>>} SignalPortals
|
|
146
|
+
*/
|
|
147
|
+
this.portals = signal(this.components.map(component => new ComponentPortal(component)));
|
|
148
|
+
/**
|
|
149
|
+
* Computes the count of portals.
|
|
150
|
+
*
|
|
151
|
+
* @returns {number} The count of portals.
|
|
152
|
+
*/
|
|
153
|
+
this.portalCount = computed(() => this.portals().length);
|
|
223
154
|
}
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
155
|
+
/**
|
|
156
|
+
* Adds a portal to the list of portals.
|
|
157
|
+
*
|
|
158
|
+
* @param {Portal<unknown>} portal - The portal to be added.
|
|
159
|
+
*
|
|
160
|
+
* @return {void}
|
|
161
|
+
*/
|
|
162
|
+
pushPortal(portal) {
|
|
163
|
+
if (!this.portals().includes(portal)) {
|
|
164
|
+
this.portals.update(portals => [...portals, portal]);
|
|
229
165
|
}
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
.pipe(filter((event) => event instanceof NavigationEnd), debounceTime(100), startWith(true), tap(() => {
|
|
234
|
-
let isActive = true;
|
|
235
|
-
const urlParts = this.router.url.split('/');
|
|
236
|
-
if (urlParts[0] === '') {
|
|
237
|
-
urlParts[0] = '/';
|
|
166
|
+
else {
|
|
167
|
+
if (isDevMode()) {
|
|
168
|
+
console.warn('Can not add the same portal multiple times');
|
|
238
169
|
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Removes a portal from the list of portals.
|
|
174
|
+
*
|
|
175
|
+
* @param {Portal<unknown>} portal - The portal to be removed.
|
|
176
|
+
* @return {void}
|
|
177
|
+
*/
|
|
178
|
+
removePortal(portal) {
|
|
179
|
+
const index = this.portals().indexOf(portal);
|
|
180
|
+
if (index !== -1) {
|
|
181
|
+
this.portals.update(portals => {
|
|
182
|
+
portals.splice(index, 1);
|
|
183
|
+
return portals.slice();
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: HeaderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
188
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: HeaderService }); }
|
|
189
|
+
}
|
|
190
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: HeaderService, decorators: [{
|
|
191
|
+
type: Injectable
|
|
192
|
+
}] });
|
|
193
|
+
|
|
194
|
+
class LayoutService {
|
|
195
|
+
constructor() {
|
|
196
|
+
this.currentThemeDensity = toSignal(ObserveCurrentThemeDensity());
|
|
197
|
+
this.footerService = inject(FooterService);
|
|
198
|
+
this.headerService = inject(HeaderService);
|
|
199
|
+
this.config = inject(ConfigService);
|
|
200
|
+
this.mediaMatcher = inject(MediaMatcher);
|
|
201
|
+
const mobileQuery = this.mediaMatcher.matchMedia('(max-width: 959px)');
|
|
202
|
+
this.isMobile = toSignal(new Observable(subscriber => {
|
|
203
|
+
mobileQuery.addEventListener('change', (event) => {
|
|
204
|
+
subscriber.next(event.matches);
|
|
205
|
+
});
|
|
206
|
+
}), { initialValue: mobileQuery.matches });
|
|
207
|
+
const initialCollapsable = this.config.get('navigation.collapsable', true);
|
|
208
|
+
const collapsable = initialCollapsable && !this.isMobile();
|
|
209
|
+
const pinned = this.config.get('navigation.pinned', false);
|
|
210
|
+
const mode = this.config.get('navigation.mode', pinned || !collapsable ? 'side' : 'over');
|
|
211
|
+
const opened = this.config.get('navigation.opened', (!collapsable || pinned) && !this.isMobile());
|
|
212
|
+
const fixedInViewport = this.config.get('navigation.fixedInViewport', true);
|
|
213
|
+
if (isDevMode()) {
|
|
214
|
+
console.log({
|
|
215
|
+
initialCollapsable,
|
|
216
|
+
collapsable,
|
|
217
|
+
pinned,
|
|
218
|
+
mode,
|
|
219
|
+
opened,
|
|
220
|
+
fixedInViewport,
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
this.opened = signal(opened);
|
|
224
|
+
this.mode = signal(mode);
|
|
225
|
+
this.pinned = signal(pinned);
|
|
226
|
+
this.collapsable = signal(collapsable);
|
|
227
|
+
this.fixedInViewport = signal(fixedInViewport);
|
|
228
|
+
this.collapsed = computed(() => this.collapsable() && !this.opened() && !this.pinned());
|
|
229
|
+
this.fixedBottomGap = computed(() => {
|
|
230
|
+
const footerPortalCount = this.footerService.portalCount();
|
|
231
|
+
const currentThemeDensity = this.currentThemeDensity() ?? 0;
|
|
232
|
+
return footerPortalCount * (currentThemeDensity * 4 + 64);
|
|
233
|
+
});
|
|
234
|
+
this.fixedTopGap = computed(() => {
|
|
235
|
+
const headerPortalCount = this.headerService.portalCount();
|
|
236
|
+
const currentThemeDensity = this.currentThemeDensity() ?? 0;
|
|
237
|
+
return headerPortalCount * (currentThemeDensity * 4 + 64);
|
|
238
|
+
});
|
|
239
|
+
if (initialCollapsable) {
|
|
240
|
+
effect(() => {
|
|
241
|
+
const isMobile = this.isMobile();
|
|
242
|
+
this.collapsable.set(!isMobile);
|
|
243
|
+
if (!isMobile && !this.pinned()) {
|
|
244
|
+
this.opened.set(false);
|
|
243
245
|
}
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
246
|
+
}, { allowSignalWrites: true });
|
|
247
|
+
}
|
|
248
|
+
effect(() => {
|
|
249
|
+
if (this.pinned()) {
|
|
250
|
+
this.mode.set('side');
|
|
251
|
+
this.opened.set(true);
|
|
248
252
|
}
|
|
249
253
|
else {
|
|
250
|
-
this.
|
|
254
|
+
this.mode.set('over');
|
|
255
|
+
this.opened.set(false);
|
|
251
256
|
}
|
|
252
|
-
})
|
|
253
|
-
.subscribe());
|
|
257
|
+
}, { allowSignalWrites: true });
|
|
254
258
|
}
|
|
255
|
-
|
|
256
|
-
this.
|
|
259
|
+
toggleOpened() {
|
|
260
|
+
this.opened.update(opened => !opened);
|
|
257
261
|
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
isNavigationDividerItem(item) {
|
|
261
|
-
return item['divider'];
|
|
262
|
+
togglePinned() {
|
|
263
|
+
this.pinned.update(pinned => !pinned);
|
|
262
264
|
}
|
|
263
|
-
|
|
264
|
-
|
|
265
|
+
openSidenav() {
|
|
266
|
+
this.opened.set(true);
|
|
265
267
|
}
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
throw new Error('The item is not a NavigationItem');
|
|
269
|
-
}
|
|
270
|
-
return item;
|
|
268
|
+
closeSidenav() {
|
|
269
|
+
this.opened.set(false);
|
|
271
270
|
}
|
|
272
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type:
|
|
273
|
-
static { this.ɵ
|
|
274
|
-
trigger('sub-nav', [
|
|
275
|
-
transition(':enter', [
|
|
276
|
-
style({
|
|
277
|
-
display: 'block',
|
|
278
|
-
height: '0',
|
|
279
|
-
overflow: 'hidden',
|
|
280
|
-
}),
|
|
281
|
-
animate(150, style({ height: '*' })),
|
|
282
|
-
]),
|
|
283
|
-
transition(':leave', [
|
|
284
|
-
style({ overflow: 'hidden' }),
|
|
285
|
-
animate(300, style({ height: '0' })),
|
|
286
|
-
style({ display: 'none' }),
|
|
287
|
-
]),
|
|
288
|
-
]),
|
|
289
|
-
], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
271
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: LayoutService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
272
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: LayoutService }); }
|
|
290
273
|
}
|
|
291
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type:
|
|
292
|
-
type:
|
|
293
|
-
|
|
294
|
-
trigger('sub-nav', [
|
|
295
|
-
transition(':enter', [
|
|
296
|
-
style({
|
|
297
|
-
display: 'block',
|
|
298
|
-
height: '0',
|
|
299
|
-
overflow: 'hidden',
|
|
300
|
-
}),
|
|
301
|
-
animate(150, style({ height: '*' })),
|
|
302
|
-
]),
|
|
303
|
-
transition(':leave', [
|
|
304
|
-
style({ overflow: 'hidden' }),
|
|
305
|
-
animate(300, style({ height: '0' })),
|
|
306
|
-
style({ display: 'none' }),
|
|
307
|
-
]),
|
|
308
|
-
]),
|
|
309
|
-
], standalone: true, imports: [
|
|
310
|
-
RouterLinkActive,
|
|
311
|
-
RouterLink,
|
|
312
|
-
NgIf,
|
|
313
|
-
MatRippleModule,
|
|
314
|
-
MatIconModule,
|
|
315
|
-
IconDirective,
|
|
316
|
-
MatDividerModule,
|
|
317
|
-
forwardRef(() => NavigationComponent),
|
|
318
|
-
NgClass,
|
|
319
|
-
], template: "<div [ngClass]=\"{\n 'border-l-4 text-accent-400 border-accent-600': active(),\n }\">\n <a [routerLink]=\"item.routerLink\"\n class=\"h-12 pl-4 pr-5 flex flex-row justify-between items-center gap-x-4\"\n matRipple\n routerLinkActive\n\n >\n <span\n [ngClass]=\"{\n 'pl-0': level === 0,\n 'pl-4': level === 1,\n 'pl-8': level === 2,\n 'pl-12': level === 3\n }\"\n class=\"grow whitespace-nowrap\"\n >\n {{ item.label }}\n </span>\n <mat-icon *ngIf=\"item.icon\" [rxapIcon]=\"item.icon\"></mat-icon>\n </a>\n\n <ng-container *ngIf=\"item.children?.length && active()\">\n\n <mat-divider></mat-divider>\n\n <ul [@sub-nav]\n [items]=\"children ?? []\"\n [level]=\"level + 1\"\n rxap-navigation\n >\n </ul>\n\n <mat-divider></mat-divider>\n\n </ng-container>\n</div>\n" }]
|
|
320
|
-
}], ctorParameters: () => [{ type: i2.Router, decorators: [{
|
|
321
|
-
type: Inject,
|
|
322
|
-
args: [Router]
|
|
323
|
-
}] }, { type: SidenavComponentService, decorators: [{
|
|
324
|
-
type: Inject,
|
|
325
|
-
args: [SidenavComponentService]
|
|
326
|
-
}] }, { type: i0.ElementRef, decorators: [{
|
|
327
|
-
type: Inject,
|
|
328
|
-
args: [ElementRef]
|
|
329
|
-
}] }, { type: i0.Renderer2, decorators: [{
|
|
330
|
-
type: Inject,
|
|
331
|
-
args: [Renderer2]
|
|
332
|
-
}] }, { type: i6.Overlay, decorators: [{
|
|
333
|
-
type: Inject,
|
|
334
|
-
args: [Overlay]
|
|
335
|
-
}] }, { type: i0.ViewContainerRef, decorators: [{
|
|
336
|
-
type: Inject,
|
|
337
|
-
args: [ViewContainerRef]
|
|
338
|
-
}] }], propDecorators: { level: [{
|
|
339
|
-
type: Input
|
|
340
|
-
}], routerLinkActive: [{
|
|
341
|
-
type: ViewChild,
|
|
342
|
-
args: [RouterLinkActive, { static: true }]
|
|
343
|
-
}], item: [{
|
|
344
|
-
type: Input,
|
|
345
|
-
args: [{ required: true }]
|
|
346
|
-
}], isActive: [{
|
|
347
|
-
type: HostBinding,
|
|
348
|
-
args: ['class.active']
|
|
349
|
-
}] } });
|
|
274
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: LayoutService, decorators: [{
|
|
275
|
+
type: Injectable
|
|
276
|
+
}], ctorParameters: () => [] });
|
|
350
277
|
|
|
351
278
|
function IsNavigationDividerItem(item) {
|
|
352
279
|
return !!item && !!item['divider'];
|
|
@@ -358,18 +285,11 @@ function IsNavigationItem(item) {
|
|
|
358
285
|
return (!!item && !!item['routerLink'] && !!item['label']);
|
|
359
286
|
}
|
|
360
287
|
|
|
361
|
-
const RXAP_NAVIGATION_CONFIG = new InjectionToken('rxap/layout/navigation-config');
|
|
362
|
-
const RXAP_NAVIGATION_CONFIG_INSERTS = new InjectionToken('rxap/layout/navigation-config-inserts');
|
|
363
|
-
const RXAP_FOOTER_COMPONENT = new InjectionToken('rxap/layout/footer-component');
|
|
364
|
-
const RXAP_HEADER_COMPONENT = new InjectionToken('rxap/layout/header-component');
|
|
365
|
-
const RXAP_LOGO_CONFIG = new InjectionToken('rxap/layout/logo-config');
|
|
366
|
-
const RXAP_LAYOUT_APPS_GRID = new InjectionToken('rxap/layout/apps-grid');
|
|
367
|
-
|
|
368
288
|
class NavigationService {
|
|
369
|
-
constructor(navigation,
|
|
370
|
-
this.injector = injector;
|
|
289
|
+
constructor(navigation, inserts = null) {
|
|
371
290
|
this.inserts = new Map();
|
|
372
291
|
this.navigation$ = new ReplaySubject(1);
|
|
292
|
+
this.injector = inject(INJECTOR);
|
|
373
293
|
if (typeof navigation === 'function') {
|
|
374
294
|
this.navigation = navigation();
|
|
375
295
|
}
|
|
@@ -420,7 +340,8 @@ class NavigationService {
|
|
|
420
340
|
if (IsNavigationDividerItem(navigationItem) || !navigationItem.status) {
|
|
421
341
|
return of(navigationItem);
|
|
422
342
|
}
|
|
423
|
-
const isVisibleArray$ = navigationItem
|
|
343
|
+
const isVisibleArray$ = navigationItem
|
|
344
|
+
.status
|
|
424
345
|
.map((statusToken) => this.injector.get(statusToken))
|
|
425
346
|
.map((status) => {
|
|
426
347
|
const isVisible = status.isVisible(navigationItem);
|
|
@@ -432,8 +353,7 @@ class NavigationService {
|
|
|
432
353
|
}
|
|
433
354
|
})
|
|
434
355
|
.map(isVisible$ => isVisible$.pipe(catchError(e => {
|
|
435
|
-
console.error(
|
|
436
|
-
e.message);
|
|
356
|
+
console.error(`isVisible method failed: ${e.message}`);
|
|
437
357
|
return of(false);
|
|
438
358
|
})));
|
|
439
359
|
// TODO : dont wait for all status services to complete, but cancel waiting if one returns false
|
|
@@ -485,18 +405,14 @@ class NavigationService {
|
|
|
485
405
|
}
|
|
486
406
|
return navigation;
|
|
487
407
|
}
|
|
488
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: NavigationService, deps: [{ token: RXAP_NAVIGATION_CONFIG }, { token:
|
|
489
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: NavigationService
|
|
408
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: NavigationService, deps: [{ token: RXAP_NAVIGATION_CONFIG }, { token: RXAP_NAVIGATION_CONFIG_INSERTS, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
409
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: NavigationService }); }
|
|
490
410
|
}
|
|
491
411
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: NavigationService, decorators: [{
|
|
492
|
-
type: Injectable
|
|
493
|
-
args: [{ providedIn: 'root' }]
|
|
412
|
+
type: Injectable
|
|
494
413
|
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
495
414
|
type: Inject,
|
|
496
415
|
args: [RXAP_NAVIGATION_CONFIG]
|
|
497
|
-
}] }, { type: undefined, decorators: [{
|
|
498
|
-
type: Inject,
|
|
499
|
-
args: [INJECTOR]
|
|
500
416
|
}] }, { type: undefined, decorators: [{
|
|
501
417
|
type: Optional
|
|
502
418
|
}, {
|
|
@@ -504,28 +420,59 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImpor
|
|
|
504
420
|
args: [RXAP_NAVIGATION_CONFIG_INSERTS]
|
|
505
421
|
}] }] });
|
|
506
422
|
|
|
507
|
-
class
|
|
508
|
-
constructor(
|
|
509
|
-
this.
|
|
510
|
-
this.
|
|
511
|
-
this.
|
|
512
|
-
this.
|
|
513
|
-
this.
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
423
|
+
class NavigationItemComponent {
|
|
424
|
+
constructor() {
|
|
425
|
+
this.level = input(0);
|
|
426
|
+
this.children = null;
|
|
427
|
+
this.item = input.required();
|
|
428
|
+
this.active = signal(false);
|
|
429
|
+
this.itemClasses = computed(() => {
|
|
430
|
+
let classes = `level-${this.level() * 4}`;
|
|
431
|
+
if (this.collapsed()) {
|
|
432
|
+
classes += ' invisible';
|
|
433
|
+
}
|
|
434
|
+
return classes;
|
|
435
|
+
});
|
|
436
|
+
this.layoutService = inject(LayoutService);
|
|
437
|
+
this.collapsed = computed(() => this.layoutService.collapsed());
|
|
438
|
+
this._subscription = new Subscription();
|
|
439
|
+
this.router = inject(Router);
|
|
440
|
+
this.elementRef = inject(ElementRef);
|
|
441
|
+
this.renderer = inject(Renderer2);
|
|
517
442
|
}
|
|
518
|
-
|
|
519
|
-
if (
|
|
520
|
-
|
|
521
|
-
this.
|
|
522
|
-
.
|
|
523
|
-
.subscribe();
|
|
443
|
+
ngOnChanges(changes) {
|
|
444
|
+
if (changes['item']) {
|
|
445
|
+
const item = changes['item'].currentValue;
|
|
446
|
+
this.children =
|
|
447
|
+
item.children && item.children.length ? item.children : null;
|
|
524
448
|
}
|
|
525
|
-
|
|
449
|
+
}
|
|
450
|
+
ngAfterViewInit() {
|
|
451
|
+
this._subscription.add(this.router.events
|
|
452
|
+
.pipe(filter((event) => event instanceof NavigationEnd), debounceTime(100), startWith(true), tap(() => {
|
|
453
|
+
let isActive = true;
|
|
454
|
+
const urlParts = this.router.url.split('/');
|
|
455
|
+
if (urlParts[0] === '') {
|
|
456
|
+
urlParts[0] = '/';
|
|
457
|
+
}
|
|
458
|
+
for (let i = 0; i < this.item().routerLink.length; i++) {
|
|
459
|
+
if (urlParts[i] !== this.item().routerLink[i]) {
|
|
460
|
+
isActive = false;
|
|
461
|
+
break;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
this.active.set(isActive);
|
|
465
|
+
if (isActive) {
|
|
466
|
+
this.renderer.addClass(this.elementRef.nativeElement, 'active');
|
|
467
|
+
}
|
|
468
|
+
else {
|
|
469
|
+
this.renderer.removeClass(this.elementRef.nativeElement, 'active');
|
|
470
|
+
}
|
|
471
|
+
}))
|
|
472
|
+
.subscribe());
|
|
526
473
|
}
|
|
527
474
|
ngOnDestroy() {
|
|
528
|
-
this.
|
|
475
|
+
this._subscription?.unsubscribe();
|
|
529
476
|
}
|
|
530
477
|
// region type save item property
|
|
531
478
|
// required to check the type of the item property in the ngFor loop
|
|
@@ -541,350 +488,431 @@ class NavigationComponent {
|
|
|
541
488
|
}
|
|
542
489
|
return item;
|
|
543
490
|
}
|
|
544
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type:
|
|
545
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
491
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: NavigationItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
492
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.0.1", type: NavigationItemComponent, isStandalone: true, selector: "li[rxap-navigation-item]", inputs: { level: { classPropertyName: "level", publicName: "level", isSignal: true, isRequired: false, transformFunction: null }, item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: true, transformFunction: null } }, usesOnChanges: true, ngImport: i0, template: "<div [ngClass]=\"{\n 'border-l-4 text-accent-400 border-accent-600': active(),\n }\">\n <a [routerLink]=\"item().routerLink\"\n class=\"h-12 pl-4 pr-5 flex flex-row justify-between items-center gap-x-4\"\n matRipple\n routerLinkActive\n\n >\n <span\n [ngClass]=\"itemClasses()\"\n class=\"grow whitespace-nowrap\"\n >\n {{ item().label }}\n </span>\n <mat-icon *ngIf=\"item().icon\" [rxapIcon]=\"item().icon\"></mat-icon>\n </a>\n\n <ng-container *ngIf=\"item().children?.length && active()\">\n\n <mat-divider></mat-divider>\n\n <ul [@sub-nav]\n [items]=\"children ?? []\"\n [level]=\"level() + 1\"\n rxap-navigation\n >\n </ul>\n\n <mat-divider></mat-divider>\n\n </ng-container>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i0.forwardRef(() => RouterLinkActive), selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { kind: "directive", type: i0.forwardRef(() => RouterLink), selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i0.forwardRef(() => NgIf), selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: i0.forwardRef(() => MatRippleModule) }, { kind: "directive", type: i0.forwardRef(() => i1.MatRipple), selector: "[mat-ripple], [matRipple]", inputs: ["matRippleColor", "matRippleUnbounded", "matRippleCentered", "matRippleRadius", "matRippleAnimation", "matRippleDisabled", "matRippleTrigger"], exportAs: ["matRipple"] }, { kind: "ngmodule", type: i0.forwardRef(() => MatIconModule) }, { kind: "component", type: i0.forwardRef(() => i2.MatIcon), selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i0.forwardRef(() => IconDirective), selector: "mat-icon[rxapIcon]", inputs: ["rxapIcon"] }, { kind: "ngmodule", type: i0.forwardRef(() => MatDividerModule) }, { kind: "component", type: i0.forwardRef(() => i3.MatDivider), selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "component", type: i0.forwardRef(() => NavigationComponent), selector: "ul[rxap-navigation]", inputs: ["items", "level", "root"] }, { kind: "directive", type: i0.forwardRef(() => NgClass), selector: "[ngClass]", inputs: ["class", "ngClass"] }], animations: [
|
|
493
|
+
trigger('sub-nav', [
|
|
494
|
+
transition(':enter', [
|
|
495
|
+
style({
|
|
496
|
+
display: 'block',
|
|
497
|
+
height: '0',
|
|
498
|
+
overflow: 'hidden',
|
|
499
|
+
}),
|
|
500
|
+
animate(150, style({ height: '*' })),
|
|
501
|
+
]),
|
|
502
|
+
transition(':leave', [
|
|
503
|
+
style({ overflow: 'hidden' }),
|
|
504
|
+
animate(300, style({ height: '0' })),
|
|
505
|
+
style({ display: 'none' }),
|
|
506
|
+
]),
|
|
507
|
+
]),
|
|
508
|
+
], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
546
509
|
}
|
|
547
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type:
|
|
510
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: NavigationItemComponent, decorators: [{
|
|
548
511
|
type: Component,
|
|
549
|
-
args: [{ selector: '
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
512
|
+
args: [{ selector: 'li[rxap-navigation-item]', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, animations: [
|
|
513
|
+
trigger('sub-nav', [
|
|
514
|
+
transition(':enter', [
|
|
515
|
+
style({
|
|
516
|
+
display: 'block',
|
|
517
|
+
height: '0',
|
|
518
|
+
overflow: 'hidden',
|
|
519
|
+
}),
|
|
520
|
+
animate(150, style({ height: '*' })),
|
|
521
|
+
]),
|
|
522
|
+
transition(':leave', [
|
|
523
|
+
style({ overflow: 'hidden' }),
|
|
524
|
+
animate(300, style({ height: '0' })),
|
|
525
|
+
style({ display: 'none' }),
|
|
526
|
+
]),
|
|
527
|
+
]),
|
|
528
|
+
], standalone: true, imports: [
|
|
529
|
+
RouterLinkActive,
|
|
530
|
+
RouterLink,
|
|
531
|
+
NgIf,
|
|
532
|
+
MatRippleModule,
|
|
533
|
+
MatIconModule,
|
|
534
|
+
IconDirective,
|
|
535
|
+
MatDividerModule,
|
|
536
|
+
forwardRef(() => NavigationComponent),
|
|
537
|
+
NgClass,
|
|
538
|
+
], template: "<div [ngClass]=\"{\n 'border-l-4 text-accent-400 border-accent-600': active(),\n }\">\n <a [routerLink]=\"item().routerLink\"\n class=\"h-12 pl-4 pr-5 flex flex-row justify-between items-center gap-x-4\"\n matRipple\n routerLinkActive\n\n >\n <span\n [ngClass]=\"itemClasses()\"\n class=\"grow whitespace-nowrap\"\n >\n {{ item().label }}\n </span>\n <mat-icon *ngIf=\"item().icon\" [rxapIcon]=\"item().icon\"></mat-icon>\n </a>\n\n <ng-container *ngIf=\"item().children?.length && active()\">\n\n <mat-divider></mat-divider>\n\n <ul [@sub-nav]\n [items]=\"children ?? []\"\n [level]=\"level() + 1\"\n rxap-navigation\n >\n </ul>\n\n <mat-divider></mat-divider>\n\n </ng-container>\n</div>\n" }]
|
|
539
|
+
}] });
|
|
577
540
|
|
|
578
|
-
class
|
|
579
|
-
constructor(
|
|
580
|
-
this.
|
|
541
|
+
class NavigationComponent {
|
|
542
|
+
constructor() {
|
|
543
|
+
this.items = input();
|
|
544
|
+
this.level = input(0);
|
|
545
|
+
this.navigationService = inject(NavigationService);
|
|
546
|
+
this.layoutService = inject(LayoutService);
|
|
547
|
+
this.collapsed = computed(() => this.layoutService.collapsed());
|
|
548
|
+
this.navigationItems = computed(() => this.items() ?? []);
|
|
549
|
+
this.root = input(false);
|
|
550
|
+
this.injector = inject(INJECTOR);
|
|
551
|
+
}
|
|
552
|
+
ngOnInit() {
|
|
553
|
+
if (this.root()) {
|
|
554
|
+
runInInjectionContext(this.injector, () => {
|
|
555
|
+
this.navigationItems = toSignal(this.navigationService.config$, { initialValue: [] });
|
|
556
|
+
});
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
// region type save item property
|
|
560
|
+
// required to check the type of the item property in the ngFor loop
|
|
561
|
+
isNavigationDividerItem(item) {
|
|
562
|
+
return item['divider'];
|
|
563
|
+
}
|
|
564
|
+
isNavigationItem(item) {
|
|
565
|
+
return !this.isNavigationDividerItem(item);
|
|
566
|
+
}
|
|
567
|
+
asNavigationItem(item) {
|
|
568
|
+
if (!this.isNavigationItem(item)) {
|
|
569
|
+
throw new Error('The item is not a NavigationItem');
|
|
570
|
+
}
|
|
571
|
+
return item;
|
|
581
572
|
}
|
|
582
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type:
|
|
583
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
573
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: NavigationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
574
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.0.1", type: NavigationComponent, isStandalone: true, selector: "ul[rxap-navigation]", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, level: { classPropertyName: "level", publicName: "level", isSignal: true, isRequired: false, transformFunction: null }, root: { classPropertyName: "root", publicName: "root", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "list-none dark:text-neutral-400 text-neutral-700" }, ngImport: i0, template: "<ng-template [ngForOf]=\"navigationItems()\" let-item ngFor>\n <ng-template [ngIf]=\"isNavigationDividerItem(item)\">\n <mat-divider></mat-divider>\n <div *ngIf=\"!collapsed() && item.title\" class=\"pl-5 h-6\">\n {{item.title}}\n </div>\n </ng-template>\n <ng-template [ngIf]=\"isNavigationItem(item)\">\n <li [item]=\"asNavigationItem(item)\"\n [level]=\"level()\"\n class=\"dark:hover:text-white hover:text-black\"\n rxap-navigation-item>\n </li>\n </ng-template>\n</ng-template>\n", styles: [""], dependencies: [{ kind: "directive", type: i0.forwardRef(() => NgFor), selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i0.forwardRef(() => NgIf), selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: i0.forwardRef(() => MatDividerModule) }, { kind: "component", type: i0.forwardRef(() => i3.MatDivider), selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "component", type: i0.forwardRef(() => NavigationItemComponent), selector: "li[rxap-navigation-item]", inputs: ["level", "item"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
584
575
|
}
|
|
585
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type:
|
|
576
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: NavigationComponent, decorators: [{
|
|
586
577
|
type: Component,
|
|
587
|
-
args: [{ selector: 'rxap-
|
|
588
|
-
class: '
|
|
589
|
-
},
|
|
590
|
-
|
|
578
|
+
args: [{ selector: 'ul[rxap-navigation]', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, standalone: true, host: {
|
|
579
|
+
class: 'list-none dark:text-neutral-400 text-neutral-700',
|
|
580
|
+
}, imports: [
|
|
581
|
+
NgFor,
|
|
591
582
|
NgIf,
|
|
592
|
-
NgTemplateOutlet,
|
|
593
583
|
MatDividerModule,
|
|
594
|
-
|
|
595
|
-
MatButtonModule,
|
|
596
|
-
MatIconModule,
|
|
584
|
+
forwardRef(() => NavigationItemComponent),
|
|
597
585
|
AsyncPipe,
|
|
598
|
-
], template: "<
|
|
599
|
-
}]
|
|
600
|
-
type: ContentChild,
|
|
601
|
-
args: [SidenavFooterDirective]
|
|
602
|
-
}], sidenavHeaderDirective: [{
|
|
603
|
-
type: ContentChild,
|
|
604
|
-
args: [SidenavHeaderDirective]
|
|
605
|
-
}] } });
|
|
586
|
+
], template: "<ng-template [ngForOf]=\"navigationItems()\" let-item ngFor>\n <ng-template [ngIf]=\"isNavigationDividerItem(item)\">\n <mat-divider></mat-divider>\n <div *ngIf=\"!collapsed() && item.title\" class=\"pl-5 h-6\">\n {{item.title}}\n </div>\n </ng-template>\n <ng-template [ngIf]=\"isNavigationItem(item)\">\n <li [item]=\"asNavigationItem(item)\"\n [level]=\"level()\"\n class=\"dark:hover:text-white hover:text-black\"\n rxap-navigation-item>\n </li>\n </ng-template>\n</ng-template>\n" }]
|
|
587
|
+
}] });
|
|
606
588
|
|
|
607
|
-
class
|
|
608
|
-
|
|
609
|
-
|
|
589
|
+
class SidenavComponent {
|
|
590
|
+
constructor() {
|
|
591
|
+
this.layoutService = inject(LayoutService);
|
|
592
|
+
this.sidenav = viewChild(MatSidenav);
|
|
593
|
+
this.sidenavMode = computed(() => this.layoutService.mode());
|
|
594
|
+
this.fixedBottomGap = computed(() => this.layoutService.fixedBottomGap());
|
|
595
|
+
this.fixedTopGap = computed(() => this.layoutService.fixedTopGap());
|
|
596
|
+
this.fixedInViewport = computed(() => this.layoutService.fixedInViewport());
|
|
597
|
+
this.pinned = computed(() => this.layoutService.pinned());
|
|
598
|
+
this.collapsed = computed(() => this.layoutService.collapsed());
|
|
599
|
+
this.collapsable = computed(() => this.layoutService.collapsable());
|
|
600
|
+
this.opened = computed(() => this.layoutService.opened());
|
|
601
|
+
this.sidenavFooterDirective = contentChild(SidenavFooterDirective);
|
|
602
|
+
this.sidenavHeaderDirective = contentChild(SidenavHeaderDirective);
|
|
603
|
+
}
|
|
604
|
+
togglePinned() {
|
|
605
|
+
this.layoutService.togglePinned();
|
|
606
|
+
}
|
|
607
|
+
async openSidenav() {
|
|
608
|
+
await this.sidenav()?.open();
|
|
609
|
+
this.layoutService.openSidenav();
|
|
610
610
|
}
|
|
611
|
-
|
|
612
|
-
|
|
611
|
+
async closeSidenav() {
|
|
612
|
+
await this.sidenav()?.close();
|
|
613
|
+
this.layoutService.closeSidenav();
|
|
614
|
+
}
|
|
615
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: SidenavComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
616
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.1", type: SidenavComponent, isStandalone: true, selector: "rxap-sidenav", queries: [{ propertyName: "sidenavFooterDirective", first: true, predicate: SidenavFooterDirective, descendants: true, isSignal: true }, { propertyName: "sidenavHeaderDirective", first: true, predicate: SidenavHeaderDirective, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "sidenav", first: true, predicate: MatSidenav, descendants: true, isSignal: true }], ngImport: i0, template: "<mat-sidenav-container [ngStyle]=\"{\n 'padding-top.px': fixedTopGap(),\n 'padding-bottom.px': fixedBottomGap(),\n }\" class=\"h-full\">\n <mat-sidenav\n [fixedBottomGap]=\"fixedBottomGap()\"\n [fixedInViewport]=\"fixedInViewport()\"\n [fixedTopGap]=\"fixedTopGap()\"\n [mode]=\"sidenavMode()\"\n [ngClass]=\"{ collapsable: collapsable() }\"\n [opened]=\"opened()\"\n >\n <div (mouseleave)=\"collapsable() && !pinned() && closeSidenav()\"\n class=\"h-full py-2 flex flex-col items-center gap-y-5 justify-items-stretch\">\n\n <div (click)=\"togglePinned()\" *ngIf=\"collapsable()\"\n class=\"pl-2 self-stretch grow-0 flex flex-row justify-between items-center\">\n <span class=\"text-lg\" i18n>Navigation</span>\n <div class=\"flex flex-row items-center justify-center\" style=\"width: 64px\">\n <button mat-icon-button>\n <mat-icon *ngIf=\"!pinned()\">radio_button_unchecked</mat-icon>\n <mat-icon *ngIf=\"pinned()\">radio_button_checked</mat-icon>\n </button>\n </div>\n </div>\n\n @if (sidenavHeaderDirective()?.template; as template) {\n <div [ngClass]=\"{ hidden: collapsed() }\" class=\"header grow-0\">\n <ng-container *ngTemplateOutlet=\"template\"></ng-container>\n </div>\n <mat-divider [ngClass]=\"{ hidden: collapsed() }\" class=\"grow-0\"></mat-divider>\n }\n\n <ul\n (mouseenter)=\"collapsable() && !pinned() && openSidenav()\"\n class=\"grow self-stretch\"\n [root]=\"true\"\n rxap-navigation\n >\n </ul>\n\n @if (sidenavFooterDirective()?.template; as template) {\n <mat-divider [ngClass]=\"{ hidden: collapsed() }\" class=\"grow-0\"></mat-divider>\n <div [ngClass]=\"{ hidden: collapsed() }\" class=\"footer grow-0\">\n <ng-container *ngTemplateOutlet=\"template\"></ng-container>\n </div>\n }\n </div>\n </mat-sidenav>\n <mat-sidenav-content [ngClass]=\"{ 'ml-16': collapsable() }\" class=\"p-4\">\n <ng-content></ng-content>\n </mat-sidenav-content>\n</mat-sidenav-container>\n", styles: [":host .collapsable:not(.mat-drawer-opened){transform:translate(calc(-100% + 64px))!important;visibility:visible!important;box-shadow:inherit!important;transition-property:transform;transition-delay:.25s;display:flex;border-right:solid 1px rgba(0,0,0,.12)}:host .collapsable ::ng-deep .mat-drawer-inner-container::-webkit-scrollbar{display:none}.rxap-container,.rxap-container .inner{height:100%}.rxap-container .inner .header{padding-bottom:12px}.rxap-container .inner .footer{padding-top:12px}.rxap-container .inner .nav-container{overflow-y:scroll;padding-top:12px}.rxap-container .inner .nav-container::-webkit-scrollbar{width:6px}.rxap-container .inner .nav-container::-webkit-scrollbar-track{border-radius:2px}.rxap-container .inner .nav-container::-webkit-scrollbar-thumb{border-radius:10px}.rxap-container .sidebar-toggle{min-height:48px}.rxap-container .sidebar-toggle .sidebar-toggle-inner{padding:0}.rxap-container .sidebar-toggle .arrow{transform:rotate(180deg)}.rxap-container .sidebar-toggle.collapsed .arrow{transform:initial}.rxap-container .sidebar-toggle.collapsed .sidebar-toggle-inner{justify-content:space-around!important}\n"], dependencies: [{ kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: MatSidenav, selector: "mat-sidenav", inputs: ["fixedInViewport", "fixedTopGap", "fixedBottomGap"], exportAs: ["matSidenav"] }, { kind: "component", type: MatSidenavContainer, selector: "mat-sidenav-container", exportAs: ["matSidenavContainer"] }, { kind: "component", type: MatSidenavContent, selector: "mat-sidenav-content" }, { kind: "component", type: NavigationComponent, selector: "ul[rxap-navigation]", inputs: ["items", "level", "root"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
613
617
|
}
|
|
614
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type:
|
|
615
|
-
type:
|
|
616
|
-
args: [{
|
|
618
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: SidenavComponent, decorators: [{
|
|
619
|
+
type: Component,
|
|
620
|
+
args: [{ selector: 'rxap-sidenav', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
|
|
621
|
+
MatIcon,
|
|
622
|
+
MatIconButton,
|
|
623
|
+
MatSidenav,
|
|
624
|
+
MatSidenavContainer,
|
|
625
|
+
MatSidenavContent,
|
|
626
|
+
NavigationComponent,
|
|
627
|
+
NgIf,
|
|
628
|
+
RouterOutlet,
|
|
629
|
+
NgClass,
|
|
630
|
+
NgStyle,
|
|
631
|
+
MatDivider,
|
|
632
|
+
NgTemplateOutlet,
|
|
633
|
+
MatButton,
|
|
634
|
+
], template: "<mat-sidenav-container [ngStyle]=\"{\n 'padding-top.px': fixedTopGap(),\n 'padding-bottom.px': fixedBottomGap(),\n }\" class=\"h-full\">\n <mat-sidenav\n [fixedBottomGap]=\"fixedBottomGap()\"\n [fixedInViewport]=\"fixedInViewport()\"\n [fixedTopGap]=\"fixedTopGap()\"\n [mode]=\"sidenavMode()\"\n [ngClass]=\"{ collapsable: collapsable() }\"\n [opened]=\"opened()\"\n >\n <div (mouseleave)=\"collapsable() && !pinned() && closeSidenav()\"\n class=\"h-full py-2 flex flex-col items-center gap-y-5 justify-items-stretch\">\n\n <div (click)=\"togglePinned()\" *ngIf=\"collapsable()\"\n class=\"pl-2 self-stretch grow-0 flex flex-row justify-between items-center\">\n <span class=\"text-lg\" i18n>Navigation</span>\n <div class=\"flex flex-row items-center justify-center\" style=\"width: 64px\">\n <button mat-icon-button>\n <mat-icon *ngIf=\"!pinned()\">radio_button_unchecked</mat-icon>\n <mat-icon *ngIf=\"pinned()\">radio_button_checked</mat-icon>\n </button>\n </div>\n </div>\n\n @if (sidenavHeaderDirective()?.template; as template) {\n <div [ngClass]=\"{ hidden: collapsed() }\" class=\"header grow-0\">\n <ng-container *ngTemplateOutlet=\"template\"></ng-container>\n </div>\n <mat-divider [ngClass]=\"{ hidden: collapsed() }\" class=\"grow-0\"></mat-divider>\n }\n\n <ul\n (mouseenter)=\"collapsable() && !pinned() && openSidenav()\"\n class=\"grow self-stretch\"\n [root]=\"true\"\n rxap-navigation\n >\n </ul>\n\n @if (sidenavFooterDirective()?.template; as template) {\n <mat-divider [ngClass]=\"{ hidden: collapsed() }\" class=\"grow-0\"></mat-divider>\n <div [ngClass]=\"{ hidden: collapsed() }\" class=\"footer grow-0\">\n <ng-container *ngTemplateOutlet=\"template\"></ng-container>\n </div>\n }\n </div>\n </mat-sidenav>\n <mat-sidenav-content [ngClass]=\"{ 'ml-16': collapsable() }\" class=\"p-4\">\n <ng-content></ng-content>\n </mat-sidenav-content>\n</mat-sidenav-container>\n", styles: [":host .collapsable:not(.mat-drawer-opened){transform:translate(calc(-100% + 64px))!important;visibility:visible!important;box-shadow:inherit!important;transition-property:transform;transition-delay:.25s;display:flex;border-right:solid 1px rgba(0,0,0,.12)}:host .collapsable ::ng-deep .mat-drawer-inner-container::-webkit-scrollbar{display:none}.rxap-container,.rxap-container .inner{height:100%}.rxap-container .inner .header{padding-bottom:12px}.rxap-container .inner .footer{padding-top:12px}.rxap-container .inner .nav-container{overflow-y:scroll;padding-top:12px}.rxap-container .inner .nav-container::-webkit-scrollbar{width:6px}.rxap-container .inner .nav-container::-webkit-scrollbar-track{border-radius:2px}.rxap-container .inner .nav-container::-webkit-scrollbar-thumb{border-radius:10px}.rxap-container .sidebar-toggle{min-height:48px}.rxap-container .sidebar-toggle .sidebar-toggle-inner{padding:0}.rxap-container .sidebar-toggle .arrow{transform:rotate(180deg)}.rxap-container .sidebar-toggle.collapsed .arrow{transform:initial}.rxap-container .sidebar-toggle.collapsed .sidebar-toggle-inner{justify-content:space-around!important}\n"] }]
|
|
617
635
|
}] });
|
|
618
636
|
|
|
619
|
-
class
|
|
620
|
-
constructor(
|
|
621
|
-
this.
|
|
637
|
+
class ReleaseInfoComponent {
|
|
638
|
+
constructor() {
|
|
639
|
+
this.modules = coerceArray(inject(RXAP_RELEASE_INFO_MODULE, { optional: true }));
|
|
640
|
+
this.release = DetermineReleaseName(inject(RXAP_ENVIRONMENT));
|
|
641
|
+
this.dialog = inject(MatDialog);
|
|
622
642
|
}
|
|
623
|
-
|
|
624
|
-
|
|
643
|
+
openEnvironmentInfo() {
|
|
644
|
+
this.dialog.open(EnvironmentComponent, {
|
|
645
|
+
closeOnNavigation: true,
|
|
646
|
+
});
|
|
625
647
|
}
|
|
626
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type:
|
|
627
|
-
static { this.ɵ
|
|
648
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: ReleaseInfoComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
649
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.1", type: ReleaseInfoComponent, isStandalone: true, selector: "rxap-release-info", ngImport: i0, template: "<div class=\"flex flex-col gap-2 w-full justify-center\">\n <button (click)=\"openEnvironmentInfo()\" mat-button>{{ release }}</button>\n @if (modules.length) {\n <table class=\"table-auto border-separate border-spacing-2 bg-white dark:bg-slate-800 text-sm shadow-sm\">\n <thead class=\"bg-slate-50 dark:bg-slate-700\">\n <th class=\"text-sm border-slate-300 dark:border-slate-600 text-slate-900 dark:text-slate-200 border p-2\">Module</th>\n <th class=\"text-sm border-slate-300 dark:border-slate-600 text-slate-900 dark:text-slate-200 border p-2\">Version</th>\n <th class=\"text-sm border-slate-300 dark:border-slate-600 text-slate-900 dark:text-slate-200 border p-2\">Hash</th>\n </thead>\n <tbody>\n @for (module of modules; track module.name) {\n <tr>\n <th class=\"text-sm border border-slate-300 dark:border-slate-700 text-slate-500 dark:text-slate-400 py-2 px-4\">{{ module.name }}</th>\n <td class=\"text-sm border border-slate-300 dark:border-slate-700 text-slate-500 dark:text-slate-400 p-2\">{{ module.version }}</td>\n <td class=\"text-sm border border-slate-300 dark:border-slate-700 text-slate-500 dark:text-slate-400 p-2\">{{ module.hash }}</td>\n </tr>\n }\n </tbody>\n </table>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "component", type: MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
628
650
|
}
|
|
629
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type:
|
|
630
|
-
type:
|
|
631
|
-
args: [{
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
}], ctorParameters: () => [{ type: ReplaceRouterPathsService }] });
|
|
651
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: ReleaseInfoComponent, decorators: [{
|
|
652
|
+
type: Component,
|
|
653
|
+
args: [{ selector: 'rxap-release-info', standalone: true, imports: [
|
|
654
|
+
MatButton,
|
|
655
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"flex flex-col gap-2 w-full justify-center\">\n <button (click)=\"openEnvironmentInfo()\" mat-button>{{ release }}</button>\n @if (modules.length) {\n <table class=\"table-auto border-separate border-spacing-2 bg-white dark:bg-slate-800 text-sm shadow-sm\">\n <thead class=\"bg-slate-50 dark:bg-slate-700\">\n <th class=\"text-sm border-slate-300 dark:border-slate-600 text-slate-900 dark:text-slate-200 border p-2\">Module</th>\n <th class=\"text-sm border-slate-300 dark:border-slate-600 text-slate-900 dark:text-slate-200 border p-2\">Version</th>\n <th class=\"text-sm border-slate-300 dark:border-slate-600 text-slate-900 dark:text-slate-200 border p-2\">Hash</th>\n </thead>\n <tbody>\n @for (module of modules; track module.name) {\n <tr>\n <th class=\"text-sm border border-slate-300 dark:border-slate-700 text-slate-500 dark:text-slate-400 py-2 px-4\">{{ module.name }}</th>\n <td class=\"text-sm border border-slate-300 dark:border-slate-700 text-slate-500 dark:text-slate-400 p-2\">{{ module.version }}</td>\n <td class=\"text-sm border border-slate-300 dark:border-slate-700 text-slate-500 dark:text-slate-400 p-2\">{{ module.hash }}</td>\n </tr>\n }\n </tbody>\n </table>\n }\n</div>\n" }]
|
|
656
|
+
}] });
|
|
636
657
|
|
|
637
|
-
class
|
|
638
|
-
constructor(
|
|
639
|
-
this.
|
|
640
|
-
this.
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
const mobileQuery = mediaMatcher.matchMedia('(max-width: 959px)');
|
|
644
|
-
const mobile = mobileQuery.matches;
|
|
645
|
-
const initialCollapsable = this.config.get('navigation.collapsable', true);
|
|
646
|
-
const collapsable = initialCollapsable && !mobile;
|
|
647
|
-
const pinned = this.config.get('navigation.pinned', false);
|
|
648
|
-
const mode = this.config.get('navigation.mode', pinned || !collapsable ? 'side' : 'over');
|
|
649
|
-
const opened = this.config.get('navigation.opened', (!collapsable || pinned) && !mobile);
|
|
650
|
-
this.opened = signal(opened);
|
|
651
|
-
this.mode = signal(mode);
|
|
652
|
-
this.pinned = signal(pinned);
|
|
653
|
-
this.collapsable = signal(collapsable);
|
|
654
|
-
this.fixedBottomGap = computed(() => this.footerComponentService.portalCount() * (64 + (this.currentThemeDensity() ?? 0) * 4));
|
|
655
|
-
this.fixedTopGap = computed(() => this.headerComponentService.componentCount() * (64 + (this.currentThemeDensity() ?? 0) * 4));
|
|
656
|
-
this.logo = logoConfig ?? {
|
|
657
|
-
src: 'assets/logo.png',
|
|
658
|
-
width: 192,
|
|
659
|
-
};
|
|
660
|
-
mobileQuery.addEventListener('change', (event) => {
|
|
661
|
-
if (initialCollapsable) {
|
|
662
|
-
this.collapsable.set(!event.matches);
|
|
663
|
-
if (this.collapsable()) {
|
|
664
|
-
if (!this.pinned()) {
|
|
665
|
-
this.opened.set(false);
|
|
666
|
-
}
|
|
667
|
-
}
|
|
668
|
-
}
|
|
669
|
-
});
|
|
670
|
-
effect(() => {
|
|
671
|
-
if (this.pinned()) {
|
|
672
|
-
this.mode.set('side');
|
|
673
|
-
this.opened.set(true);
|
|
674
|
-
}
|
|
675
|
-
else {
|
|
676
|
-
this.mode.set('over');
|
|
677
|
-
this.opened.set(false);
|
|
678
|
-
}
|
|
679
|
-
}, { allowSignalWrites: true });
|
|
680
|
-
}
|
|
681
|
-
toggleOpened() {
|
|
682
|
-
this.opened.set(!this.opened());
|
|
683
|
-
}
|
|
684
|
-
togglePinned() {
|
|
685
|
-
this.pinned.set(!this.pinned());
|
|
658
|
+
class NavigationProgressBarComponent {
|
|
659
|
+
constructor() {
|
|
660
|
+
this.router = inject(Router);
|
|
661
|
+
this.navigating = toSignal(this.router.events.pipe(filter(event => event instanceof NavigationStart ||
|
|
662
|
+
event instanceof NavigationEnd ||
|
|
663
|
+
event instanceof NavigationCancel), map(event => event instanceof NavigationStart)), { initialValue: true });
|
|
686
664
|
}
|
|
687
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type:
|
|
688
|
-
static { this.ɵ
|
|
665
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: NavigationProgressBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
666
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.1", type: NavigationProgressBarComponent, isStandalone: true, selector: "rxap-navigation-progress-bar", ngImport: i0, template: "@if (navigating()) {\n<mat-progress-bar color=\"accent\" mode=\"indeterminate\"></mat-progress-bar>\n}\n", styles: [""], dependencies: [{ kind: "component", type: MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
689
667
|
}
|
|
690
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type:
|
|
691
|
-
type:
|
|
692
|
-
args: [{
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
type: Inject,
|
|
697
|
-
args: [RXAP_LOGO_CONFIG]
|
|
698
|
-
}] }, { type: i1$2.ConfigService, decorators: [{
|
|
699
|
-
type: Inject,
|
|
700
|
-
args: [ConfigService]
|
|
701
|
-
}] }, { type: i2$1.MediaMatcher }] });
|
|
668
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: NavigationProgressBarComponent, decorators: [{
|
|
669
|
+
type: Component,
|
|
670
|
+
args: [{ selector: 'rxap-navigation-progress-bar', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
|
|
671
|
+
MatProgressBar,
|
|
672
|
+
], template: "@if (navigating()) {\n<mat-progress-bar color=\"accent\" mode=\"indeterminate\"></mat-progress-bar>\n}\n" }]
|
|
673
|
+
}] });
|
|
702
674
|
|
|
703
675
|
class FooterComponent {
|
|
704
|
-
constructor(
|
|
705
|
-
this.footerService =
|
|
676
|
+
constructor() {
|
|
677
|
+
this.footerService = inject(FooterService);
|
|
678
|
+
this.portals = computed(() => this.footerService.portals());
|
|
679
|
+
this.hasPortals = computed(() => this.portals().length > 0);
|
|
706
680
|
}
|
|
707
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: FooterComponent, deps: [
|
|
708
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
681
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: FooterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
682
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.1", type: FooterComponent, isStandalone: true, selector: "rxap-footer", ngImport: i0, template: "@if (hasPortals()) {\n <mat-toolbar class=\"mat-elevation-z1\">\n @for (portal of portals(); track portal) {\n <mat-toolbar-row>\n <ng-template [cdkPortalOutlet]=\"portal\"></ng-template>\n </mat-toolbar-row>\n }\n </mat-toolbar>\n}\n", styles: [""], dependencies: [{ kind: "ngmodule", type: MatToolbarModule }, { kind: "component", type: i1$1.MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }, { kind: "directive", type: i1$1.MatToolbarRow, selector: "mat-toolbar-row", exportAs: ["matToolbarRow"] }, { kind: "ngmodule", type: PortalModule }, { kind: "directive", type: i2$1.CdkPortalOutlet, selector: "[cdkPortalOutlet]", inputs: ["cdkPortalOutlet"], outputs: ["attached"], exportAs: ["cdkPortalOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
709
683
|
}
|
|
710
684
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: FooterComponent, decorators: [{
|
|
711
685
|
type: Component,
|
|
712
|
-
args: [{ selector: 'rxap-footer', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
|
|
713
|
-
}]
|
|
686
|
+
args: [{ selector: 'rxap-footer', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [MatToolbarModule, PortalModule], template: "@if (hasPortals()) {\n <mat-toolbar class=\"mat-elevation-z1\">\n @for (portal of portals(); track portal) {\n <mat-toolbar-row>\n <ng-template [cdkPortalOutlet]=\"portal\"></ng-template>\n </mat-toolbar-row>\n }\n </mat-toolbar>\n}\n" }]
|
|
687
|
+
}] });
|
|
714
688
|
|
|
715
|
-
class
|
|
716
|
-
constructor(
|
|
717
|
-
this.
|
|
718
|
-
this.
|
|
719
|
-
this.
|
|
720
|
-
this.
|
|
721
|
-
this._apps = this.config.get('navigation.apps', []);
|
|
689
|
+
class HeaderComponent {
|
|
690
|
+
constructor() {
|
|
691
|
+
this.color = input();
|
|
692
|
+
this.headerService = inject(HeaderService);
|
|
693
|
+
this.portals = computed(() => this.headerService.portals());
|
|
694
|
+
this.hasPortals = computed(() => this.portals().length > 0);
|
|
722
695
|
}
|
|
723
|
-
|
|
724
|
-
|
|
696
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: HeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
697
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.1", type: HeaderComponent, isStandalone: true, selector: "rxap-header", inputs: { color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (hasPortals()) {\n <mat-toolbar [color]=\"color()\" class=\"mat-elevation-z1\">\n @for (portal of portals(); track portal) {\n <mat-toolbar-row>\n <ng-template [cdkPortalOutlet]=\"portal\"></ng-template>\n </mat-toolbar-row>\n }\n </mat-toolbar>\n}\n", styles: [""], dependencies: [{ kind: "component", type: MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }, { kind: "directive", type: MatToolbarRow, selector: "mat-toolbar-row", exportAs: ["matToolbarRow"] }, { kind: "directive", type: CdkPortalOutlet, selector: "[cdkPortalOutlet]", inputs: ["cdkPortalOutlet"], outputs: ["attached"], exportAs: ["cdkPortalOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
698
|
+
}
|
|
699
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: HeaderComponent, decorators: [{
|
|
700
|
+
type: Component,
|
|
701
|
+
args: [{ selector: 'rxap-header', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
|
|
702
|
+
MatToolbar,
|
|
703
|
+
MatToolbarRow,
|
|
704
|
+
CdkPortalOutlet,
|
|
705
|
+
], template: "@if (hasPortals()) {\n <mat-toolbar [color]=\"color()\" class=\"mat-elevation-z1\">\n @for (portal of portals(); track portal) {\n <mat-toolbar-row>\n <ng-template [cdkPortalOutlet]=\"portal\"></ng-template>\n </mat-toolbar-row>\n }\n </mat-toolbar>\n}\n" }]
|
|
706
|
+
}] });
|
|
707
|
+
|
|
708
|
+
class BaseLayoutComponent {
|
|
709
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: BaseLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
710
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.0.1", type: BaseLayoutComponent, isStandalone: true, selector: "rxap-base-layout", ngImport: i0, template: "<div class=\"flex flex-col h-screen justify-between\">\n <rxap-header class=\"z-10 w-full fixed top-0\"></rxap-header>\n <ng-content></ng-content>\n <rxap-footer class=\"z-10 w-full fixed bottom-0\"></rxap-footer>\n</div>\n", styles: [""], dependencies: [{ kind: "component", type: HeaderComponent, selector: "rxap-header", inputs: ["color"] }, { kind: "component", type: FooterComponent, selector: "rxap-footer" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
711
|
+
}
|
|
712
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: BaseLayoutComponent, decorators: [{
|
|
713
|
+
type: Component,
|
|
714
|
+
args: [{ selector: 'rxap-base-layout', standalone: true, imports: [
|
|
715
|
+
HeaderComponent,
|
|
716
|
+
FooterComponent,
|
|
717
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"flex flex-col h-screen justify-between\">\n <rxap-header class=\"z-10 w-full fixed top-0\"></rxap-header>\n <ng-content></ng-content>\n <rxap-footer class=\"z-10 w-full fixed bottom-0\"></rxap-footer>\n</div>\n" }]
|
|
718
|
+
}] });
|
|
719
|
+
|
|
720
|
+
class MinimalLayoutComponent {
|
|
721
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: MinimalLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
722
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.0.1", type: MinimalLayoutComponent, isStandalone: true, selector: "rxap-minimal-layout", ngImport: i0, template: "<rxap-base-layout>\n <rxap-navigation-progress-bar></rxap-navigation-progress-bar>\n <router-outlet></router-outlet>\n</rxap-base-layout>\n", styles: [""], dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "component", type: BaseLayoutComponent, selector: "rxap-base-layout" }, { kind: "component", type: NavigationProgressBarComponent, selector: "rxap-navigation-progress-bar" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
723
|
+
}
|
|
724
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: MinimalLayoutComponent, decorators: [{
|
|
725
|
+
type: Component,
|
|
726
|
+
args: [{ selector: 'rxap-minimal-layout', standalone: true, imports: [RouterOutlet, BaseLayoutComponent, NavigationProgressBarComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<rxap-base-layout>\n <rxap-navigation-progress-bar></rxap-navigation-progress-bar>\n <router-outlet></router-outlet>\n</rxap-base-layout>\n" }]
|
|
727
|
+
}] });
|
|
728
|
+
|
|
729
|
+
class LogoService {
|
|
730
|
+
constructor() {
|
|
731
|
+
this.config = inject(ConfigService);
|
|
732
|
+
this.logo = signal(inject(RXAP_LOGO_CONFIG, { optional: true }) ??
|
|
733
|
+
this.config.get('logo', {
|
|
734
|
+
src: 'logo.png',
|
|
735
|
+
width: 192,
|
|
736
|
+
}));
|
|
737
|
+
this.src = computed(() => this.logo().src);
|
|
738
|
+
this.width = computed(() => this.logo().width);
|
|
739
|
+
this.height = computed(() => this.logo().height);
|
|
740
|
+
}
|
|
741
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: LogoService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
742
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: LogoService }); }
|
|
743
|
+
}
|
|
744
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: LogoService, decorators: [{
|
|
745
|
+
type: Injectable
|
|
746
|
+
}] });
|
|
747
|
+
|
|
748
|
+
class LayoutComponent {
|
|
749
|
+
constructor() {
|
|
750
|
+
this.userSettingsThemeService = inject(UserSettingsThemeService);
|
|
751
|
+
this.themeService = inject(ThemeService);
|
|
752
|
+
this.logoService = inject(LogoService);
|
|
753
|
+
this.logoSrc = computed(() => this.logoService.src());
|
|
754
|
+
this.logoWidth = computed(() => this.logoService.width());
|
|
755
|
+
this.logoHeight = computed(() => this.logoService.height());
|
|
725
756
|
}
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
if (app) {
|
|
729
|
-
return JoinPath(app.href, infix, path);
|
|
730
|
-
}
|
|
731
|
-
return null;
|
|
757
|
+
ngOnDestroy() {
|
|
758
|
+
this.userSettingsThemeService.stopSync();
|
|
732
759
|
}
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
760
|
+
ngOnInit() {
|
|
761
|
+
this.userSettingsThemeService.startSync().then(() => {
|
|
762
|
+
this.userSettingsThemeService.get().then(theme => {
|
|
763
|
+
if (theme.preset && theme.preset !== 'default') {
|
|
764
|
+
this.themeService.setTheme(theme.preset, true);
|
|
765
|
+
}
|
|
766
|
+
if (theme.density && IsThemeDensity(theme.density) && theme.density !== ThemeDensity.Normal) {
|
|
767
|
+
this.themeService.setDensity(theme.density, true);
|
|
768
|
+
}
|
|
769
|
+
if (theme.typography && theme.typography !== 'default') {
|
|
770
|
+
this.themeService.setTypography(theme.typography, true);
|
|
771
|
+
}
|
|
772
|
+
});
|
|
773
|
+
});
|
|
739
774
|
}
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
775
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: LayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
776
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.0.1", type: LayoutComponent, isStandalone: true, selector: "rxap-layout", ngImport: i0, template: "<rxap-header class=\"z-10 w-full fixed top-0\"></rxap-header>\n<rxap-navigation-progress-bar></rxap-navigation-progress-bar>\n<rxap-sidenav>\n <router-outlet></router-outlet>\n <ng-template rxapSidenavFooter>\n <img\n [src]=\"logoSrc()\"\n [routerLink]=\"['/']\"\n [width]=\"logoWidth()\"\n [height]=\"logoHeight()\"\n alt=\"logo\"\n class=\"grow-0 mx-16 cursor-pointer\"\n />\n <div class=\"grow-0 px-16 mt-4\">\n <rxap-release-info></rxap-release-info>\n </div>\n </ng-template>\n</rxap-sidenav>\n<rxap-footer class=\"z-10 w-full fixed bottom-0\"></rxap-footer>\n", styles: [":host .collapsable:not(.mat-drawer-opened){transform:translate(calc(-100% + 64px))!important;visibility:visible!important;box-shadow:inherit!important;transition-property:transform;transition-delay:.25s;display:flex;border-right:solid 1px rgba(0,0,0,.12)}:host .collapsable ::ng-deep .mat-drawer-inner-container::-webkit-scrollbar{display:none}\n"], dependencies: [{ kind: "component", type: HeaderComponent, selector: "rxap-header", inputs: ["color"] }, { kind: "ngmodule", type: MatSidenavModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "ngmodule", type: MatButtonModule }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: FooterComponent, selector: "rxap-footer" }, { kind: "ngmodule", type: MatMenuModule }, { kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "component", type: SidenavComponent, selector: "rxap-sidenav" }, { kind: "component", type: ReleaseInfoComponent, selector: "rxap-release-info" }, { kind: "directive", type: SidenavFooterDirective, selector: "[rxapSidenavFooter]" }, { kind: "component", type: NavigationProgressBarComponent, selector: "rxap-navigation-progress-bar" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
777
|
+
}
|
|
778
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: LayoutComponent, decorators: [{
|
|
779
|
+
type: Component,
|
|
780
|
+
args: [{ selector: 'rxap-layout', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
|
|
781
|
+
HeaderComponent,
|
|
782
|
+
MatSidenavModule,
|
|
783
|
+
AsyncPipe,
|
|
784
|
+
MatIconModule,
|
|
785
|
+
MatButtonModule,
|
|
786
|
+
RouterLink,
|
|
787
|
+
NgIf,
|
|
788
|
+
FooterComponent,
|
|
789
|
+
MatMenuModule,
|
|
790
|
+
NgOptimizedImage,
|
|
791
|
+
NavigationComponent,
|
|
792
|
+
RouterOutlet,
|
|
793
|
+
NgStyle,
|
|
794
|
+
NgClass,
|
|
795
|
+
SidenavComponent,
|
|
796
|
+
ReleaseInfoComponent,
|
|
797
|
+
SidenavFooterDirective,
|
|
798
|
+
NavigationProgressBarComponent,
|
|
799
|
+
], template: "<rxap-header class=\"z-10 w-full fixed top-0\"></rxap-header>\n<rxap-navigation-progress-bar></rxap-navigation-progress-bar>\n<rxap-sidenav>\n <router-outlet></router-outlet>\n <ng-template rxapSidenavFooter>\n <img\n [src]=\"logoSrc()\"\n [routerLink]=\"['/']\"\n [width]=\"logoWidth()\"\n [height]=\"logoHeight()\"\n alt=\"logo\"\n class=\"grow-0 mx-16 cursor-pointer\"\n />\n <div class=\"grow-0 px-16 mt-4\">\n <rxap-release-info></rxap-release-info>\n </div>\n </ng-template>\n</rxap-sidenav>\n<rxap-footer class=\"z-10 w-full fixed bottom-0\"></rxap-footer>\n", styles: [":host .collapsable:not(.mat-drawer-opened){transform:translate(calc(-100% + 64px))!important;visibility:visible!important;box-shadow:inherit!important;transition-property:transform;transition-delay:.25s;display:flex;border-right:solid 1px rgba(0,0,0,.12)}:host .collapsable ::ng-deep .mat-drawer-inner-container::-webkit-scrollbar{display:none}\n"] }]
|
|
800
|
+
}] });
|
|
801
|
+
|
|
802
|
+
class HeaderDirective {
|
|
803
|
+
constructor() {
|
|
804
|
+
this.headerService = inject(HeaderService);
|
|
805
|
+
this.template = inject(TemplateRef);
|
|
806
|
+
this.viewContainerRef = inject(ViewContainerRef);
|
|
745
807
|
}
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
.filter(app => !app.hidden)
|
|
750
|
-
.map(app => ({
|
|
751
|
-
...app,
|
|
752
|
-
href: JoinPath(app.href, this.getPathPrefix()),
|
|
753
|
-
}));
|
|
754
|
-
const filteredAppList = [];
|
|
755
|
-
for (const app of appList) {
|
|
756
|
-
if (await firstValueFrom(this.authorizationService.hasPermission$(app.permissions))) {
|
|
757
|
-
filteredAppList.push(app);
|
|
758
|
-
}
|
|
759
|
-
}
|
|
760
|
-
return filteredAppList;
|
|
808
|
+
ngOnInit() {
|
|
809
|
+
this._portal = new TemplatePortal(this.template, this.viewContainerRef);
|
|
810
|
+
this.headerService.pushPortal(this._portal);
|
|
761
811
|
}
|
|
762
|
-
|
|
763
|
-
if (this.
|
|
764
|
-
|
|
812
|
+
ngOnDestroy() {
|
|
813
|
+
if (this._portal) {
|
|
814
|
+
this.headerService.removePortal(this._portal);
|
|
765
815
|
}
|
|
766
|
-
return '';
|
|
767
816
|
}
|
|
768
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type:
|
|
769
|
-
static { this.ɵ
|
|
817
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: HeaderDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
818
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.0.1", type: HeaderDirective, isStandalone: true, selector: "[rxapHeader]", ngImport: i0 }); }
|
|
770
819
|
}
|
|
771
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type:
|
|
772
|
-
type:
|
|
773
|
-
args: [{
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
type: Inject,
|
|
779
|
-
args: [RXAP_ENVIRONMENT]
|
|
780
|
-
}] }] });
|
|
820
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: HeaderDirective, decorators: [{
|
|
821
|
+
type: Directive,
|
|
822
|
+
args: [{
|
|
823
|
+
selector: '[rxapHeader]',
|
|
824
|
+
standalone: true,
|
|
825
|
+
}]
|
|
826
|
+
}] });
|
|
781
827
|
|
|
782
|
-
class
|
|
783
|
-
constructor(
|
|
784
|
-
this.
|
|
785
|
-
this.
|
|
786
|
-
this.
|
|
787
|
-
this.appList = signal([]);
|
|
828
|
+
class FooterDirective {
|
|
829
|
+
constructor() {
|
|
830
|
+
this.footerService = inject(FooterService);
|
|
831
|
+
this.template = inject(TemplateRef);
|
|
832
|
+
this.viewContainerRef = inject(ViewContainerRef);
|
|
788
833
|
}
|
|
789
834
|
ngOnInit() {
|
|
790
|
-
this.
|
|
835
|
+
this._portal = new TemplatePortal(this.template, this.viewContainerRef);
|
|
836
|
+
this.footerService.pushPortal(this._portal);
|
|
791
837
|
}
|
|
792
838
|
ngOnDestroy() {
|
|
793
|
-
this.
|
|
839
|
+
if (this._portal) {
|
|
840
|
+
this.footerService.removePortal(this._portal);
|
|
841
|
+
}
|
|
794
842
|
}
|
|
795
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type:
|
|
796
|
-
static { this.ɵ
|
|
843
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: FooterDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
844
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.0.1", type: FooterDirective, isStandalone: true, selector: "[rxapFooter]", ngImport: i0 }); }
|
|
797
845
|
}
|
|
798
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type:
|
|
799
|
-
type:
|
|
800
|
-
args: [{
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
NgOptimizedImage,
|
|
806
|
-
], template: "<div *ngIf=\"appList()?.length\" class=\"flex flex-row items-center gap-8\">\n\n <div *ngIf=\"isOpen\" class=\"flex flex-row items-center gap-6\">\n\n <div *ngFor=\"let app of appList()\" class=\"h-10\">\n <a [href]=\"app.href\" mat-stroked-button>\n <span class=\"flex flex-row items-center gap-4\">\n <img *ngIf=\"app.image\" [alt]=\"app.label\" [ngSrc]=\"app.image\" height=\"40\" width=\"40\">\n <span class=\"label grow-0\">{{app.label}}</span>\n </span>\n </a>\n </div>\n\n </div>\n\n <button (click)=\"isOpen = !isOpen\" mat-icon-button>\n <mat-icon svgIcon=\"apps\"></mat-icon>\n </button>\n\n</div>\n" }]
|
|
807
|
-
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
808
|
-
type: Optional
|
|
809
|
-
}, {
|
|
810
|
-
type: Inject,
|
|
811
|
-
args: [RXAP_LAYOUT_APPS_GRID]
|
|
812
|
-
}] }, { type: AppUrlService }, { type: i2$4.RxapAuthenticationService }] });
|
|
846
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: FooterDirective, decorators: [{
|
|
847
|
+
type: Directive,
|
|
848
|
+
args: [{
|
|
849
|
+
selector: '[rxapFooter]',
|
|
850
|
+
standalone: true,
|
|
851
|
+
}]
|
|
852
|
+
}] });
|
|
813
853
|
|
|
814
|
-
class
|
|
815
|
-
constructor(
|
|
816
|
-
this.
|
|
817
|
-
this.
|
|
818
|
-
|
|
819
|
-
|
|
854
|
+
class UserProfileIconComponent {
|
|
855
|
+
constructor() {
|
|
856
|
+
this.extractUsernameFromProfile = inject(EXTRACT_USERNAME_FROM_PROFILE);
|
|
857
|
+
this.pubSubService = inject(PubSubService);
|
|
858
|
+
this.profile = input.required();
|
|
859
|
+
this.username = computed(() => {
|
|
860
|
+
const profile = this.profile();
|
|
861
|
+
if (profile) {
|
|
862
|
+
return this.extractUsernameFromProfile(profile);
|
|
863
|
+
}
|
|
864
|
+
return null;
|
|
865
|
+
});
|
|
866
|
+
}
|
|
867
|
+
logout() {
|
|
868
|
+
this.pubSubService.publish('authentication.logout');
|
|
820
869
|
}
|
|
821
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type:
|
|
822
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
870
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: UserProfileIconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
871
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.1", type: UserProfileIconComponent, isStandalone: true, selector: "rxap-user-profile-icon", inputs: { profile: { classPropertyName: "profile", publicName: "profile", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<button [matMenuTriggerFor]=\"menu\"\n class=\"rounded-full cursor-pointer outline-none overflow-hidden h-8 w-8 bg-center bg-no-repeat bg-cover flex flex-row justify-center items-center\">\n <mat-icon class=\"h-8 w-8 text-[32px]\" svgIcon=\"account-circle\"></mat-icon>\n</button>\n\n<mat-menu #menu=\"matMenu\" [yPosition]=\"'below'\" class=\"!max-w-none\">\n @if (this.username(); as username) {\n <button mat-menu-item>\n <span class=\"flex flex-row gap-2\">\n <mat-icon svgIcon=\"account\"></mat-icon>\n <span>{{username}}</span>\n </span>\n </button>\n }\n <button (click)=\"logout()\" mat-menu-item>\n <span class=\"flex flex-row gap-2\">\n <mat-icon svgIcon=\"logout\"></mat-icon>\n <span i18n>Logout</span>\n </span>\n </button>\n</mat-menu>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i1$2.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i1$2.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i1$2.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
823
872
|
}
|
|
824
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type:
|
|
873
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: UserProfileIconComponent, decorators: [{
|
|
825
874
|
type: Component,
|
|
826
|
-
args: [{ selector: 'rxap-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
}], ctorParameters: () => [{ type: i2.Router, decorators: [{
|
|
832
|
-
type: Inject,
|
|
833
|
-
args: [Router]
|
|
834
|
-
}] }] });
|
|
875
|
+
args: [{ selector: 'rxap-user-profile-icon', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
|
|
876
|
+
MatMenuModule,
|
|
877
|
+
MatIconModule,
|
|
878
|
+
], template: "<button [matMenuTriggerFor]=\"menu\"\n class=\"rounded-full cursor-pointer outline-none overflow-hidden h-8 w-8 bg-center bg-no-repeat bg-cover flex flex-row justify-center items-center\">\n <mat-icon class=\"h-8 w-8 text-[32px]\" svgIcon=\"account-circle\"></mat-icon>\n</button>\n\n<mat-menu #menu=\"matMenu\" [yPosition]=\"'below'\" class=\"!max-w-none\">\n @if (this.username(); as username) {\n <button mat-menu-item>\n <span class=\"flex flex-row gap-2\">\n <mat-icon svgIcon=\"account\"></mat-icon>\n <span>{{username}}</span>\n </span>\n </button>\n }\n <button (click)=\"logout()\" mat-menu-item>\n <span class=\"flex flex-row gap-2\">\n <mat-icon svgIcon=\"logout\"></mat-icon>\n <span i18n>Logout</span>\n </span>\n </button>\n</mat-menu>\n" }]
|
|
879
|
+
}] });
|
|
835
880
|
|
|
836
|
-
class
|
|
837
|
-
constructor(
|
|
838
|
-
this.
|
|
881
|
+
class SidenavToggleButtonComponent {
|
|
882
|
+
constructor() {
|
|
883
|
+
this.layoutComponentService = inject(LayoutService);
|
|
884
|
+
this.opened = computed(() => this.layoutComponentService.opened());
|
|
885
|
+
}
|
|
886
|
+
toggle() {
|
|
887
|
+
this.layoutComponentService.toggleOpened();
|
|
839
888
|
}
|
|
840
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type:
|
|
841
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
889
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: SidenavToggleButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
890
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.1", type: SidenavToggleButtonComponent, isStandalone: true, selector: "rxap-sidenav-toggle-button", ngImport: i0, template: "<button (click)=\"toggle()\" mat-icon-button>\n @if (opened()) {\n <mat-icon>menu_open</mat-icon>\n } @else {\n <mat-icon>menu</mat-icon>\n }\n</button>\n", styles: [""], dependencies: [{ kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
842
891
|
}
|
|
843
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type:
|
|
892
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: SidenavToggleButtonComponent, decorators: [{
|
|
844
893
|
type: Component,
|
|
845
|
-
args: [{ selector: 'rxap-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
FormsModule,
|
|
851
|
-
NgFor,
|
|
852
|
-
MatOptionModule,
|
|
853
|
-
KeyValuePipe,
|
|
854
|
-
], template: "<ng-template [ngIf]=\"(language.languages | keyvalue).length\">\n <div>\n <mat-form-field appearance=\"outline\" class=\"language-selector\" rxapStopPropagation>\n <mat-label i18n>Select Language</mat-label>\n <mat-select (ngModelChange)=\"language.setLanguage($event)\" [ngModel]=\"language.selectedLanguage\">\n <mat-option *ngFor=\"let item of language.languages | keyvalue\" [value]=\"item.key\">{{item.value}}</mat-option>\n </mat-select>\n </mat-form-field>\n </div>\n</ng-template>\n", styles: [".language-selector{width:calc(100% - 32px);margin:0 16px}.language-selector ::ng-deep .mat-form-field-wrapper{padding-bottom:0}.language-selector ::ng-deep .mat-form-field-wrapper .mat-form-field-infix{padding:12px 0;border-width:6px}.language-selector ::ng-deep .mat-form-field-wrapper .mat-form-field-infix .mat-select-arrow-wrapper{transform:translateY(0)}\n"] }]
|
|
855
|
-
}], ctorParameters: () => [{ type: i1$5.LanguageSelectorService }] });
|
|
894
|
+
args: [{ selector: 'rxap-sidenav-toggle-button', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
|
|
895
|
+
MatIcon,
|
|
896
|
+
MatIconButton,
|
|
897
|
+
], template: "<button (click)=\"toggle()\" mat-icon-button>\n @if (opened()) {\n <mat-icon>menu_open</mat-icon>\n } @else {\n <mat-icon>menu</mat-icon>\n }\n</button>\n" }]
|
|
898
|
+
}] });
|
|
856
899
|
|
|
857
900
|
class SettingsButtonComponent {
|
|
858
|
-
constructor(
|
|
859
|
-
this.theme = theme;
|
|
860
|
-
this.route = route;
|
|
861
|
-
this.injector = injector;
|
|
862
|
-
this.changelogService = changelogService;
|
|
901
|
+
constructor() {
|
|
863
902
|
this.isDevMode = isDevMode();
|
|
864
|
-
this.
|
|
903
|
+
this.theme = inject(ThemeService);
|
|
904
|
+
this.injector = inject(Injector);
|
|
905
|
+
this.customItemComponents = signal(coerceArray(inject(RXAP_SETTINGS_MENU_ITEM_COMPONENT, { optional: true }))
|
|
906
|
+
.map(item => new ComponentPortal(item, null, this.injector)));
|
|
907
|
+
this.customItems = signal(coerceArray(inject(RXAP_SETTINGS_MENU_ITEM, { optional: true })));
|
|
865
908
|
this.savePreviewDensityValue = false;
|
|
866
909
|
this.currentDensityValue = null;
|
|
867
910
|
this.savePreviewTypographyValue = false;
|
|
868
911
|
this.currentTypographyValue = null;
|
|
912
|
+
this.availableTypographies = this.theme.getAvailableTypographies();
|
|
869
913
|
this.savePreviewThemeValue = false;
|
|
870
|
-
this.currentThemeValue = null;
|
|
871
914
|
this.availableThemes = this.theme.getAvailableThemes();
|
|
872
|
-
this.
|
|
873
|
-
}
|
|
874
|
-
ngOnDestroy() {
|
|
875
|
-
this._subscription?.unsubscribe();
|
|
876
|
-
}
|
|
877
|
-
ngOnInit() {
|
|
878
|
-
this._subscription = this.route.data.pipe(map(data => this.getCustomMenuItems(data)), map(items => items.map(item => new ComponentPortal(item, undefined, this.injector))), tap(items => this.items.set(items))).subscribe();
|
|
879
|
-
}
|
|
880
|
-
getCustomMenuItems(data) {
|
|
881
|
-
if (data?.layout?.header?.menu?.items?.length) {
|
|
882
|
-
return data.layout.header.menu.items;
|
|
883
|
-
}
|
|
884
|
-
return [];
|
|
885
|
-
}
|
|
886
|
-
openChangelogDialog() {
|
|
887
|
-
this.changelogService.showChangelogDialog();
|
|
915
|
+
this.currentThemeValue = null;
|
|
888
916
|
}
|
|
889
917
|
previewDensity(density) {
|
|
890
918
|
this.theme.applyDensity(density);
|
|
@@ -913,255 +941,239 @@ class SettingsButtonComponent {
|
|
|
913
941
|
setTheme(theme) {
|
|
914
942
|
this.theme.setTheme(theme);
|
|
915
943
|
}
|
|
916
|
-
|
|
917
|
-
|
|
944
|
+
clickItem(item) {
|
|
945
|
+
runInInjectionContext(this.injector, () => item.action());
|
|
946
|
+
}
|
|
947
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: SettingsButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
948
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.1", type: SettingsButtonComponent, isStandalone: true, selector: "rxap-settings-button", ngImport: i0, template: "<button [matMenuTriggerFor]=\"menu\" mat-icon-button>\n <mat-icon svgIcon=\"cog\"></mat-icon>\n</button>\n\n<mat-menu #menu=\"matMenu\">\n <button (click)=\"theme.toggleDarkTheme()\" mat-menu-item>\n @if (theme.darkMode()) {\n <mat-icon svgIcon=\"brightness-2\"></mat-icon>\n } @else {\n <mat-icon svgIcon=\"brightness-5\"></mat-icon>\n }\n <span i18n>Mode</span>\n </button>\n <button [matMenuTriggerFor]=\"themeMenu\" mat-menu-item>\n <mat-icon svgIcon=\"compare\"></mat-icon>\n <span i18n>Theme</span>\n </button>\n @for (item of customItems(); track item.label) {\n <button (click)=\"clickItem(item)\" mat-menu-item>\n <mat-icon [rxapIcon]=\"item.icon\"></mat-icon>\n <span>{{ item.label }}</span>\n </button>\n }\n @for (item of customItemComponents(); track item) {\n <ng-template [cdkPortalOutlet]=\"item\"></ng-template>\n }\n</mat-menu>\n\n<mat-menu #themeMenu=\"matMenu\" xPosition=\"before\">\n <button [matMenuTriggerFor]=\"themeDensityMenu\" mat-menu-item>\n <mat-icon svgIcon=\"move-resize\"></mat-icon>\n <span i18n>Density</span>\n </button>\n @if (availableTypographies?.length) {\n <button [matMenuTriggerFor]=\"themeFontMenu\" mat-menu-item>\n <mat-icon svgIcon=\"format-font\"></mat-icon>\n <span i18n>Font</span>\n </button>\n }\n @if (availableThemes?.length) {\n <button [matMenuTriggerFor]=\"themePresetMenu\" mat-menu-item>\n <mat-icon svgIcon=\"shape-outline\"></mat-icon>\n <span i18n>Preset</span>\n </button>\n }\n</mat-menu>\n\n<mat-menu #themeDensityMenu=\"matMenu\" xPosition=\"before\">\n <button (click)=\"setDensity(0)\" (mouseenter)=\"previewDensity(0)\" (mouseleave)=\"restoreDensity()\" mat-menu-item>\n <mat-icon svgIcon=\"size-l\"></mat-icon>\n <span i18n>Normal</span>\n </button>\n <button (click)=\"setDensity(-1)\" (mouseenter)=\"previewDensity(-1)\" (mouseleave)=\"restoreDensity()\" mat-menu-item>\n <mat-icon svgIcon=\"size-m\"></mat-icon>\n <span i18n>Dense</span>\n </button>\n <button (click)=\"setDensity(-2)\" (mouseenter)=\"previewDensity(-2)\" (mouseleave)=\"restoreDensity()\" mat-menu-item>\n <mat-icon svgIcon=\"size-s\"></mat-icon>\n <span i18n>Very Dense</span>\n </button>\n <button (click)=\"setDensity(-3)\" (mouseenter)=\"previewDensity(-3)\" (mouseleave)=\"restoreDensity()\" mat-menu-item>\n <mat-icon svgIcon=\"size-xs\"></mat-icon>\n <span i18n>Extreme Dense</span>\n </button>\n</mat-menu>\n<mat-menu #themeFontMenu=\"matMenu\" xPosition=\"before\">\n @for (typographyName of availableTypographies ?? []; track typographyName) {\n <button (click)=\"setTypography(typographyName)\"\n (mouseenter)=\"previewTypography(typographyName)\"\n (mouseleave)=\"restoreTypography()\"\n mat-menu-item>\n {{ typographyName }}\n </button>\n }\n</mat-menu>\n\n<mat-menu #themePresetMenu=\"matMenu\" xPosition=\"before\">\n @for (themeName of availableThemes ?? []; track themeName) {\n <button (click)=\"setTheme(themeName)\"\n (mouseenter)=\"previewTheme(themeName)\"\n (mouseleave)=\"restoreTheme()\"\n mat-menu-item>\n {{ themeName }}\n </button>\n }\n</mat-menu>\n", styles: [""], dependencies: [{ kind: "component", type: MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "directive", type: MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: CdkPortalOutlet, selector: "[cdkPortalOutlet]", inputs: ["cdkPortalOutlet"], outputs: ["attached"], exportAs: ["cdkPortalOutlet"] }, { kind: "directive", type: IconDirective, selector: "mat-icon[rxapIcon]", inputs: ["rxapIcon"] }] }); }
|
|
918
949
|
}
|
|
919
950
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: SettingsButtonComponent, decorators: [{
|
|
920
951
|
type: Component,
|
|
921
|
-
args: [{ selector: 'rxap-settings-button', standalone: true, imports: [
|
|
922
|
-
|
|
952
|
+
args: [{ selector: 'rxap-settings-button', standalone: true, imports: [
|
|
953
|
+
MatIconButton,
|
|
954
|
+
MatIcon,
|
|
955
|
+
MatMenu,
|
|
956
|
+
MatMenuTrigger,
|
|
957
|
+
MatMenuItem,
|
|
958
|
+
CdkPortalOutlet,
|
|
959
|
+
IconDirective,
|
|
960
|
+
], template: "<button [matMenuTriggerFor]=\"menu\" mat-icon-button>\n <mat-icon svgIcon=\"cog\"></mat-icon>\n</button>\n\n<mat-menu #menu=\"matMenu\">\n <button (click)=\"theme.toggleDarkTheme()\" mat-menu-item>\n @if (theme.darkMode()) {\n <mat-icon svgIcon=\"brightness-2\"></mat-icon>\n } @else {\n <mat-icon svgIcon=\"brightness-5\"></mat-icon>\n }\n <span i18n>Mode</span>\n </button>\n <button [matMenuTriggerFor]=\"themeMenu\" mat-menu-item>\n <mat-icon svgIcon=\"compare\"></mat-icon>\n <span i18n>Theme</span>\n </button>\n @for (item of customItems(); track item.label) {\n <button (click)=\"clickItem(item)\" mat-menu-item>\n <mat-icon [rxapIcon]=\"item.icon\"></mat-icon>\n <span>{{ item.label }}</span>\n </button>\n }\n @for (item of customItemComponents(); track item) {\n <ng-template [cdkPortalOutlet]=\"item\"></ng-template>\n }\n</mat-menu>\n\n<mat-menu #themeMenu=\"matMenu\" xPosition=\"before\">\n <button [matMenuTriggerFor]=\"themeDensityMenu\" mat-menu-item>\n <mat-icon svgIcon=\"move-resize\"></mat-icon>\n <span i18n>Density</span>\n </button>\n @if (availableTypographies?.length) {\n <button [matMenuTriggerFor]=\"themeFontMenu\" mat-menu-item>\n <mat-icon svgIcon=\"format-font\"></mat-icon>\n <span i18n>Font</span>\n </button>\n }\n @if (availableThemes?.length) {\n <button [matMenuTriggerFor]=\"themePresetMenu\" mat-menu-item>\n <mat-icon svgIcon=\"shape-outline\"></mat-icon>\n <span i18n>Preset</span>\n </button>\n }\n</mat-menu>\n\n<mat-menu #themeDensityMenu=\"matMenu\" xPosition=\"before\">\n <button (click)=\"setDensity(0)\" (mouseenter)=\"previewDensity(0)\" (mouseleave)=\"restoreDensity()\" mat-menu-item>\n <mat-icon svgIcon=\"size-l\"></mat-icon>\n <span i18n>Normal</span>\n </button>\n <button (click)=\"setDensity(-1)\" (mouseenter)=\"previewDensity(-1)\" (mouseleave)=\"restoreDensity()\" mat-menu-item>\n <mat-icon svgIcon=\"size-m\"></mat-icon>\n <span i18n>Dense</span>\n </button>\n <button (click)=\"setDensity(-2)\" (mouseenter)=\"previewDensity(-2)\" (mouseleave)=\"restoreDensity()\" mat-menu-item>\n <mat-icon svgIcon=\"size-s\"></mat-icon>\n <span i18n>Very Dense</span>\n </button>\n <button (click)=\"setDensity(-3)\" (mouseenter)=\"previewDensity(-3)\" (mouseleave)=\"restoreDensity()\" mat-menu-item>\n <mat-icon svgIcon=\"size-xs\"></mat-icon>\n <span i18n>Extreme Dense</span>\n </button>\n</mat-menu>\n<mat-menu #themeFontMenu=\"matMenu\" xPosition=\"before\">\n @for (typographyName of availableTypographies ?? []; track typographyName) {\n <button (click)=\"setTypography(typographyName)\"\n (mouseenter)=\"previewTypography(typographyName)\"\n (mouseleave)=\"restoreTypography()\"\n mat-menu-item>\n {{ typographyName }}\n </button>\n }\n</mat-menu>\n\n<mat-menu #themePresetMenu=\"matMenu\" xPosition=\"before\">\n @for (themeName of availableThemes ?? []; track themeName) {\n <button (click)=\"setTheme(themeName)\"\n (mouseenter)=\"previewTheme(themeName)\"\n (mouseleave)=\"restoreTheme()\"\n mat-menu-item>\n {{ themeName }}\n </button>\n }\n</mat-menu>\n" }]
|
|
961
|
+
}] });
|
|
923
962
|
|
|
924
|
-
class
|
|
925
|
-
constructor(
|
|
926
|
-
this.
|
|
927
|
-
this.
|
|
963
|
+
class ExternalAppsService {
|
|
964
|
+
constructor() {
|
|
965
|
+
this.appFilterList = coerceArray(inject(RXAP_EXTERNAL_APP_FILTER, { optional: true }));
|
|
966
|
+
this.config = inject(ConfigService);
|
|
967
|
+
this.localeId = inject(LOCALE_ID);
|
|
968
|
+
this.environment = inject(RXAP_ENVIRONMENT);
|
|
969
|
+
this.apps = this.config.get('navigation.apps', []);
|
|
970
|
+
/**
|
|
971
|
+
* The list of active apps that is processed by the getAppList method
|
|
972
|
+
*/
|
|
973
|
+
this.activeAppList = signal([]);
|
|
974
|
+
}
|
|
975
|
+
hasApp(appId) {
|
|
976
|
+
return this.apps.some(app => app.id === appId);
|
|
928
977
|
}
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
], template: "<button (click)=\"layoutComponentService.toggleOpened()\" mat-icon-button>\n <mat-icon *ngIf=\"!opened()\">menu</mat-icon>\n <mat-icon *ngIf=\"opened()\">menu_open</mat-icon>\n</button>\n" }]
|
|
939
|
-
}], ctorParameters: () => [{ type: LayoutComponentService }] });
|
|
940
|
-
|
|
941
|
-
const EXTRACT_USERNAME_FROM_PROFILE = new InjectionToken('extract-username-from-profile', {
|
|
942
|
-
providedIn: 'root',
|
|
943
|
-
factory: () => (profile) => (profile ? profile.username ?? profile.email ?? profile.name : null) ?? null,
|
|
944
|
-
});
|
|
945
|
-
class UserProfileIconComponent {
|
|
946
|
-
constructor(userProfileService, authenticationService, extractUsernameFromProfile) {
|
|
947
|
-
this.userProfileService = userProfileService;
|
|
948
|
-
this.authenticationService = authenticationService;
|
|
949
|
-
this.username = toSignal(this.authenticationService.isAuthenticated$.pipe(filter$1(Boolean), switchMap(() => this.userProfileService.connect({
|
|
950
|
-
viewChange: this.authenticationService.isAuthenticated$.pipe(skip(1), filter$1(Boolean), distinctUntilChanged()),
|
|
951
|
-
})), filter$1(Boolean), map(extractUsernameFromProfile)), { initialValue: null });
|
|
952
|
-
}
|
|
953
|
-
async logout() {
|
|
954
|
-
await this.authenticationService.signOut();
|
|
955
|
-
}
|
|
956
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: UserProfileIconComponent, deps: [{ token: i1$7.UserProfileDataSource }, { token: i2$4.RxapAuthenticationService }, { token: EXTRACT_USERNAME_FROM_PROFILE }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
957
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.0.1", type: UserProfileIconComponent, isStandalone: true, selector: "rxap-user-profile-icon", ngImport: i0, template: "<button [matMenuTriggerFor]=\"menu\"\n [disabled]=\"!username()\"\n class=\"profile-icon flex flex-row justify-center items-center\">\n <mat-icon class=\"avatar-icon\" svgIcon=\"account-circle\"></mat-icon>\n</button>\n\n<mat-menu #menu=\"matMenu\" [yPosition]=\"'below'\" class=\"!max-w-none\">\n <button mat-menu-item>\n <span class=\"flex flex-row gap-2\">\n <mat-icon svgIcon=\"account\"></mat-icon>\n <span>{{username()}}</span>\n </span>\n </button>\n <button (click)=\"logout()\" mat-menu-item>\n <span class=\"flex flex-row gap-2\">\n <mat-icon svgIcon=\"logout\"></mat-icon>\n <span i18n>Logout</span>\n </span>\n </button>\n</mat-menu>\n", styles: [".profile-icon{border-radius:100%;border:none;height:32px;width:32px;overflow:hidden;background-position:center center;background-repeat:no-repeat;background-size:cover}.profile-icon .avatar-icon{width:32px;height:32px;font-size:32px}.profile-icon:hover{cursor:pointer}.profile-icon:focus{outline:none}\n"], dependencies: [{ kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i7.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i7.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i7.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
958
|
-
}
|
|
959
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: UserProfileIconComponent, decorators: [{
|
|
960
|
-
type: Component,
|
|
961
|
-
args: [{ selector: 'rxap-user-profile-icon', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
|
|
962
|
-
MatMenuModule,
|
|
963
|
-
MatIconModule,
|
|
964
|
-
NgIf,
|
|
965
|
-
AsyncPipe,
|
|
966
|
-
], template: "<button [matMenuTriggerFor]=\"menu\"\n [disabled]=\"!username()\"\n class=\"profile-icon flex flex-row justify-center items-center\">\n <mat-icon class=\"avatar-icon\" svgIcon=\"account-circle\"></mat-icon>\n</button>\n\n<mat-menu #menu=\"matMenu\" [yPosition]=\"'below'\" class=\"!max-w-none\">\n <button mat-menu-item>\n <span class=\"flex flex-row gap-2\">\n <mat-icon svgIcon=\"account\"></mat-icon>\n <span>{{username()}}</span>\n </span>\n </button>\n <button (click)=\"logout()\" mat-menu-item>\n <span class=\"flex flex-row gap-2\">\n <mat-icon svgIcon=\"logout\"></mat-icon>\n <span i18n>Logout</span>\n </span>\n </button>\n</mat-menu>\n", styles: [".profile-icon{border-radius:100%;border:none;height:32px;width:32px;overflow:hidden;background-position:center center;background-repeat:no-repeat;background-size:cover}.profile-icon .avatar-icon{width:32px;height:32px;font-size:32px}.profile-icon:hover{cursor:pointer}.profile-icon:focus{outline:none}\n"] }]
|
|
967
|
-
}], ctorParameters: () => [{ type: i1$7.UserProfileDataSource }, { type: i2$4.RxapAuthenticationService }, { type: undefined, decorators: [{
|
|
968
|
-
type: Inject,
|
|
969
|
-
args: [EXTRACT_USERNAME_FROM_PROFILE]
|
|
970
|
-
}] }] });
|
|
971
|
-
|
|
972
|
-
class HeaderComponent {
|
|
973
|
-
constructor(headerComponentService, layoutComponentService, headerComponent) {
|
|
974
|
-
this.headerComponentService = headerComponentService;
|
|
975
|
-
this.layoutComponentService = layoutComponentService;
|
|
976
|
-
this.headerComponent = headerComponent;
|
|
977
|
-
this.color = undefined;
|
|
978
|
-
this.collapsable = layoutComponentService.collapsable;
|
|
979
|
-
this.opened = layoutComponentService.opened;
|
|
980
|
-
}
|
|
981
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: HeaderComponent, deps: [{ token: HeaderService }, { token: LayoutComponentService }, { token: RXAP_HEADER_COMPONENT, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
982
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.0.1", type: HeaderComponent, isStandalone: true, selector: "rxap-header", inputs: { color: "color" }, ngImport: i0, template: "<mat-toolbar [color]=\"color\" [ngClass]=\"{ open: opened() }\" class=\"mat-elevation-z3 header\">\n <div class=\"w-full flex flex-row gap-x-4 justify-between items-center\">\n <rxap-sidenav-toggle-button *ngIf=\"!collapsable()\"></rxap-sidenav-toggle-button>\n <div class=\"grow\">\n <ng-content></ng-content>\n </div>\n <rxap-apps-button class=\"grow-0\"></rxap-apps-button>\n <rxap-settings-button class=\"grow-0\"></rxap-settings-button>\n <rxap-user-profile-icon class=\"grow-0\"></rxap-user-profile-icon>\n </div>\n</mat-toolbar>\n\n<rxap-navigation-progress-bar></rxap-navigation-progress-bar>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: MatToolbarModule }, { kind: "component", type: i2$2.MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "ngmodule", type: MatMenuModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: MatSelectModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: MatOptionModule }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: NavigationProgressBarComponent, selector: "rxap-navigation-progress-bar" }, { kind: "component", type: UserProfileIconComponent, selector: "rxap-user-profile-icon" }, { kind: "component", type: AppsButtonComponent, selector: "rxap-apps-button" }, { kind: "component", type: SettingsButtonComponent, selector: "rxap-settings-button" }, { kind: "component", type: SidenavToggleButtonComponent, selector: "rxap-sidenav-toggle-button" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
983
|
-
}
|
|
984
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: HeaderComponent, decorators: [{
|
|
985
|
-
type: Component,
|
|
986
|
-
args: [{ selector: 'rxap-header', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
|
|
987
|
-
MatToolbarModule,
|
|
988
|
-
NgClass,
|
|
989
|
-
NgIf,
|
|
990
|
-
MatButtonModule,
|
|
991
|
-
MatMenuModule,
|
|
992
|
-
MatIconModule,
|
|
993
|
-
MatFormFieldModule,
|
|
994
|
-
StopPropagationDirective,
|
|
995
|
-
MatSelectModule,
|
|
996
|
-
FormsModule,
|
|
997
|
-
MatOptionModule,
|
|
998
|
-
DataSourceCollectionDirective,
|
|
999
|
-
MatSlideToggleModule,
|
|
1000
|
-
AsyncPipe,
|
|
1001
|
-
NavigationProgressBarComponent,
|
|
1002
|
-
UserProfileIconComponent,
|
|
1003
|
-
AppsButtonComponent,
|
|
1004
|
-
SettingsButtonComponent,
|
|
1005
|
-
SidenavToggleButtonComponent,
|
|
1006
|
-
], template: "<mat-toolbar [color]=\"color\" [ngClass]=\"{ open: opened() }\" class=\"mat-elevation-z3 header\">\n <div class=\"w-full flex flex-row gap-x-4 justify-between items-center\">\n <rxap-sidenav-toggle-button *ngIf=\"!collapsable()\"></rxap-sidenav-toggle-button>\n <div class=\"grow\">\n <ng-content></ng-content>\n </div>\n <rxap-apps-button class=\"grow-0\"></rxap-apps-button>\n <rxap-settings-button class=\"grow-0\"></rxap-settings-button>\n <rxap-user-profile-icon class=\"grow-0\"></rxap-user-profile-icon>\n </div>\n</mat-toolbar>\n\n<rxap-navigation-progress-bar></rxap-navigation-progress-bar>\n" }]
|
|
1007
|
-
}], ctorParameters: () => [{ type: i1$1.HeaderService, decorators: [{
|
|
1008
|
-
type: Inject,
|
|
1009
|
-
args: [HeaderService]
|
|
1010
|
-
}] }, { type: LayoutComponentService }, { type: undefined, decorators: [{
|
|
1011
|
-
type: Optional
|
|
1012
|
-
}, {
|
|
1013
|
-
type: Inject,
|
|
1014
|
-
args: [RXAP_HEADER_COMPONENT]
|
|
1015
|
-
}] }], propDecorators: { color: [{
|
|
1016
|
-
type: Input
|
|
1017
|
-
}] } });
|
|
1018
|
-
|
|
1019
|
-
class LayoutComponent {
|
|
1020
|
-
constructor(layoutComponentService, environment, iconLoaderService) {
|
|
1021
|
-
this.layoutComponentService = layoutComponentService;
|
|
1022
|
-
this.environment = environment;
|
|
1023
|
-
this.userSettingsThemeService = inject(UserSettingsThemeService);
|
|
1024
|
-
this.themeService = inject(ThemeService);
|
|
1025
|
-
iconLoaderService.load();
|
|
1026
|
-
this.fixedBottomGap = layoutComponentService.fixedBottomGap;
|
|
1027
|
-
this.fixedTopGap = layoutComponentService.fixedTopGap;
|
|
1028
|
-
this.pinned = layoutComponentService.pinned;
|
|
1029
|
-
this.collapsable = layoutComponentService.collapsable;
|
|
1030
|
-
this.opened = layoutComponentService.opened;
|
|
1031
|
-
this.sidenavMode = layoutComponentService.mode;
|
|
1032
|
-
this.logoSrc = this.layoutComponentService.logo.src ?? 'https://via.placeholder.com/256x128px';
|
|
1033
|
-
this.logoWidth = this.layoutComponentService.logo.width ?? 256;
|
|
1034
|
-
this.release = DetermineReleaseName(this.environment);
|
|
978
|
+
getApp(appId) {
|
|
979
|
+
if (!this.hasApp(appId)) {
|
|
980
|
+
return null;
|
|
981
|
+
}
|
|
982
|
+
const app = this.apps.find(app => app.id === appId);
|
|
983
|
+
if (!app) {
|
|
984
|
+
throw new Error(`FATAL: App with id "${appId}" not found!`);
|
|
985
|
+
}
|
|
986
|
+
return structuredClone(app);
|
|
1035
987
|
}
|
|
1036
|
-
|
|
1037
|
-
this.
|
|
988
|
+
getAppUrl(appId, path, infix = this.getPathPrefix()) {
|
|
989
|
+
const app = this.getApp(appId);
|
|
990
|
+
if (!app || !app.href) {
|
|
991
|
+
return null;
|
|
992
|
+
}
|
|
993
|
+
return JoinPath(app.href, infix, path);
|
|
1038
994
|
}
|
|
1039
|
-
|
|
1040
|
-
this.
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
995
|
+
getAppRouterLink(appId, path) {
|
|
996
|
+
const app = this.getApp(appId);
|
|
997
|
+
if (!app || !app.routerLink) {
|
|
998
|
+
return null;
|
|
999
|
+
}
|
|
1000
|
+
return [...app.routerLink, path];
|
|
1001
|
+
}
|
|
1002
|
+
getAppUrlOrThrow(appId, path) {
|
|
1003
|
+
const url = this.getAppUrl(appId, path);
|
|
1004
|
+
if (url) {
|
|
1005
|
+
return url;
|
|
1006
|
+
}
|
|
1007
|
+
throw new Error(`Could not find url for app with id "${appId}"`);
|
|
1008
|
+
}
|
|
1009
|
+
getAppRouterLinkOrThrow(appId, path) {
|
|
1010
|
+
const routerLink = this.getAppRouterLink(appId, path);
|
|
1011
|
+
if (routerLink) {
|
|
1012
|
+
return routerLink;
|
|
1013
|
+
}
|
|
1014
|
+
throw new Error(`Could not find router link for app with id "${appId}"`);
|
|
1015
|
+
}
|
|
1016
|
+
navigate(appId, path) {
|
|
1017
|
+
const url = this.getAppUrl(appId, path);
|
|
1018
|
+
if (url) {
|
|
1019
|
+
ClickOnLink(url);
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
async getAppList() {
|
|
1023
|
+
let appList = this
|
|
1024
|
+
.apps
|
|
1025
|
+
.filter(app => !app.hidden)
|
|
1026
|
+
.map(app => structuredClone(app));
|
|
1027
|
+
appList.forEach(app => {
|
|
1028
|
+
if (app.href) {
|
|
1029
|
+
app.href = JoinPath(app.href, this.getPathPrefix());
|
|
1050
1030
|
}
|
|
1051
1031
|
});
|
|
1032
|
+
for (const appFilter of this.appFilterList) {
|
|
1033
|
+
appList = await appFilter.call(structuredClone(appList));
|
|
1034
|
+
}
|
|
1035
|
+
appList = structuredClone(appList);
|
|
1036
|
+
this.activeAppList.set(appList);
|
|
1037
|
+
return appList;
|
|
1038
|
+
}
|
|
1039
|
+
getPathPrefix() {
|
|
1040
|
+
if (this.environment.production && this.localeId) {
|
|
1041
|
+
return this.localeId.replace(/-.+$/, '');
|
|
1042
|
+
}
|
|
1043
|
+
return '';
|
|
1052
1044
|
}
|
|
1053
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type:
|
|
1054
|
-
static { this.ɵ
|
|
1045
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: ExternalAppsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1046
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: ExternalAppsService }); }
|
|
1055
1047
|
}
|
|
1056
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type:
|
|
1057
|
-
type:
|
|
1058
|
-
|
|
1059
|
-
HeaderComponent,
|
|
1060
|
-
MatSidenavModule,
|
|
1061
|
-
AsyncPipe,
|
|
1062
|
-
MatIconModule,
|
|
1063
|
-
MatButtonModule,
|
|
1064
|
-
RouterLink,
|
|
1065
|
-
NgIf,
|
|
1066
|
-
FooterComponent,
|
|
1067
|
-
MatMenuModule,
|
|
1068
|
-
NgOptimizedImage,
|
|
1069
|
-
NavigationComponent,
|
|
1070
|
-
RouterOutlet,
|
|
1071
|
-
StatusIndicatorComponent,
|
|
1072
|
-
NgStyle,
|
|
1073
|
-
NgClass,
|
|
1074
|
-
], template: "<rxap-status-indicator class=\"fixed bottom-0 right-0 z-10\"></rxap-status-indicator>\n<div class=\"flex flex-col h-screen justify-between\">\n <rxap-header class=\"z-10 w-full fixed top-0\"></rxap-header>\n <mat-sidenav-container [ngStyle]=\"{\n 'margin-top.px': fixedTopGap(),\n 'margin-bottom.px': fixedBottomGap(),\n }\" class=\"grow\">\n <mat-sidenav\n #matSidenav=\"matSidenav\"\n [fixedBottomGap]=\"fixedBottomGap()\"\n [fixedInViewport]=\"true\"\n [fixedTopGap]=\"fixedTopGap()\"\n [mode]=\"sidenavMode()\"\n [ngClass]=\"{ collapsable: collapsable() }\"\n class=\"sidenav\"\n [opened]=\"opened()\"\n >\n <div (mouseleave)=\"collapsable() && !pinned() && matSidenav.close()\"\n class=\"h-full py-2 flex flex-col items-center gap-y-5 justify-items-stretch\">\n\n <div (click)=\"layoutComponentService.togglePinned()\" *ngIf=\"collapsable()\"\n class=\"pl-2 self-stretch grow-0 flex flex-row justify-between items-center\">\n <span class=\"text-lg\" i18n>Navigation</span>\n <div class=\"flex flex-row items-center justify-center\" style=\"width: 64px\">\n <button mat-icon-button>\n <mat-icon *ngIf=\"!pinned()\">radio_button_unchecked</mat-icon>\n <mat-icon *ngIf=\"pinned()\">radio_button_checked</mat-icon>\n </button>\n </div>\n </div>\n\n <ul\n (mouseenter)=\"collapsable() && !pinned() && matSidenav.open()\"\n class=\"grow self-stretch\"\n root\n rxap-navigation\n >\n </ul>\n\n <img\n [src]=\"logoSrc\"\n [routerLink]=\"['/']\"\n [width]=\"logoWidth\"\n alt=\"logo\"\n class=\"grow-0 mx-16\"\n />\n <div class=\"grow-0 px-16\">\n <span>{{release}}</span>\n </div>\n </div>\n </mat-sidenav>\n <mat-sidenav-content [ngClass]=\"{ 'ml-16': collapsable() }\" class=\"p-4\">\n <router-outlet></router-outlet>\n </mat-sidenav-content>\n </mat-sidenav-container>\n <rxap-footer class=\"z-10 w-full fixed bottom-0\"></rxap-footer>\n</div>\n<!--<rxap-window-task-bar-container></rxap-window-task-bar-container>-->\n", styles: [":host .sidenav.collapsable:not(.mat-drawer-opened){transform:translate(calc(-100% + 64px))!important;visibility:visible!important;box-shadow:inherit!important;transition-property:transform;transition-delay:.25s;display:flex;border-right:solid 1px rgba(0,0,0,.12)}:host .sidenav.collapsable ::ng-deep .mat-drawer-inner-container::-webkit-scrollbar{display:none}\n"] }]
|
|
1075
|
-
}], ctorParameters: () => [{ type: LayoutComponentService }, { type: undefined, decorators: [{
|
|
1076
|
-
type: Inject,
|
|
1077
|
-
args: [RXAP_ENVIRONMENT]
|
|
1078
|
-
}] }, { type: i2$6.IconLoaderService }], propDecorators: { sidenav: [{
|
|
1079
|
-
type: ViewChild,
|
|
1080
|
-
args: [MatSidenav, { static: true }]
|
|
1081
|
-
}] } });
|
|
1048
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: ExternalAppsService, decorators: [{
|
|
1049
|
+
type: Injectable
|
|
1050
|
+
}] });
|
|
1082
1051
|
|
|
1083
|
-
class
|
|
1084
|
-
constructor(
|
|
1085
|
-
|
|
1052
|
+
class AppsButtonComponent {
|
|
1053
|
+
constructor() {
|
|
1054
|
+
/**
|
|
1055
|
+
* The signal that indicates if the app list is open
|
|
1056
|
+
*/
|
|
1057
|
+
this.isOpen = signal(false);
|
|
1058
|
+
this.externalAppsService = inject(ExternalAppsService);
|
|
1059
|
+
this.appList = computed(() => this.externalAppsService.activeAppList());
|
|
1060
|
+
this.hasApps = computed(() => this.appList().length > 0);
|
|
1086
1061
|
}
|
|
1087
|
-
|
|
1088
|
-
|
|
1062
|
+
toggle() {
|
|
1063
|
+
this.isOpen.update(isOpen => !isOpen);
|
|
1089
1064
|
}
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
}
|
|
1093
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: SignOutComponent, decorators: [{
|
|
1094
|
-
type: Component,
|
|
1095
|
-
args: [{ selector: 'rxap-sign-out', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [MatButtonModule, MatIconModule], template: "<button\n mat-icon-button\n (click)=\"logout()\"\n>\n <mat-icon svgIcon=\"logout\"></mat-icon>\n</button>\n" }]
|
|
1096
|
-
}], ctorParameters: () => [{ type: i2$4.RxapAuthenticationService }] });
|
|
1097
|
-
|
|
1098
|
-
class ResetButtonComponent {
|
|
1099
|
-
constructor(resetService) {
|
|
1100
|
-
this.resetService = resetService;
|
|
1065
|
+
ngOnInit() {
|
|
1066
|
+
this.externalAppsService.getAppList();
|
|
1101
1067
|
}
|
|
1102
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type:
|
|
1103
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "
|
|
1068
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: AppsButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1069
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.1", type: AppsButtonComponent, isStandalone: true, selector: "rxap-apps-button", ngImport: i0, template: "@if (hasApps()) {\n <div class=\"flex flex-row items-center gap-8\">\n\n @if (isOpen()) {\n <div class=\"flex flex-row items-center gap-6 h-10\">\n\n @for (app of appList(); track app.label) {\n @if (app.href) {\n <a [href]=\"app.href\" [target]=\"app.target ?? '_self'\" mat-stroked-button>\n <span class=\"flex flex-row items-center gap-4\">\n @if (app.image) {\n <img [alt]=\"app.label\" [ngSrc]=\"app.image\" height=\"40\" width=\"40\">\n }\n <span class=\"label grow-0\">{{ app.label }}</span>\n </span>\n </a>\n } @else if (app.routerLink) {\n <a mat-stroked-button [routerLink]=\"app.routerLink\">\n <span class=\"flex flex-row items-center gap-4\">\n @if (app.image) {\n <img [alt]=\"app.label\" [ngSrc]=\"app.image\" height=\"40\" width=\"40\">\n }\n <span class=\"label grow-0\">{{ app.label }}</span>\n </span>\n </a>\n } @else {\n <button mat-stroked-button [disabled]=\"true\">\n <span class=\"flex flex-row items-center gap-4\">\n @if (app.image) {\n <img [alt]=\"app.label\" [ngSrc]=\"app.image\" height=\"40\" width=\"40\">\n }\n <span class=\"label grow-0\">{{ app.label }}</span>\n </span>\n </button>\n }\n }\n\n </div>\n }\n\n <button (click)=\"toggle()\" mat-icon-button>\n <mat-icon svgIcon=\"apps\"></mat-icon>\n </button>\n\n </div>\n}\n", styles: [""], dependencies: [{ kind: "directive", type: NgOptimizedImage, selector: "img[ngSrc]", inputs: ["ngSrc", "ngSrcset", "sizes", "width", "height", "loading", "priority", "loaderParams", "disableOptimizedSrcset", "fill", "placeholder", "placeholderConfig", "src", "srcset"] }, { kind: "component", type: MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: MatAnchor, selector: "a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1104
1070
|
}
|
|
1105
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type:
|
|
1071
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: AppsButtonComponent, decorators: [{
|
|
1106
1072
|
type: Component,
|
|
1107
|
-
args: [{ selector: 'rxap-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1073
|
+
args: [{ selector: 'rxap-apps-button', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
|
|
1074
|
+
NgOptimizedImage,
|
|
1075
|
+
MatButton,
|
|
1076
|
+
RouterLink,
|
|
1077
|
+
MatAnchor,
|
|
1078
|
+
MatIconButton,
|
|
1079
|
+
MatIcon,
|
|
1080
|
+
], template: "@if (hasApps()) {\n <div class=\"flex flex-row items-center gap-8\">\n\n @if (isOpen()) {\n <div class=\"flex flex-row items-center gap-6 h-10\">\n\n @for (app of appList(); track app.label) {\n @if (app.href) {\n <a [href]=\"app.href\" [target]=\"app.target ?? '_self'\" mat-stroked-button>\n <span class=\"flex flex-row items-center gap-4\">\n @if (app.image) {\n <img [alt]=\"app.label\" [ngSrc]=\"app.image\" height=\"40\" width=\"40\">\n }\n <span class=\"label grow-0\">{{ app.label }}</span>\n </span>\n </a>\n } @else if (app.routerLink) {\n <a mat-stroked-button [routerLink]=\"app.routerLink\">\n <span class=\"flex flex-row items-center gap-4\">\n @if (app.image) {\n <img [alt]=\"app.label\" [ngSrc]=\"app.image\" height=\"40\" width=\"40\">\n }\n <span class=\"label grow-0\">{{ app.label }}</span>\n </span>\n </a>\n } @else {\n <button mat-stroked-button [disabled]=\"true\">\n <span class=\"flex flex-row items-center gap-4\">\n @if (app.image) {\n <img [alt]=\"app.label\" [ngSrc]=\"app.image\" height=\"40\" width=\"40\">\n }\n <span class=\"label grow-0\">{{ app.label }}</span>\n </span>\n </button>\n }\n }\n\n </div>\n }\n\n <button (click)=\"toggle()\" mat-icon-button>\n <mat-icon svgIcon=\"apps\"></mat-icon>\n </button>\n\n </div>\n}\n" }]
|
|
1081
|
+
}] });
|
|
1112
1082
|
|
|
1113
|
-
class
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1083
|
+
class DefaultHeaderComponent {
|
|
1084
|
+
constructor() {
|
|
1085
|
+
this.layoutComponentService = inject(LayoutService);
|
|
1086
|
+
this.collapsable = computed(() => this.layoutComponentService.collapsable());
|
|
1087
|
+
this.opened = computed(() => this.layoutComponentService.opened());
|
|
1088
|
+
this.userProfileService = inject(UserProfileDataSource);
|
|
1089
|
+
this.profile = toSignal(this.userProfileService.connect('user-profile'), { initialValue: null });
|
|
1090
|
+
}
|
|
1091
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: DefaultHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1092
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.1", type: DefaultHeaderComponent, isStandalone: true, selector: "rxap-default-header", host: { classAttribute: "grow" }, ngImport: i0, template: "<div class=\"w-full flex flex-row gap-x-4 justify-between items-center\">\n @if (!collapsable()) {\n <rxap-sidenav-toggle-button></rxap-sidenav-toggle-button>\n }\n <div class=\"grow\">\n <ng-content></ng-content>\n </div>\n <rxap-apps-button class=\"grow-0\"></rxap-apps-button>\n <rxap-settings-button class=\"grow-0\"></rxap-settings-button>\n @if (this.profile(); as profile) {\n <rxap-user-profile-icon [profile]=\"profile\" class=\"grow-0\"></rxap-user-profile-icon>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "component", type: AppsButtonComponent, selector: "rxap-apps-button" }, { kind: "component", type: SettingsButtonComponent, selector: "rxap-settings-button" }, { kind: "component", type: SidenavToggleButtonComponent, selector: "rxap-sidenav-toggle-button" }, { kind: "component", type: UserProfileIconComponent, selector: "rxap-user-profile-icon", inputs: ["profile"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1119
1093
|
}
|
|
1120
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type:
|
|
1121
|
-
type:
|
|
1094
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: DefaultHeaderComponent, decorators: [{
|
|
1095
|
+
type: Component,
|
|
1096
|
+
args: [{ selector: 'rxap-default-header', standalone: true, imports: [
|
|
1097
|
+
AppsButtonComponent,
|
|
1098
|
+
SettingsButtonComponent,
|
|
1099
|
+
SidenavToggleButtonComponent,
|
|
1100
|
+
UserProfileIconComponent,
|
|
1101
|
+
], host: {
|
|
1102
|
+
'class': 'grow',
|
|
1103
|
+
}, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"w-full flex flex-row gap-x-4 justify-between items-center\">\n @if (!collapsable()) {\n <rxap-sidenav-toggle-button></rxap-sidenav-toggle-button>\n }\n <div class=\"grow\">\n <ng-content></ng-content>\n </div>\n <rxap-apps-button class=\"grow-0\"></rxap-apps-button>\n <rxap-settings-button class=\"grow-0\"></rxap-settings-button>\n @if (this.profile(); as profile) {\n <rxap-user-profile-icon [profile]=\"profile\" class=\"grow-0\"></rxap-user-profile-icon>\n }\n</div>\n" }]
|
|
1122
1104
|
}] });
|
|
1123
1105
|
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1106
|
+
function provideLayout(...additionalProviders) {
|
|
1107
|
+
return [
|
|
1108
|
+
ExternalAppsService,
|
|
1109
|
+
LayoutService,
|
|
1110
|
+
LogoService,
|
|
1111
|
+
NavigationService,
|
|
1112
|
+
HeaderService,
|
|
1113
|
+
FooterService,
|
|
1114
|
+
...additionalProviders,
|
|
1115
|
+
];
|
|
1116
|
+
}
|
|
1117
|
+
function withNavigationConfig(config) {
|
|
1118
|
+
return [
|
|
1119
|
+
{
|
|
1120
|
+
provide: RXAP_NAVIGATION_CONFIG,
|
|
1121
|
+
useValue: config,
|
|
1122
|
+
},
|
|
1123
|
+
];
|
|
1124
|
+
}
|
|
1125
|
+
function withNavigationInserts(inserts) {
|
|
1126
|
+
return [{
|
|
1127
|
+
provide: RXAP_NAVIGATION_CONFIG_INSERTS,
|
|
1128
|
+
useValue: inserts,
|
|
1129
|
+
}];
|
|
1130
|
+
}
|
|
1131
|
+
function withSettingsMenuItems(...items) {
|
|
1132
|
+
return [
|
|
1133
|
+
...items.filter((item) => typeof item === 'function').map(component => ({
|
|
1134
|
+
provide: RXAP_SETTINGS_MENU_ITEM_COMPONENT,
|
|
1135
|
+
useValue: component,
|
|
1136
|
+
multi: true,
|
|
1137
|
+
})),
|
|
1138
|
+
...items.filter((item) => typeof item !== 'function').map(item => ({
|
|
1139
|
+
provide: RXAP_SETTINGS_MENU_ITEM,
|
|
1140
|
+
useValue: item,
|
|
1141
|
+
multi: true,
|
|
1142
|
+
})),
|
|
1143
|
+
];
|
|
1144
|
+
}
|
|
1145
|
+
function withReleaseInfoModules(...module) {
|
|
1146
|
+
return module.map(item => ({
|
|
1147
|
+
provide: RXAP_RELEASE_INFO_MODULE,
|
|
1148
|
+
useValue: item,
|
|
1149
|
+
multi: true,
|
|
1150
|
+
}));
|
|
1151
|
+
}
|
|
1152
|
+
function withHeaderComponents(components) {
|
|
1153
|
+
return components.map(component => ({
|
|
1154
|
+
provide: RXAP_HEADER_COMPONENT,
|
|
1155
|
+
useValue: component,
|
|
1156
|
+
}));
|
|
1157
|
+
}
|
|
1158
|
+
function withFooterComponents(components) {
|
|
1159
|
+
return components.map(component => ({
|
|
1160
|
+
provide: RXAP_FOOTER_COMPONENT,
|
|
1161
|
+
useValue: component,
|
|
1162
|
+
}));
|
|
1163
|
+
}
|
|
1164
|
+
function widthDefaultHeaderComponent() {
|
|
1165
|
+
return {
|
|
1166
|
+
provide: RXAP_HEADER_COMPONENT,
|
|
1167
|
+
useValue: DefaultHeaderComponent,
|
|
1168
|
+
};
|
|
1141
1169
|
}
|
|
1142
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: FooterDirective, decorators: [{
|
|
1143
|
-
type: Directive,
|
|
1144
|
-
args: [{
|
|
1145
|
-
selector: '[rxapFooter]',
|
|
1146
|
-
standalone: true,
|
|
1147
|
-
}]
|
|
1148
|
-
}], ctorParameters: () => [{ type: i1$1.FooterService, decorators: [{
|
|
1149
|
-
type: Inject,
|
|
1150
|
-
args: [FooterService]
|
|
1151
|
-
}] }, { type: i0.TemplateRef, decorators: [{
|
|
1152
|
-
type: Inject,
|
|
1153
|
-
args: [TemplateRef]
|
|
1154
|
-
}] }, { type: i0.ViewContainerRef, decorators: [{
|
|
1155
|
-
type: Inject,
|
|
1156
|
-
args: [ViewContainerRef]
|
|
1157
|
-
}] }] });
|
|
1158
1170
|
|
|
1159
|
-
// region
|
|
1171
|
+
// region sidenav
|
|
1160
1172
|
// endregion
|
|
1161
1173
|
|
|
1162
1174
|
/**
|
|
1163
1175
|
* Generated bundle index. Do not edit.
|
|
1164
1176
|
*/
|
|
1165
1177
|
|
|
1166
|
-
export {
|
|
1178
|
+
export { AppsButtonComponent, BaseLayoutComponent, DefaultHeaderComponent, EXTRACT_USERNAME_FROM_PROFILE, ExternalAppsService, FooterComponent, FooterDirective, FooterService, HeaderComponent, HeaderDirective, HeaderService, IsNavigationDividerItem, IsNavigationInsertItem, IsNavigationItem, LayoutComponent, LayoutService, LogoService, MinimalLayoutComponent, NavigationComponent, NavigationItemComponent, NavigationProgressBarComponent, NavigationService, RXAP_EXTERNAL_APP_FILTER, RXAP_FOOTER_COMPONENT, RXAP_HEADER_COMPONENT, RXAP_LAYOUT_APPS_GRID, RXAP_LOGO_CONFIG, RXAP_NAVIGATION_CONFIG, RXAP_NAVIGATION_CONFIG_INSERTS, RXAP_RELEASE_INFO_MODULE, RXAP_SETTINGS_MENU_ITEM, RXAP_SETTINGS_MENU_ITEM_COMPONENT, ReleaseInfoComponent, SettingsButtonComponent, SidenavComponent, SidenavFooterDirective, SidenavHeaderDirective, SidenavToggleButtonComponent, UserProfileIconComponent, provideLayout, widthDefaultHeaderComponent, withFooterComponents, withHeaderComponents, withNavigationConfig, withNavigationInserts, withReleaseInfoModules, withSettingsMenuItems };
|
|
1167
1179
|
//# sourceMappingURL=rxap-layout.mjs.map
|