mirror of
https://github.com/Alfresco/alfresco-content-app.git
synced 2025-07-31 17:38:28 +00:00
[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:
@@ -24,6 +24,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { ElementFinder, ElementArrayFinder, by, element } from 'protractor';
|
import { ElementFinder, ElementArrayFinder, by, element } from 'protractor';
|
||||||
|
import { SIDEBAR_LABELS } from '../../configs';
|
||||||
import { Menu } from '../menu/menu';
|
import { Menu } from '../menu/menu';
|
||||||
import { Component } from '../component';
|
import { Component } from '../component';
|
||||||
import { Utils } from '../../utilities/utils';
|
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) {
|
async expandMenu(label: string) {
|
||||||
try{
|
try{
|
||||||
|
|
||||||
@@ -117,4 +122,5 @@ export class Sidenav extends Component {
|
|||||||
console.log('---- sidebar navigation catch expandMenu: ', e);
|
console.log('---- sidebar navigation catch expandMenu: ', e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -63,6 +63,17 @@ export class BrowsingPage extends Page {
|
|||||||
await this.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.MY_LIBRARIES);
|
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() {
|
async clickRecentFilesAndWait() {
|
||||||
await this.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.RECENT_FILES);
|
await this.sidenav.navigateToLinkByLabel(SIDEBAR_LABELS.RECENT_FILES);
|
||||||
|
@@ -89,10 +89,16 @@ describe('Breadcrumb', () => {
|
|||||||
expect(await breadcrumb.getCurrentItemName()).toBe('Personal Files');
|
expect(await breadcrumb.getCurrentItemName()).toBe('Personal Files');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('File Libraries breadcrumb main node - [C260966]', async () => {
|
it('My Libraries breadcrumb main node - [C260966]', async () => {
|
||||||
await page.clickFileLibraries();
|
await page.clickMyLibraries();
|
||||||
expect(await breadcrumb.getItemsCount()).toEqual(1, 'Breadcrumb has incorrect number of items');
|
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 () => {
|
it('Recent Files breadcrumb main node - [C260971]', async () => {
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
<app-page-layout>
|
<app-page-layout>
|
||||||
|
|
||||||
<app-page-layout-header>
|
<app-page-layout-header>
|
||||||
<adf-breadcrumb root="APP.BROWSE.LIBRARIES.TITLE">
|
<adf-breadcrumb root="APP.BROWSE.LIBRARIES.MENU.MY_LIBRARIES.TITLE">
|
||||||
</adf-breadcrumb>
|
</adf-breadcrumb>
|
||||||
|
|
||||||
<adf-toolbar class="inline">
|
<adf-toolbar class="inline">
|
||||||
|
119
src/app/components/sidenav/expansion-panel.directive.spec.ts
Normal file
119
src/app/components/sidenav/expansion-panel.directive.spec.ts
Normal 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);
|
||||||
|
});
|
||||||
|
});
|
83
src/app/components/sidenav/expansion-panel.directive.ts
Normal file
83
src/app/components/sidenav/expansion-panel.directive.ts
Normal 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)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@@ -39,7 +39,10 @@
|
|||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container *ngIf="item.children && item.children.length">
|
<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-expansion-panel-header expandedHeight="48px" collapsedHeight="48px">
|
||||||
<mat-panel-title [attr.title]="item.description | translate">
|
<mat-panel-title [attr.title]="item.description | translate">
|
||||||
<mat-icon [color]="routerLink.isActive? 'accent': 'primary'">{{ item.icon }}</mat-icon>
|
<mat-icon [color]="routerLink.isActive? 'accent': 'primary'">{{ item.icon }}</mat-icon>
|
||||||
|
@@ -29,6 +29,7 @@ import { CommonModule } from '@angular/common';
|
|||||||
import { SidenavComponent } from './sidenav.component';
|
import { SidenavComponent } from './sidenav.component';
|
||||||
import { CoreModule } from '@alfresco/adf-core';
|
import { CoreModule } from '@alfresco/adf-core';
|
||||||
import { RouterModule } from '@angular/router';
|
import { RouterModule } from '@angular/router';
|
||||||
|
import { AcaExpansionPanelDirective } from './expansion-panel.directive';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
@@ -37,7 +38,7 @@ import { RouterModule } from '@angular/router';
|
|||||||
RouterModule,
|
RouterModule,
|
||||||
AppCreateMenuModule
|
AppCreateMenuModule
|
||||||
],
|
],
|
||||||
declarations: [SidenavComponent],
|
declarations: [SidenavComponent, AcaExpansionPanelDirective],
|
||||||
exports: [SidenavComponent]
|
exports: [SidenavComponent, AcaExpansionPanelDirective]
|
||||||
})
|
})
|
||||||
export class AppSidenavModule {}
|
export class AppSidenavModule {}
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
<mat-hint *ngIf="libraryTitleExists">{{ 'LIBRARY.HINTS.SITE_TITLE_EXISTS' | translate }}</mat-hint>
|
<mat-hint *ngIf="libraryTitleExists">{{ 'LIBRARY.HINTS.SITE_TITLE_EXISTS' | translate }}</mat-hint>
|
||||||
<mat-error *ngIf="form.controls['title'].hasError('maxlength')">
|
<mat-error *ngIf="form.controls['title'].hasError('maxlength')">
|
||||||
{{ 'LIBRARY.ERRORS.DESCRIPTION_TOO_LONG' | translate }}
|
{{ 'LIBRARY.ERRORS.TITLE_TOO_LONG' | translate }}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
|
@@ -252,8 +252,8 @@
|
|||||||
{
|
{
|
||||||
"id": "app.navbar.libraries.files",
|
"id": "app.navbar.libraries.files",
|
||||||
"order": 100,
|
"order": 100,
|
||||||
"title": "APP.BROWSE.LIBRARIES.MENU.FILE_LIBRARIES.SIDENAV_LINK.LABEL",
|
"title": "APP.BROWSE.LIBRARIES.MENU.MY_LIBRARIES.SIDENAV_LINK.LABEL",
|
||||||
"description": "APP.BROWSE.LIBRARIES.MENU.FILE_LIBRARIES.SIDENAV_LINK.TOOLTIP",
|
"description": "APP.BROWSE.LIBRARIES.MENU.MY_LIBRARIES.SIDENAV_LINK.TOOLTIP",
|
||||||
"route": "libraries"
|
"route": "libraries"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@@ -61,7 +61,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"MENU": {
|
"MENU": {
|
||||||
"FILE_LIBRARIES": {
|
"MY_LIBRARIES": {
|
||||||
"TITLE": "My Libraries",
|
"TITLE": "My Libraries",
|
||||||
"SIDENAV_LINK": {
|
"SIDENAV_LINK": {
|
||||||
"LABEL": "My Libraries",
|
"LABEL": "My Libraries",
|
||||||
|
Reference in New Issue
Block a user