[ACA-20] Sidenav - navigate to first child route when expanded for the first time (#798)

* bradcrumb root title

* use correct i18n string reference

* expansion panel state directive

* takeUntil

* fix text

* parameter type

* fix title error message reference

* fix My Libraries test and add separate one for Favourite Libraries
This commit is contained in:
Cilibiu Bogdan
2018-11-14 12:09:24 +02:00
committed by GitHub
parent b592ea8635
commit 031198e784
11 changed files with 240 additions and 11 deletions

View File

@@ -24,6 +24,7 @@
*/
import { ElementFinder, ElementArrayFinder, by, element } from 'protractor';
import { SIDEBAR_LABELS } from '../../configs';
import { Menu } from '../menu/menu';
import { Component } from '../component';
import { Utils } from '../../utilities/utils';
@@ -101,6 +102,10 @@ export class Sidenav extends Component {
}
}
async isFileLibrariesMenuExpanded() {
return await element(by.cssContainingText('.mat-expanded', SIDEBAR_LABELS.FILE_LIBRARIES)).isPresent();
}
async expandMenu(label: string) {
try{
@@ -117,4 +122,5 @@ export class Sidenav extends Component {
console.log('---- sidebar navigation catch expandMenu: ', e);
}
}
}

View File

@@ -63,6 +63,17 @@ export class BrowsingPage extends Page {
await this.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.MY_LIBRARIES);
}
async clickFavoriteLibraries() {
await this.sidenav.expandMenu(SIDEBAR_LABELS.FILE_LIBRARIES);
await this.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.FAVORITE_LIBRARIES);
}
async clickMyLibraries() {
if ( !(await this.sidenav.isFileLibrariesMenuExpanded()) ) {
await this.sidenav.expandMenu(SIDEBAR_LABELS.FILE_LIBRARIES);
}
await this.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.MY_LIBRARIES);
}
async clickRecentFilesAndWait() {
await this.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.RECENT_FILES);

View File

