diff --git a/app/src/app/app-shell/app-shell.module.ts b/app/src/app/app-shell/app-shell.module.ts deleted file mode 100644 index 94f110d94..000000000 --- a/app/src/app/app-shell/app-shell.module.ts +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright © 2005 - 2021 Alfresco Software, Ltd. All rights reserved. - * - * License rights for this program may be obtained from Alfresco Software, Ltd. - * pursuant to a written agreement and any use of this program without such an - * agreement is prohibited. - */ - -import { CommonModule } from '@angular/common'; -import { ModuleWithProviders, NgModule } from '@angular/core'; -import { Routes, provideRoutes, RouterModule, Route } from '@angular/router'; -import { SHELL_LAYOUT_ROUTE } from './app-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 AppShellModule { - static withRoutes(routes: Routes | AppShellRoutesConfig): ModuleWithProviders { - if (Array.isArray(routes)) { - return getModuleForRoutes(routes); - } - - return getModuleForRouteConfig(routes); - } -} - -function getModuleForRoutes(routes: Routes): ModuleWithProviders { - const shellLayoutRoute = SHELL_LAYOUT_ROUTE; - - routes.forEach((childRoute) => { - shellLayoutRoute.children.push(childRoute); - }); - - return { - ngModule: AppShellModule, - providers: provideRoutes([shellLayoutRoute]) - }; -} - -function getModuleForRouteConfig(config: AppShellRoutesConfig): ModuleWithProviders { - 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: AppShellModule, - providers: provideRoutes([rootRoute]) - }; -} diff --git a/app/src/app/app-shell/app-shell.routes.ts b/app/src/app/app-shell/app-shell.routes.ts deleted file mode 100644 index 86a726bcb..000000000 --- a/app/src/app/app-shell/app-shell.routes.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright © 2005 - 2021 Alfresco Software, Ltd. All rights reserved. - * - * License rights for this program may be obtained from Alfresco Software, Ltd. - * pursuant to a written agreement and any use of this program without such an - * agreement is prohibited. - */ - -import { InjectionToken } from '@angular/core'; -import { CanActivate, CanActivateChild, Route } from '@angular/router'; -import { ShellLayoutComponent } from './components/shell/shell.component'; - -export const SHELL_AUTH_TOKEN = new InjectionToken('SHELL_AUTH_TOKEN'); - -export const SHELL_LAYOUT_ROUTE: Route = { - path: '', - component: ShellLayoutComponent, - canActivate: [SHELL_AUTH_TOKEN], - children: [] -}; diff --git a/app/src/app/app-shell/components/shell/shell.component.html b/app/src/app/app-shell/components/shell/shell.component.html deleted file mode 100644 index 3cd17c11f..000000000 --- a/app/src/app/app-shell/components/shell/shell.component.html +++ /dev/null @@ -1,48 +0,0 @@ - - - -
- - -
-
-
- - - -
- - -
-
-
- - - - - - -
- - - - - diff --git a/app/src/app/app-shell/components/shell/shell.component.scss b/app/src/app/app-shell/components/shell/shell.component.scss deleted file mode 100644 index 776563786..000000000 --- a/app/src/app/app-shell/components/shell/shell.component.scss +++ /dev/null @@ -1,34 +0,0 @@ -.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; - } -} diff --git a/app/src/app/app-shell/components/shell/shell.component.spec.ts b/app/src/app/app-shell/components/shell/shell.component.spec.ts deleted file mode 100644 index 962e911a4..000000000 --- a/app/src/app/app-shell/components/shell/shell.component.spec.ts +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright © 2005 - 2021 Alfresco Software, Ltd. All rights reserved. - * - * License rights for this program may be obtained from Alfresco Software, Ltd. - * pursuant to a written agreement and any use of this program without such an - * agreement is prohibited. - */ - -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 { Store } from '@ngrx/store'; -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 { TranslateService } from '@ngx-translate/core'; -import { TranslateServiceMock } from '@alfresco/aca-shared'; -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; - 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: [ - Store, - { - provide: Router, - useClass: MockRouter - }, - { - provide: SHELL_APP_SERVICE, - useValue: shellService - }, - { provide: TranslateService, useClass: TranslateServiceMock } - ], - 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(); - }); -}); diff --git a/app/src/app/app-shell/components/shell/shell.component.ts b/app/src/app/app-shell/components/shell/shell.component.ts deleted file mode 100644 index c4a8db82c..000000000 --- a/app/src/app/app-shell/components/shell/shell.component.ts +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright © 2005 - 2021 Alfresco Software, Ltd. All rights reserved. - * - * License rights for this program may be obtained from Alfresco Software, Ltd. - * pursuant to a written agreement and any use of this program without such an - * agreement is prohibited. - */ - -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 = new Subject(); - isSmallScreen$: Observable; - - 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('sideNav.expandedSidenav', true); - const preserveState = this.appConfigService.get('sideNav.preserveState', true); - - if (preserveState) { - return this.shellService.preferencesService.get('expandedSidenav', expand.toString()) === 'true'; - } - - return expand; - } -} diff --git a/app/src/app/app-shell/index.ts b/app/src/app/app-shell/index.ts deleted file mode 100644 index e0aad68ec..000000000 --- a/app/src/app/app-shell/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -/* - * Copyright © 2005 - 2021 Alfresco Software, Ltd. All rights reserved. - * - * License rights for this program may be obtained from Alfresco Software, Ltd. - * pursuant to a written agreement and any use of this program without such an - * agreement is prohibited. - */ - -export * from './app-shell.module'; -export * from './services/shell-app.service'; diff --git a/app/src/app/app-shell/services/shell-app.service.ts b/app/src/app/app-shell/services/shell-app.service.ts deleted file mode 100644 index c2912517a..000000000 --- a/app/src/app/app-shell/services/shell-app.service.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright © 2005 - 2021 Alfresco Software, Ltd. All rights reserved. - * - * License rights for this program may be obtained from Alfresco Software, Ltd. - * pursuant to a written agreement and any use of this program without such an - * agreement is prohibited. - */ - -import { InjectionToken } from '@angular/core'; -import { Observable } from 'rxjs'; - -export interface ShellPreferencesService { - set(preferenceKey: string, value: any): void; - get(preferenceKey: string, defaultValue: string): string; -} - -export interface ShellAppService { - pageHeading$: Observable; - hideSidenavConditions: string[]; - minimizeSidenavConditions: string[]; - preferencesService: ShellPreferencesService; -} - -export const SHELL_APP_SERVICE = new InjectionToken('SHELL_APP_SERVICE'); diff --git a/app/src/app/app.module.ts b/app/src/app/app.module.ts index 02c5ebb37..b9631814d 100644 --- a/app/src/app/app.module.ts +++ b/app/src/app/app.module.ts @@ -50,11 +50,9 @@ import localePl from '@angular/common/locales/pl'; import localeFi from '@angular/common/locales/fi'; import localeDa from '@angular/common/locales/da'; import localeSv from '@angular/common/locales/sv'; -import { AppShellModule, SHELL_APP_SERVICE } from './app-shell'; import { TranslateModule } from '@ngx-translate/core'; import { RouterModule } from '@angular/router'; import { AppComponent } from './app.components'; -import { SHELL_AUTH_TOKEN } from './app-shell/app-shell.routes'; import { CONTENT_LAYOUT_ROUTES } from './content-plugin/content.routes'; import { ContentServiceExtensionModule } from './content-plugin/content-services-extension.module'; import { CoreExtensionsModule } from './extensions/core.extensions.module'; @@ -62,6 +60,7 @@ import { INITIAL_APP_STATE } from './content-plugin/store/initial-state'; import { ContentVersionService } from '@alfresco/adf-content-services'; import { ContentUrlService } from './content-plugin/services/content-url.service'; import { STORE_INITIAL_APP_DATA } from '@alfresco/aca-shared/store'; +import { ShellModule, SHELL_APP_SERVICE, SHELL_AUTH_TOKEN } from '@alfresco/adf-core/shell'; registerLocaleData(localeFr); registerLocaleData(localeDe); @@ -94,7 +93,7 @@ registerLocaleData(localeSv); relativeLinkResolution: 'legacy' }), AppExtensionsModule, - AppShellModule.withRoutes({ + ShellModule.withRoutes({ shellChildren: [CONTENT_LAYOUT_ROUTES] }), ContentServiceExtensionModule diff --git a/docs/extending/app-shell.md b/docs/extending/app-shell.md deleted file mode 100644 index b3a5eeab1..000000000 --- a/docs/extending/app-shell.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -Title: Shell ---- - -# Shell - -[AppShellModule](../../app/src/app/app-shell/app-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](../../app/src/app/app-shell/app-shell.routes.ts) - -If you would like to provide custom app guard, you can provide your own using [SHELL_AUTH_TOKEN](../../app/src/app/app-shell/app-shell.routes.ts) - -## Shell Service - -In order to use `shell`, you need to provide `SHELL_APP_SERVICE` which provides necessary options for shell component to work. \ No newline at end of file diff --git a/tsconfig.adf.json b/tsconfig.adf.json index 159920bc4..69319edb8 100644 --- a/tsconfig.adf.json +++ b/tsconfig.adf.json @@ -24,6 +24,7 @@ "@alfresco/adf-testing/shared": ["../alfresco-ng2-components/lib/testing/src/lib/shared"], "@alfresco/adf-core": ["../alfresco-ng2-components/lib/core"], "@alfresco/adf-core/*": ["../alfresco-ng2-components/lib/core/*/public-api.ts"], + "@alfresco/adf-core/shell": ["../alfresco-ng2-components/lib/core/shell/src/index.ts"], "@alfresco/adf-core/auth": ["../alfresco-ng2-components/lib/core/auth/src/index.ts"], "@alfresco/adf-extensions": ["../alfresco-ng2-components/lib/extensions"], "@alfresco/adf-content-services": ["../alfresco-ng2-components/lib/content-services"],