@alfresco/adf-core
Version:
342 lines (333 loc) • 19.2 kB
JavaScript
import * as i0 from '@angular/core';
import { InjectionToken, inject, DestroyRef, ViewChild, Inject, Optional, ViewEncapsulation, Component, NgModule } from '@angular/core';
import * as i1 from '@angular/router';
import { NavigationEnd, RouterModule, provideRouter } from '@angular/router';
import * as i2 from '@alfresco/adf-core';
import { SidenavLayoutHeaderDirective, SidenavLayoutNavigationDirective, SidenavLayoutContentDirective, SidenavLayoutComponent } from '@alfresco/adf-core';
import { DynamicExtensionComponent } from '@alfresco/adf-extensions';
import { map, withLatestFrom, filter } from 'rxjs/operators';
import * as i3 from '@angular/cdk/layout';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
/*!
* @license
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const SHELL_APP_SERVICE = new InjectionToken('SHELL_APP_SERVICE');
const SHELL_AUTH_TOKEN = new InjectionToken('SHELL_AUTH_TOKEN');
const SHELL_NAVBAR_MIN_WIDTH = new InjectionToken('SHELL_NAVBAR_MIN_WIDTH');
const SHELL_NAVBAR_MAX_WIDTH = new InjectionToken('SHELL_NAVBAR_MAX_WIDTH');
/*!
* @license
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class ShellLayoutComponent {
constructor(router, appConfigService, breakpointObserver, shellService, navBarMinWidth, navbarMaxWidth) {
this.router = router;
this.appConfigService = appConfigService;
this.breakpointObserver = breakpointObserver;
this.shellService = shellService;
this.minimizeSidenav = false;
this.hideSidenav = false;
this.destroyRef = inject(DestroyRef);
this.sidenavMin = navBarMinWidth ?? 70;
this.sidenavMax = navbarMaxWidth ?? 320;
}
ngOnInit() {
this.isSmallScreen$ = this.breakpointObserver.observe(['(max-width: 600px)']).pipe(map((result) => result.matches));
this.hideSidenav = this.shellService.hideSidenavConditions.some((el) => this.router.routerState.snapshot.url.includes(el));
this.minimizeSidenav = this.shellService.minimizeSidenavConditions.some((el) => this.router.routerState.snapshot.url.includes(el));
if (!this.minimizeSidenav) {
this.expandedSidenav = this.getSidenavState();
}
else {
this.expandedSidenav = false;
}
this.router.events
.pipe(withLatestFrom(this.isSmallScreen$), filter(([event, isSmallScreen]) => isSmallScreen && event instanceof NavigationEnd), takeUntilDestroyed(this.destroyRef))
.subscribe(() => {
this.layout.container.sidenav.close();
});
this.router.events
.pipe(filter((event) => event instanceof NavigationEnd), takeUntilDestroyed(this.destroyRef))
.subscribe((event) => {
this.minimizeSidenav = this.shellService.minimizeSidenavConditions.some((el) => {
const previousNavigation = this.router.getCurrentNavigation()?.previousNavigation?.finalUrl;
const previousPath = previousNavigation ? this.router.serializeUrl(previousNavigation) : '';
return event.urlAfterRedirects.includes(el) && !previousPath.includes(el);
});
this.hideSidenav = this.shellService.hideSidenavConditions.some((el) => event.urlAfterRedirects.includes(el));
this.updateState();
});
}
hideMenu(event) {
if (this.layout.container.isMobileScreenSize) {
event.preventDefault();
this.layout.container.toggleMenu();
}
}
updateState() {
if (this.minimizeSidenav && !this.layout.isMenuMinimized) {
this.layout.isMenuMinimized = true;
if (!this.layout.container.isMobileScreenSize) {
this.layout.container.toggleMenu();
}
}
if (!this.minimizeSidenav) {
if (this.getSidenavState() && this.layout.isMenuMinimized) {
this.layout.isMenuMinimized = false;
this.layout.container.toggleMenu();
}
}
}
onExpanded(state) {
if (!this.minimizeSidenav && this.appConfigService.get('sideNav.preserveState')) {
this.shellService.preferencesService.set('expandedSidenav', state);
}
}
getSidenavState() {
const expand = this.appConfigService.get('sideNav.expandedSidenav', true);
const preserveState = this.appConfigService.get('sideNav.preserveState', true);
if (preserveState) {
return this.shellService.preferencesService.get('expandedSidenav', expand.toString()) === 'true';
}
return expand;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: ShellLayoutComponent, deps: [{ token: i1.Router }, { token: i2.AppConfigService }, { token: i3.BreakpointObserver }, { token: SHELL_APP_SERVICE }, { token: SHELL_NAVBAR_MIN_WIDTH, optional: true }, { token: SHELL_NAVBAR_MAX_WIDTH, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.6", type: ShellLayoutComponent, isStandalone: true, selector: "app-shell", host: { classAttribute: "app-shell" }, viewQueries: [{ propertyName: "layout", first: true, predicate: ["layout"], descendants: true, static: true }], ngImport: i0, template: "<adf-sidenav-layout\n #layout\n [sidenavMin]=\"sidenavMin\"\n [sidenavMax]=\"sidenavMax\"\n [stepOver]=\"600\"\n [hideSidenav]=\"hideSidenav\"\n [expandedSidenav]=\"expandedSidenav\"\n (expanded)=\"onExpanded($event)\"\n>\n <adf-sidenav-layout-header>\n <ng-template let-isMenuMinimized=\"isMenuMinimized\">\n @if (!hideSidenav) {\n <div\n role=\"heading\"\n aria-level=\"1\"\n >\n <adf-dynamic-component id=\"app.layout.header\" [data]=\"{ layout }\" />\n </div>\n }\n </ng-template>\n </adf-sidenav-layout-header>\n\n <adf-sidenav-layout-navigation>\n <ng-template let-isMenuMinimized=\"isMenuMinimized\">\n <div\n (swipeleft)=\"hideMenu($event)\"\n [attr.data-automation-id]=\"isMenuMinimized() ? 'collapsed' : 'expanded'\"\n >\n <adf-dynamic-component\n id=\"app.layout.sidenav\"\n [data]=\"{ layout, mode: layout.isMenuMinimized ? 'collapsed' : 'expanded'}\"\n />\n </div>\n </ng-template>\n </adf-sidenav-layout-navigation>\n\n <adf-sidenav-layout-content>\n <ng-template>\n <router-outlet />\n </ng-template>\n </adf-sidenav-layout-content>\n</adf-sidenav-layout>\n\n<adf-dynamic-component id=\"app.shell.sibling\" />\n\n<router-outlet name=\"viewer\" />\n", styles: [".app-shell{display:flex;flex-direction:column;flex:1;height:100%;overflow:hidden;min-height:0}.app-shell router-outlet[name=viewer]+*{width:100%;height:100%;z-index:999;position:absolute;top:0;right:0;background-color:#fff}.app-shell adf-file-uploading-dialog{z-index:1000}@media (max-width: 599.9px){.adf-app-title{display:none}}@media screen and (width <= 719px){.adf-app-logo{display:none}}\n"], dependencies: [{ kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1.RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "directive", type: SidenavLayoutHeaderDirective, selector: "adf-sidenav-layout-header" }, { kind: "directive", type: SidenavLayoutNavigationDirective, selector: "adf-sidenav-layout-navigation" }, { kind: "directive", type: SidenavLayoutContentDirective, selector: "adf-sidenav-layout-content" }, { kind: "component", type: DynamicExtensionComponent, selector: "adf-dynamic-component", inputs: ["id", "data"] }, { kind: "component", type: SidenavLayoutComponent, selector: "adf-sidenav-layout", inputs: ["position", "sidenavMin", "sidenavMax", "stepOver", "hideSidenav", "expandedSidenav"], outputs: ["expanded"] }], encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: ShellLayoutComponent, decorators: [{
type: Component,
args: [{ selector: 'app-shell', imports: [
RouterModule,
SidenavLayoutHeaderDirective,
SidenavLayoutNavigationDirective,
SidenavLayoutContentDirective,
DynamicExtensionComponent,
SidenavLayoutComponent
], encapsulation: ViewEncapsulation.None, host: { class: 'app-shell' }, template: "<adf-sidenav-layout\n #layout\n [sidenavMin]=\"sidenavMin\"\n [sidenavMax]=\"sidenavMax\"\n [stepOver]=\"600\"\n [hideSidenav]=\"hideSidenav\"\n [expandedSidenav]=\"expandedSidenav\"\n (expanded)=\"onExpanded($event)\"\n>\n <adf-sidenav-layout-header>\n <ng-template let-isMenuMinimized=\"isMenuMinimized\">\n @if (!hideSidenav) {\n <div\n role=\"heading\"\n aria-level=\"1\"\n >\n <adf-dynamic-component id=\"app.layout.header\" [data]=\"{ layout }\" />\n </div>\n }\n </ng-template>\n </adf-sidenav-layout-header>\n\n <adf-sidenav-layout-navigation>\n <ng-template let-isMenuMinimized=\"isMenuMinimized\">\n <div\n (swipeleft)=\"hideMenu($event)\"\n [attr.data-automation-id]=\"isMenuMinimized() ? 'collapsed' : 'expanded'\"\n >\n <adf-dynamic-component\n id=\"app.layout.sidenav\"\n [data]=\"{ layout, mode: layout.isMenuMinimized ? 'collapsed' : 'expanded'}\"\n />\n </div>\n </ng-template>\n </adf-sidenav-layout-navigation>\n\n <adf-sidenav-layout-content>\n <ng-template>\n <router-outlet />\n </ng-template>\n </adf-sidenav-layout-content>\n</adf-sidenav-layout>\n\n<adf-dynamic-component id=\"app.shell.sibling\" />\n\n<router-outlet name=\"viewer\" />\n", styles: [".app-shell{display:flex;flex-direction:column;flex:1;height:100%;overflow:hidden;min-height:0}.app-shell router-outlet[name=viewer]+*{width:100%;height:100%;z-index:999;position:absolute;top:0;right:0;background-color:#fff}.app-shell adf-file-uploading-dialog{z-index:1000}@media (max-width: 599.9px){.adf-app-title{display:none}}@media screen and (width <= 719px){.adf-app-logo{display:none}}\n"] }]
}], ctorParameters: () => [{ type: i1.Router }, { type: i2.AppConfigService }, { type: i3.BreakpointObserver }, { type: undefined, decorators: [{
type: Inject,
args: [SHELL_APP_SERVICE]
}] }, { type: undefined, decorators: [{
type: Optional
}, {
type: Inject,
args: [SHELL_NAVBAR_MIN_WIDTH]
}] }, { type: undefined, decorators: [{
type: Optional
}, {
type: Inject,
args: [SHELL_NAVBAR_MAX_WIDTH]
}] }], propDecorators: { layout: [{
type: ViewChild,
args: ['layout', { static: true }]
}] } });
/*!
* @license
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const SHELL_LAYOUT_ROUTE = {
path: '',
component: ShellLayoutComponent,
canActivate: [SHELL_AUTH_TOKEN],
children: []
};
/**
* Provides shell routes for the application.
*
* @param routes The routes configuration for the shell.
* @returns An array of providers for the shell routes.
*/
function provideShellRoutes(routes) {
const shellLayoutRoute = SHELL_LAYOUT_ROUTE;
if (Array.isArray(routes)) {
shellLayoutRoute.children.push(...routes);
return [provideRouter([shellLayoutRoute])];
}
const shellChildrenRoutes = routes.shellChildren || [];
if (shellChildrenRoutes.length > 0) {
shellLayoutRoute.children.push(...shellChildrenRoutes);
}
const shellParentRoute = routes.shellParentRoute;
const rootRoute = shellParentRoute || shellLayoutRoute;
if (routes.shellParentRoute) {
rootRoute.children = rootRoute.children || [];
rootRoute.children.push(shellLayoutRoute);
}
return [provideRouter([rootRoute])];
}
/*!
* @license
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/** @deprecated use `provideShell` instead */
class ShellModule {
static withRoutes(routes) {
if (Array.isArray(routes)) {
return getModuleForRoutes(routes);
}
return getModuleForRouteConfig(routes);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: ShellModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.6", ngImport: i0, type: ShellModule }); }
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: ShellModule }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: ShellModule, decorators: [{
type: NgModule
}] });
/**
* Resolve module for routes
*
* @param routes route configuration
* @returns module with providers
*/
function getModuleForRoutes(routes) {
const shellLayoutRoute = SHELL_LAYOUT_ROUTE;
routes.forEach((childRoute) => {
shellLayoutRoute.children.push(childRoute);
});
return {
ngModule: ShellModule,
providers: [provideRouter([shellLayoutRoute])]
};
}
/**
* Resolve a module for the route configuration
*
* @param config route configuration
* @returns module with providers
*/
function getModuleForRouteConfig(config) {
const shellLayoutRoute = SHELL_LAYOUT_ROUTE;
const shellParentRoute = config.shellParentRoute;
const shellChildrenRoutes = config.shellChildren;
shellLayoutRoute.children.push(...shellChildrenRoutes);
const rootRoute = shellParentRoute ? shellParentRoute : shellLayoutRoute;
if (config.shellParentRoute) {
if (rootRoute.children === undefined) {
rootRoute.children = [];
}
rootRoute.children.push(shellLayoutRoute);
}
return {
ngModule: ShellModule,
providers: [provideRouter([rootRoute])]
};
}
/*!
* @license
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Provides Shell-related api and providers
*
* @param opts Optional parameters
* @returns list of Angular providers
*/
function provideShell(opts) {
const result = [provideShellRoutes(opts?.routes || [])];
if (opts?.appService) {
result.push({
provide: SHELL_APP_SERVICE,
useValue: opts.appService
});
}
if (opts?.authGuard) {
result.push({
provide: SHELL_AUTH_TOKEN,
useValue: opts.authGuard
});
}
if (opts?.navBar) {
result.push({
provide: SHELL_NAVBAR_MIN_WIDTH,
useValue: opts.navBar.minWidth ?? 70
});
result.push({
provide: SHELL_NAVBAR_MAX_WIDTH,
useValue: opts.navBar.maxWidth ?? 320
});
}
return result;
}
/*!
* @license
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Generated bundle index. Do not edit.
*/
export { SHELL_APP_SERVICE, SHELL_AUTH_TOKEN, SHELL_LAYOUT_ROUTE, SHELL_NAVBAR_MAX_WIDTH, SHELL_NAVBAR_MIN_WIDTH, ShellLayoutComponent, ShellModule, provideShell, provideShellRoutes };
//# sourceMappingURL=alfresco-adf-core-shell.mjs.map