@@ -89,10 +89,16 @@ describe('Breadcrumb', () => {
expect(await breadcrumb.getCurrentItemName()).toBe('Personal Files');
});
it('File Libraries breadcrumb main node - [C260966]', async () => {
await page.clickFileLibraries();
it('My Libraries breadcrumb main node - [C260966]', async () => {
await page.clickMyLibraries();
expect(await breadcrumb.getItemsCount()).toEqual(1, 'Breadcrumb has incorrect number of items');
expect(await breadcrumb.getCurrentItemName()).toBe('File Libraries');
expect(await breadcrumb.getCurrentItemName()).toBe('My Libraries');
});
it('Favorite Libraries breadcrumb main node - [C289891]', async () => {
await page.clickFavoriteLibraries();
expect(await breadcrumb.getItemsCount()).toEqual(1, 'Breadcrumb has incorrect number of items');
expect(await breadcrumb.getCurrentItemName()).toBe('Favorite Libraries');
});
it('Recent Files breadcrumb main node - [C260971]', async () => {

View File

@@ -1,7 +1,7 @@
<app-page-layout>
<app-page-layout-header>
<adf-breadcrumb root="APP.BROWSE.LIBRARIES.TITLE">
<adf-breadcrumb root="APP.BROWSE.LIBRARIES.MENU.MY_LIBRARIES.TITLE">
</adf-breadcrumb>
<adf-toolbar class="inline">

View File

@@ -0,0 +1,119 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2018 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import { NavigationEnd } from '@angular/router';
import { AcaExpansionPanelDirective } from './expansion-panel.directive';
import { Subject } from 'rxjs';
class RouterStub {
url;
private subject = new Subject();
events = this.subject.asObservable();
constructor(url = 'some-url') {
this.url = url;
}
navigate(nextUrl: string) {
const navigationEnd = new NavigationEnd(0, this.url, nextUrl);
this.subject.next(navigationEnd);
}
}
describe('AcaExpansionPanel', () => {
const item = {
children: [{ url: 'dummy-route-1' }, { url: 'dummy-route-2' }]
};
it('should set panel as selected on initialization if url contains child url', () => {
const router: any = new RouterStub('dummy-route-2');
const directive = new AcaExpansionPanelDirective(router, null);
directive.acaExpansionPanel = item;
directive.ngOnInit();
expect(directive.selected).toBe(true);
});
it('should not set panel as selected on initialization if url does not contain child url', () => {
const router: any = new RouterStub('dummy-route-other');
const directive = new AcaExpansionPanelDirective(router, null);
directive.acaExpansionPanel = item;
directive.ngOnInit();
expect(directive.selected).toBe(false);
});
it('should go on first child url when expended and url does not contain any child url', () => {
const router: any = new RouterStub();
spyOn(router, 'navigate');
const expansionPanelInstance: any = { expanded: true };
const directive = new AcaExpansionPanelDirective(
router,
expansionPanelInstance
);
directive.acaExpansionPanel = item;
directive.ngOnInit();
directive.onClick();
expect(router.navigate).toHaveBeenCalledWith(['dummy-route-1']);
});
it('should not go on first child url when expended and url contains any child url', () => {
const router: any = new RouterStub('dummy-route-2');
spyOn(router, 'navigate');
const expansionPanelInstance: any = { expanded: true };
const directive = new AcaExpansionPanelDirective(
router,
expansionPanelInstance
);
directive.acaExpansionPanel = item;
directive.ngOnInit();
directive.onClick();
expect(router.navigate).not.toHaveBeenCalled();
});
it('should set panel selected on navigation change', done => {
const router: any = new RouterStub();
const directive = new AcaExpansionPanelDirective(router, null);
directive.acaExpansionPanel = item;
directive.ngOnInit();
router.navigate('dummy-route-1');
done();
expect(directive.selected).toBe(true);
router.navigate('some-url');
done();
expect(directive.selected).toBe(false);
});
});

View File

@@ -0,0 +1,83 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2018 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
import {
Directive,
OnInit,
Input,
HostListener,
OnDestroy
} from '@angular/core';
import { Router, NavigationEnd } from '@angular/router';
import { filter, takeUntil } from 'rxjs/operators';
import { Subject } from 'rxjs';
import { MatExpansionPanel } from '@angular/material/expansion';
@Directive({
selector: '[acaExpansionPanel]',
exportAs: 'acaExpansionPanel'
})
export class AcaExpansionPanelDirective implements OnInit, OnDestroy {
@Input() acaExpansionPanel;
selected = false;
private onDestroy$: Subject<boolean> = new Subject<boolean>();
@HostListener('click')
onClick() {
if (this.expansionPanel.expanded && !this.selected) {
this.router.navigate([this.acaExpansionPanel.children[0].url]);
}
}
constructor(
private router: Router,
private expansionPanel: MatExpansionPanel
) {}
ngOnInit() {
this.setSelected(this.router.url);
this.router.events
.pipe(
filter(event => event instanceof NavigationEnd),
takeUntil(this.onDestroy$)
)
.subscribe((event: NavigationEnd) => {
this.setSelected(event.urlAfterRedirects);
});
}
ngOnDestroy() {
this.onDestroy$.next(true);
this.onDestroy$.complete();
}
private setSelected(url: string) {
this.selected = this.acaExpansionPanel.children.some(child =>
url.startsWith(child.url)
);
}
}

View File

@@ -39,7 +39,10 @@
</ng-container>
<ng-container *ngIf="item.children && item.children.length">
<mat-expansion-panel [expanded]="routerLink.isActive" [@.disabled]="true">
<mat-expansion-panel
[acaExpansionPanel]="item"
[expanded]="routerLink.isActive"
[@.disabled]="true">
<mat-expansion-panel-header expandedHeight="48px" collapsedHeight="48px">
<mat-panel-title [attr.title]="item.description | translate">
<mat-icon [color]="routerLink.isActive? 'accent': 'primary'">{{ item.icon }}</mat-icon>

View File

@@ -29,6 +29,7 @@ import { CommonModule } from '@angular/common';
import { SidenavComponent } from './sidenav.component';
import { CoreModule } from '@alfresco/adf-core';
import { RouterModule } from '@angular/router';
import { AcaExpansionPanelDirective } from './expansion-panel.directive';
@NgModule({
imports: [
@@ -37,7 +38,7 @@ import { RouterModule } from '@angular/router';
RouterModule,
AppCreateMenuModule
],
declarations: [SidenavComponent],
exports: [SidenavComponent]
declarations: [SidenavComponent, AcaExpansionPanelDirective],
exports: [SidenavComponent, AcaExpansionPanelDirective]
})
export class AppSidenavModule {}

View File

@@ -14,7 +14,7 @@
<mat-hint *ngIf="libraryTitleExists">{{ 'LIBRARY.HINTS.SITE_TITLE_EXISTS' | translate }}</mat-hint>
<mat-error *ngIf="form.controls['title'].hasError('maxlength')">
{{ 'LIBRARY.ERRORS.DESCRIPTION_TOO_LONG' | translate }}
{{ 'LIBRARY.ERRORS.TITLE_TOO_LONG' | translate }}
</mat-error>
</mat-form-field>

View File

@@ -252,8 +252,8 @@
{
"id": "app.navbar.libraries.files",
"order": 100,
"title": "APP.BROWSE.LIBRARIES.MENU.FILE_LIBRARIES.SIDENAV_LINK.LABEL",
"description": "APP.BROWSE.LIBRARIES.MENU.FILE_LIBRARIES.SIDENAV_LINK.TOOLTIP",
"title": "APP.BROWSE.LIBRARIES.MENU.MY_LIBRARIES.SIDENAV_LINK.LABEL",
"description": "APP.BROWSE.LIBRARIES.MENU.MY_LIBRARIES.SIDENAV_LINK.TOOLTIP",
"route": "libraries"
},
{

View File

@@ -61,7 +61,7 @@
}
},
"MENU": {
"FILE_LIBRARIES": {
"MY_LIBRARIES": {
"TITLE": "My Libraries",
"SIDENAV_LINK": {
"LABEL": "My Libraries",