mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-05-12 17:04:57 +00:00
[AAE-10533] Generic App shell for HxP applications (#8002)
* [AAE-10533] Generic App shell for HxP applications * Clean code and add public_api for shell
This commit is contained in:
parent
7667c98196
commit
426cafff5e
@ -339,7 +339,9 @@
|
|||||||
"lib/core/api/**/*.ts",
|
"lib/core/api/**/*.ts",
|
||||||
"lib/core/api/**/*.html",
|
"lib/core/api/**/*.html",
|
||||||
"lib/core/auth/**/*.ts",
|
"lib/core/auth/**/*.ts",
|
||||||
"lib/core/auth/**/*.html"
|
"lib/core/auth/**/*.html",
|
||||||
|
"lib/core/shell/**/*.ts",
|
||||||
|
"lib/core/shell/**/*.html"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
17
lib/core/shell/README.md
Normal file
17
lib/core/shell/README.md
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# @alfresco/adf-core/shell
|
||||||
|
|
||||||
|
Secondary entry point of `@alfresco/adf-core`. It can be used by importing from `@alfresco/adf-core/shell`.
|
||||||
|
|
||||||
|
# Shell
|
||||||
|
|
||||||
|
[ShellModule](./src/lib/shell.module.ts) is designated as a main layout for the application.
|
||||||
|
|
||||||
|
I order to attach routes to appShell, `withRoutes(routes: Routes | AppShellRoutesConfig)` method should be used.
|
||||||
|
|
||||||
|
Passed routes are going to be attached to [shell main route](./src/lib/shell.routes.ts)
|
||||||
|
|
||||||
|
If you would like to provide custom app guard, you can provide your own using [SHELL_AUTH_TOKEN](./src/lib/shell.routes.ts)
|
||||||
|
|
||||||
|
## Shell Service
|
||||||
|
|
||||||
|
In order to use `shell`, you need to provide [SHELL_APP_SERVICE](./src/lib/services/shell-app.service.ts) which provides necessary options for shell component to work.
|
6
lib/core/shell/ng-package.json
Normal file
6
lib/core/shell/ng-package.json
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"$schema": "../../../../../node_modules/ng-packagr/ng-package.schema.json",
|
||||||
|
"lib": {
|
||||||
|
"entryFile": "src/index.ts"
|
||||||
|
}
|
||||||
|
}
|
18
lib/core/shell/public-api.ts
Normal file
18
lib/core/shell/public-api.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Copyright 2019 Alfresco Software, Ltd.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export * from './src/index';
|
20
lib/core/shell/src/index.ts
Normal file
20
lib/core/shell/src/index.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Copyright 2019 Alfresco Software, Ltd.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export * from './lib/shell.module';
|
||||||
|
export * from './lib/services/shell-app.service';
|
||||||
|
export * from './lib/components/shell/shell.component';
|
48
lib/core/shell/src/lib/components/shell/shell.component.html
Normal file
48
lib/core/shell/src/lib/components/shell/shell.component.html
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
<adf-sidenav-layout
|
||||||
|
#layout
|
||||||
|
[sidenavMin]="70"
|
||||||
|
[sidenavMax]="320"
|
||||||
|
[stepOver]="600"
|
||||||
|
[hideSidenav]="hideSidenav"
|
||||||
|
[expandedSidenav]="expandedSidenav"
|
||||||
|
(expanded)="onExpanded($event)"
|
||||||
|
>
|
||||||
|
<adf-sidenav-layout-header>
|
||||||
|
<ng-template let-isMenuMinimized="isMenuMinimized">
|
||||||
|
<div
|
||||||
|
role="heading"
|
||||||
|
aria-level="1"
|
||||||
|
*ngIf="!hideSidenav"
|
||||||
|
>
|
||||||
|
<adf-dynamic-component id="app.layout.header" [data]="{ layout }">
|
||||||
|
</adf-dynamic-component>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
</adf-sidenav-layout-header>
|
||||||
|
|
||||||
|
<adf-sidenav-layout-navigation>
|
||||||
|
<ng-template let-isMenuMinimized="isMenuMinimized">
|
||||||
|
<div
|
||||||
|
(swipeleft)="hideMenu($event)"
|
||||||
|
[attr.data-automation-id]="isMenuMinimized() ? 'collapsed' : 'expanded'"
|
||||||
|
>
|
||||||
|
<adf-dynamic-component
|
||||||
|
id="app.layout.sidenav"
|
||||||
|
[data]="{ mode: layout.isMenuMinimized ? 'collapsed' : 'expanded'}"
|
||||||
|
>
|
||||||
|
</adf-dynamic-component>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
</adf-sidenav-layout-navigation>
|
||||||
|
|
||||||
|
<adf-sidenav-layout-content>
|
||||||
|
<ng-template>
|
||||||
|
<router-outlet></router-outlet>
|
||||||
|
</ng-template>
|
||||||
|
</adf-sidenav-layout-content>
|
||||||
|
</adf-sidenav-layout>
|
||||||
|
|
||||||
|
<adf-dynamic-component id="app.shell.sibling">
|
||||||
|
</adf-dynamic-component>
|
||||||
|
|
||||||
|
<router-outlet name="viewer"></router-outlet>
|
34
lib/core/shell/src/lib/components/shell/shell.component.scss
Normal file
34
lib/core/shell/src/lib/components/shell/shell.component.scss
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
.app-shell {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex: 1;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
min-height: 0;
|
||||||
|
|
||||||
|
router-outlet[name='viewer'] + * {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
z-index: 999;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
adf-file-uploading-dialog {
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 599px) {
|
||||||
|
.adf-app-title {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 719px) {
|
||||||
|
.adf-app-logo {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
173
lib/core/shell/src/lib/components/shell/shell.component.spec.ts
Normal file
173
lib/core/shell/src/lib/components/shell/shell.component.spec.ts
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Copyright 2019 Alfresco Software, Ltd.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
||||||
|
import { TestBed, ComponentFixture } from '@angular/core/testing';
|
||||||
|
import { AppConfigService, SidenavLayoutModule } from '@alfresco/adf-core';
|
||||||
|
import { ShellLayoutComponent } from './shell.component';
|
||||||
|
import { Router, NavigationStart, RouterModule } from '@angular/router';
|
||||||
|
import { of, Subject } from 'rxjs';
|
||||||
|
import { ExtensionsModule } from '@alfresco/adf-extensions';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { ShellAppService, SHELL_APP_SERVICE } from '../../services/shell-app.service';
|
||||||
|
import { HttpClientModule } from '@angular/common/http';
|
||||||
|
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
|
|
||||||
|
class MockRouter {
|
||||||
|
private url = 'some-url';
|
||||||
|
private subject = new Subject();
|
||||||
|
events = this.subject.asObservable();
|
||||||
|
routerState = { snapshot: { url: this.url } };
|
||||||
|
|
||||||
|
navigateByUrl(url: string) {
|
||||||
|
const navigationStart = new NavigationStart(0, url);
|
||||||
|
this.subject.next(navigationStart);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('AppLayoutComponent', () => {
|
||||||
|
let fixture: ComponentFixture<ShellLayoutComponent>;
|
||||||
|
let component: ShellLayoutComponent;
|
||||||
|
let appConfig: AppConfigService;
|
||||||
|
let shellAppService: ShellAppService;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
const shellService: ShellAppService = {
|
||||||
|
pageHeading$: of('Title'),
|
||||||
|
hideSidenavConditions: [],
|
||||||
|
minimizeSidenavConditions: [],
|
||||||
|
preferencesService: {
|
||||||
|
get: (_key: string) => 'true',
|
||||||
|
set: (_key: string, _value: any) => {}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
imports: [CommonModule, NoopAnimationsModule, HttpClientModule, SidenavLayoutModule, ExtensionsModule, RouterModule.forChild([])],
|
||||||
|
providers: [
|
||||||
|
{
|
||||||
|
provide: Router,
|
||||||
|
useClass: MockRouter
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: SHELL_APP_SERVICE,
|
||||||
|
useValue: shellService
|
||||||
|
}
|
||||||
|
],
|
||||||
|
declarations: [ShellLayoutComponent],
|
||||||
|
schemas: [NO_ERRORS_SCHEMA]
|
||||||
|
});
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(ShellLayoutComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
appConfig = TestBed.inject(AppConfigService);
|
||||||
|
shellAppService = TestBed.inject(SHELL_APP_SERVICE);
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
appConfig.config.languages = [];
|
||||||
|
appConfig.config.locale = 'en';
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('sidenav state', () => {
|
||||||
|
it('should get state from configuration', () => {
|
||||||
|
appConfig.config.sideNav = {
|
||||||
|
expandedSidenav: false,
|
||||||
|
preserveState: false
|
||||||
|
};
|
||||||
|
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(component.expandedSidenav).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should resolve state to true is no configuration', () => {
|
||||||
|
appConfig.config.sidenav = {};
|
||||||
|
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(component.expandedSidenav).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should get state from user settings as true', () => {
|
||||||
|
appConfig.config.sideNav = {
|
||||||
|
expandedSidenav: false,
|
||||||
|
preserveState: true
|
||||||
|
};
|
||||||
|
|
||||||
|
spyOn(shellAppService.preferencesService, 'get').and.callFake((key) => {
|
||||||
|
if (key === 'expandedSidenav') {
|
||||||
|
return 'true';
|
||||||
|
}
|
||||||
|
return 'false';
|
||||||
|
});
|
||||||
|
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(component.expandedSidenav).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should get state from user settings as false', () => {
|
||||||
|
appConfig.config.sidenav = {
|
||||||
|
expandedSidenav: false,
|
||||||
|
preserveState: true
|
||||||
|
};
|
||||||
|
|
||||||
|
spyOn(shellAppService.preferencesService, 'get').and.callFake((key) => {
|
||||||
|
if (key === 'expandedSidenav') {
|
||||||
|
return 'false';
|
||||||
|
}
|
||||||
|
return 'true';
|
||||||
|
});
|
||||||
|
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(component.expandedSidenav).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should close menu on mobile screen size', () => {
|
||||||
|
component.minimizeSidenav = false;
|
||||||
|
component.layout.container = {
|
||||||
|
isMobileScreenSize: true,
|
||||||
|
toggleMenu: () => {}
|
||||||
|
};
|
||||||
|
|
||||||
|
spyOn(component.layout.container, 'toggleMenu');
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
component.hideMenu({ preventDefault: () => {} } as any);
|
||||||
|
|
||||||
|
expect(component.layout.container.toggleMenu).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should close menu on mobile screen size also when minimizeSidenav true', () => {
|
||||||
|
fixture.detectChanges();
|
||||||
|
component.minimizeSidenav = true;
|
||||||
|
component.layout.container = {
|
||||||
|
isMobileScreenSize: true,
|
||||||
|
toggleMenu: () => {}
|
||||||
|
};
|
||||||
|
|
||||||
|
spyOn(component.layout.container, 'toggleMenu');
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
component.hideMenu({ preventDefault: () => {} } as any);
|
||||||
|
|
||||||
|
expect(component.layout.container.toggleMenu).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
132
lib/core/shell/src/lib/components/shell/shell.component.ts
Normal file
132
lib/core/shell/src/lib/components/shell/shell.component.ts
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Copyright 2019 Alfresco Software, Ltd.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { AppConfigService, SidenavLayoutComponent } from '@alfresco/adf-core';
|
||||||
|
import { Component, Inject, OnDestroy, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
|
||||||
|
import { NavigationEnd, Router } from '@angular/router';
|
||||||
|
import { Subject, Observable } from 'rxjs';
|
||||||
|
import { filter, takeUntil, map, withLatestFrom } from 'rxjs/operators';
|
||||||
|
import { BreakpointObserver } from '@angular/cdk/layout';
|
||||||
|
import { Directionality } from '@angular/cdk/bidi';
|
||||||
|
import { SHELL_APP_SERVICE, ShellAppService } from '../../services/shell-app.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-shell',
|
||||||
|
templateUrl: './shell.component.html',
|
||||||
|
styleUrls: ['./shell.component.scss'],
|
||||||
|
encapsulation: ViewEncapsulation.None,
|
||||||
|
host: { class: 'app-shell' }
|
||||||
|
})
|
||||||
|
export class ShellLayoutComponent implements OnInit, OnDestroy {
|
||||||
|
@ViewChild('layout', { static: true })
|
||||||
|
layout: SidenavLayoutComponent;
|
||||||
|
|
||||||
|
onDestroy$: Subject<boolean> = new Subject<boolean>();
|
||||||
|
isSmallScreen$: Observable<boolean>;
|
||||||
|
|
||||||
|
expandedSidenav: boolean;
|
||||||
|
minimizeSidenav = false;
|
||||||
|
hideSidenav = false;
|
||||||
|
direction: Directionality;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private router: Router,
|
||||||
|
private appConfigService: AppConfigService,
|
||||||
|
private breakpointObserver: BreakpointObserver,
|
||||||
|
@Inject(SHELL_APP_SERVICE) private shellService: ShellAppService
|
||||||
|
) {}
|
||||||
|
|
||||||
|
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),
|
||||||
|
takeUntil(this.onDestroy$)
|
||||||
|
)
|
||||||
|
.subscribe(() => {
|
||||||
|
this.layout.container.sidenav.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
this.router.events
|
||||||
|
.pipe(
|
||||||
|
filter((event) => event instanceof NavigationEnd),
|
||||||
|
takeUntil(this.onDestroy$)
|
||||||
|
)
|
||||||
|
.subscribe((event: NavigationEnd) => {
|
||||||
|
this.minimizeSidenav = this.shellService.minimizeSidenavConditions.some((el) => event.urlAfterRedirects.includes(el));
|
||||||
|
this.hideSidenav = this.shellService.hideSidenavConditions.some((el) => event.urlAfterRedirects.includes(el));
|
||||||
|
|
||||||
|
this.updateState();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy() {
|
||||||
|
this.onDestroy$.next(true);
|
||||||
|
this.onDestroy$.complete();
|
||||||
|
}
|
||||||
|
|
||||||
|
hideMenu(event: Event) {
|
||||||
|
if (this.layout.container.isMobileScreenSize) {
|
||||||
|
event.preventDefault();
|
||||||
|
this.layout.container.toggleMenu();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private 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: boolean) {
|
||||||
|
if (!this.minimizeSidenav && this.appConfigService.get('sideNav.preserveState')) {
|
||||||
|
this.shellService.preferencesService.set('expandedSidenav', state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private getSidenavState(): boolean {
|
||||||
|
const expand = this.appConfigService.get<boolean>('sideNav.expandedSidenav', true);
|
||||||
|
const preserveState = this.appConfigService.get<boolean>('sideNav.preserveState', true);
|
||||||
|
|
||||||
|
if (preserveState) {
|
||||||
|
return this.shellService.preferencesService.get('expandedSidenav', expand.toString()) === 'true';
|
||||||
|
}
|
||||||
|
|
||||||
|
return expand;
|
||||||
|
}
|
||||||
|
}
|
36
lib/core/shell/src/lib/services/shell-app.service.ts
Normal file
36
lib/core/shell/src/lib/services/shell-app.service.ts
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Copyright 2019 Alfresco Software, Ltd.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { InjectionToken } from '@angular/core';
|
||||||
|
import { CanActivate, CanActivateChild } from '@angular/router';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
|
||||||
|
export interface ShellPreferencesService {
|
||||||
|
set(preferenceKey: string, value: any): void;
|
||||||
|
get(preferenceKey: string, defaultValue: string): string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ShellAppService {
|
||||||
|
pageHeading$: Observable<string>;
|
||||||
|
hideSidenavConditions: string[];
|
||||||
|
minimizeSidenavConditions: string[];
|
||||||
|
preferencesService: ShellPreferencesService;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const SHELL_APP_SERVICE = new InjectionToken<ShellAppService>('SHELL_APP_SERVICE');
|
||||||
|
|
||||||
|
export const SHELL_AUTH_TOKEN = new InjectionToken<CanActivate & CanActivateChild>('SHELL_AUTH_TOKEN');
|
81
lib/core/shell/src/lib/shell.module.ts
Normal file
81
lib/core/shell/src/lib/shell.module.ts
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Copyright 2019 Alfresco Software, Ltd.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { ModuleWithProviders, NgModule } from '@angular/core';
|
||||||
|
import { Routes, provideRoutes, RouterModule, Route } from '@angular/router';
|
||||||
|
import { SHELL_LAYOUT_ROUTE } from './shell.routes';
|
||||||
|
import { SidenavLayoutModule } from '@alfresco/adf-core';
|
||||||
|
import { ExtensionsModule } from '@alfresco/adf-extensions';
|
||||||
|
import { ShellLayoutComponent } from './components/shell/shell.component';
|
||||||
|
|
||||||
|
export interface AppShellRoutesConfig {
|
||||||
|
shellParentRoute?: Route;
|
||||||
|
shellChildren: Routes;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [SidenavLayoutModule, ExtensionsModule, RouterModule.forChild([]), CommonModule],
|
||||||
|
exports: [ShellLayoutComponent],
|
||||||
|
declarations: [ShellLayoutComponent]
|
||||||
|
})
|
||||||
|
export class ShellModule {
|
||||||
|
static withRoutes(routes: Routes | AppShellRoutesConfig): ModuleWithProviders<ShellModule> {
|
||||||
|
if (Array.isArray(routes)) {
|
||||||
|
return getModuleForRoutes(routes);
|
||||||
|
}
|
||||||
|
|
||||||
|
return getModuleForRouteConfig(routes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getModuleForRoutes(routes: Routes): ModuleWithProviders<ShellModule> {
|
||||||
|
const shellLayoutRoute = SHELL_LAYOUT_ROUTE;
|
||||||
|
|
||||||
|
routes.forEach((childRoute) => {
|
||||||
|
shellLayoutRoute.children.push(childRoute);
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
ngModule: ShellModule,
|
||||||
|
providers: provideRoutes([shellLayoutRoute])
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function getModuleForRouteConfig(config: AppShellRoutesConfig): ModuleWithProviders<ShellModule> {
|
||||||
|
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: provideRoutes([rootRoute])
|
||||||
|
};
|
||||||
|
}
|
27
lib/core/shell/src/lib/shell.routes.ts
Normal file
27
lib/core/shell/src/lib/shell.routes.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
/*!
|
||||||
|
* @license
|
||||||
|
* Copyright 2019 Alfresco Software, Ltd.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Route } from '@angular/router';
|
||||||
|
import { ShellLayoutComponent } from './components/shell/shell.component';
|
||||||
|
import { SHELL_AUTH_TOKEN } from './services/shell-app.service';
|
||||||
|
|
||||||
|
export const SHELL_LAYOUT_ROUTE: Route = {
|
||||||
|
path: '',
|
||||||
|
component: ShellLayoutComponent,
|
||||||
|
canActivate: [SHELL_AUTH_TOKEN],
|
||||||
|
children: []
|
||||||
|
};
|
@ -26,6 +26,7 @@
|
|||||||
"@alfresco/adf-core": ["lib/core"],
|
"@alfresco/adf-core": ["lib/core"],
|
||||||
"@alfresco/adf-core/*": ["lib/core/*/public-api.ts"],
|
"@alfresco/adf-core/*": ["lib/core/*/public-api.ts"],
|
||||||
"@alfresco/adf-core/auth": ["lib/core/auth/src/index.ts"],
|
"@alfresco/adf-core/auth": ["lib/core/auth/src/index.ts"],
|
||||||
|
"@alfresco/adf-core/shell": ["lib/core/shell/src/index.ts"],
|
||||||
"@alfresco/adf-extensions": ["lib/extensions"],
|
"@alfresco/adf-extensions": ["lib/extensions"],
|
||||||
"@alfresco/adf-insights": ["lib/insights"],
|
"@alfresco/adf-insights": ["lib/insights"],
|
||||||
"@alfresco/adf-process-services": ["lib/process-services"],
|
"@alfresco/adf-process-services": ["lib/process-services"],
|
||||||
|
Loading…
x
Reference in New Issue
Block a user