From aaea3bad0cebaa525e4526c2375364e5f8cee136 Mon Sep 17 00:00:00 2001 From: Cilibiu Bogdan Date: Thu, 24 May 2018 22:51:17 +0300 Subject: [PATCH] sidenav view manager (#366) --- src/app/app.module.ts | 2 + .../components/layout/layout.component.html | 6 +- .../layout/layout.component.spec.ts | 37 ++-------- src/app/components/layout/layout.component.ts | 48 ++++--------- .../layout/sidenav-views-manager.directive.ts | 72 +++++++++++++++++++ 5 files changed, 96 insertions(+), 69 deletions(-) create mode 100644 src/app/components/layout/sidenav-views-manager.directive.ts diff --git a/src/app/app.module.ts b/src/app/app.module.ts index f12f94d52..4ff689b40 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -45,6 +45,7 @@ import { RecentFilesComponent } from './components/recent-files/recent-files.com import { SharedFilesComponent } from './components/shared-files/shared-files.component'; import { TrashcanComponent } from './components/trashcan/trashcan.component'; import { LayoutComponent } from './components/layout/layout.component'; +import { SidenavViewsManagerDirective } from './components/layout/sidenav-views-manager.directive'; import { HeaderComponent } from './components/header/header.component'; import { CurrentUserComponent } from './components/current-user/current-user.component'; import { SearchInputComponent } from './components/search-input/search-input.component'; @@ -93,6 +94,7 @@ import { HybridAppConfigService } from './common/services/hybrid-app-config.serv GenericErrorComponent, LoginComponent, LayoutComponent, + SidenavViewsManagerDirective, HeaderComponent, CurrentUserComponent, SearchInputComponent, diff --git a/src/app/components/layout/layout.component.html b/src/app/components/layout/layout.component.html index 090d002c0..754195e4c 100644 --- a/src/app/components/layout/layout.component.html +++ b/src/app/components/layout/layout.component.html @@ -4,12 +4,14 @@ [disabled]="!permission.check(node, ['create'])"> + (expanded)="sidenavManager.setState($event)"> diff --git a/src/app/components/layout/layout.component.spec.ts b/src/app/components/layout/layout.component.spec.ts index 0424abf35..f89274906 100644 --- a/src/app/components/layout/layout.component.spec.ts +++ b/src/app/components/layout/layout.component.spec.ts @@ -40,6 +40,7 @@ import { Observable } from 'rxjs/Observable'; import { BrowsingFilesService } from '../../common/services/browsing-files.service'; import { NodePermissionService } from '../../common/services/node-permission.service'; import { LayoutComponent } from './layout.component'; +import { SidenavViewsManagerDirective } from './sidenav-views-manager.directive'; describe('LayoutComponent', () => { let fixture: ComponentFixture; @@ -47,6 +48,7 @@ describe('LayoutComponent', () => { let browsingFilesService: BrowsingFilesService; let appConfig: AppConfigService; let userPreference: UserPreferencesService; + const navItem = { label: 'some-label', route: { @@ -62,7 +64,8 @@ describe('LayoutComponent', () => { RouterTestingModule ], declarations: [ - LayoutComponent + LayoutComponent, + SidenavViewsManagerDirective ], providers: [ { provide: TranslationService, useClass: TranslationMock }, @@ -165,37 +168,5 @@ describe('LayoutComponent', () => { expect(component.expandedSidenav).toBe(false); }); - - it('should set expandedSidenav to true if configuration is true', () => { - spyOn(userPreference, 'set'); - - appConfig.config = { - sideNav: { - expandedSidenav: false, - preserveState: true - } - }; - - fixture.detectChanges(); - component.setState(true); - - expect(userPreference.set).toHaveBeenCalledWith( 'expandedSidenav', true); - }); - - it('should set expandedSidenav to false if configuration is true', () => { - spyOn(userPreference, 'set'); - - appConfig.config = { - sideNav: { - expandedSidenav: false, - preserveState: true - } - }; - - fixture.detectChanges(); - component.setState(false); - - expect(userPreference.set).toHaveBeenCalledWith( 'expandedSidenav', false); - }); }); }); diff --git a/src/app/components/layout/layout.component.ts b/src/app/components/layout/layout.component.ts index 1800a8ddc..4f1cf43bc 100644 --- a/src/app/components/layout/layout.component.ts +++ b/src/app/components/layout/layout.component.ts @@ -23,13 +23,12 @@ * along with Alfresco. If not, see . */ -import { Component, OnInit, OnDestroy } from '@angular/core'; -import { Router, NavigationEnd } from '@angular/router'; +import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core'; import { Subscription } from 'rxjs/Rx'; import { MinimalNodeEntryEntity } from 'alfresco-js-api'; -import { UserPreferencesService, AppConfigService } from '@alfresco/adf-core'; import { BrowsingFilesService } from '../../common/services/browsing-files.service'; import { NodePermissionService } from '../../common/services/node-permission.service'; +import { SidenavViewsManagerDirective } from './sidenav-views-manager.directive'; @Component({ selector: 'app-layout', @@ -37,27 +36,25 @@ import { NodePermissionService } from '../../common/services/node-permission.ser styleUrls: ['./layout.component.scss'] }) export class LayoutComponent implements OnInit, OnDestroy { - node: MinimalNodeEntryEntity; - hideSidenav: boolean; + @ViewChild(SidenavViewsManagerDirective) manager: SidenavViewsManagerDirective; + expandedSidenav: boolean; - private hideConditions: string[] = ['preview']; + node: MinimalNodeEntryEntity; + private subscriptions: Subscription[] = []; constructor( - private router: Router, private browsingFilesService: BrowsingFilesService, - private userPreferenceService: UserPreferencesService, - private appConfigService: AppConfigService, - public permission: NodePermissionService) { - this.router.events - .filter(event => event instanceof NavigationEnd) - .subscribe( (event: any ) => { - this.hideSidenav = this.hideConditions.some(el => event.urlAfterRedirects.includes(el)); - }); - } + public permission: NodePermissionService) {} ngOnInit() { - this.expandedSidenav = this.sidenavState; + if (!this.manager.minimizeSidenav) { + this.expandedSidenav = this.manager.sidenavState; + } else { + this.expandedSidenav = false; + } + + this.manager.run(true); this.subscriptions.concat([ this.browsingFilesService.onChangeParent.subscribe((node: MinimalNodeEntryEntity) => this.node = node) @@ -67,21 +64,4 @@ export class LayoutComponent implements OnInit, OnDestroy { ngOnDestroy() { this.subscriptions.forEach(s => s.unsubscribe()); } - - get sidenavState(): boolean { - const expand = this.appConfigService.get('sideNav.expandedSidenav', true); - const preserveState = this.appConfigService.get('sideNav.preserveState', true); - - if (preserveState) { - return (this.userPreferenceService.get('expandedSidenav', expand.toString()) === 'true'); - } - - return expand; - } - - setState(state) { - if (this.appConfigService.get('sideNav.preserveState')) { - this.userPreferenceService.set('expandedSidenav', state); - } - } } diff --git a/src/app/components/layout/sidenav-views-manager.directive.ts b/src/app/components/layout/sidenav-views-manager.directive.ts new file mode 100644 index 000000000..513073faa --- /dev/null +++ b/src/app/components/layout/sidenav-views-manager.directive.ts @@ -0,0 +1,72 @@ +import { Directive, ContentChild } from '@angular/core'; +import { Router, NavigationEnd } from '@angular/router'; +import { UserPreferencesService, AppConfigService, SidenavLayoutComponent } from '@alfresco/adf-core'; + +@Directive({ + selector: '[acaSidenavManager]', + exportAs: 'acaSidenavManager' +}) +export class SidenavViewsManagerDirective { + + @ContentChild(SidenavLayoutComponent) sidenavLayout: SidenavLayoutComponent; + + minimizeSidenav = false; + hideSidenav = false; + + private _run = false; + private minimizeConditions: string[] = ['search']; + private hideConditions: string[] = ['preview']; + + constructor( + private router: Router, + private userPreferenceService: UserPreferencesService, + private appConfigService: AppConfigService + ) { + this.router.events + .filter(event => event instanceof NavigationEnd) + .subscribe( (event: any ) => { + this.minimizeSidenav = this.minimizeConditions.some(el => event.urlAfterRedirects.includes(el)); + this.hideSidenav = this.hideConditions.some(el => event.urlAfterRedirects.includes(el)); + + if (this._run) { + this.manageSidenavState(); + } + }); + + } + + run (shouldRun) { + this._run = shouldRun; + } + + manageSidenavState() { + if (this.minimizeSidenav && !this.sidenavLayout.isMenuMinimized) { + this.sidenavLayout.isMenuMinimized = true; + this.sidenavLayout.container.toggleMenu(); + } + + if (!this.minimizeSidenav) { + if (this.sidenavState && this.sidenavLayout.isMenuMinimized) { + this.sidenavLayout.isMenuMinimized = false; + this.sidenavLayout.container.toggleMenu(); + } + } + } + + setState(state) { + if (!this.minimizeSidenav && this.appConfigService.get('sideNav.preserveState')) { + this.userPreferenceService.set('expandedSidenav', state); + } + } + + get sidenavState(): boolean { + const expand = this.appConfigService.get('sideNav.expandedSidenav', true); + const preserveState = this.appConfigService.get('sideNav.preserveState', true); + + if (preserveState) { + return (this.userPreferenceService.get('expandedSidenav', expand.toString()) === 'true'); + } + + return expand; + } +}