Merge pull request #1234 from Alfresco/dev-pionnegru-ACA-2526

[ACA-2526] Info Drawer - When user selects or inputs value a substantial change occurs
This commit is contained in:
Denys Vuika 2019-10-21 11:44:45 +01:00 committed by GitHub
commit f335bcf708
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 133 additions and 15 deletions

View File

@ -14,8 +14,8 @@
[canNavigateNext]="nextNodeId" [canNavigateNext]="nextNodeId"
[overlayMode]="true" [overlayMode]="true"
(showViewerChange)="onVisibilityChanged($event)" (showViewerChange)="onVisibilityChanged($event)"
(navigateBefore)="onNavigateBefore()" (navigateBefore)="onNavigateBefore($event)"
(navigateNext)="onNavigateNext()" (navigateNext)="onNavigateNext($event)"
> >
<adf-viewer-sidebar *ngIf="infoDrawerOpened$ | async"> <adf-viewer-sidebar *ngIf="infoDrawerOpened$ | async">
<aca-info-drawer [node]="selection.file"></aca-info-drawer> <aca-info-drawer [node]="selection.file"></aca-info-drawer>

View File

@ -91,11 +91,12 @@ describe('PreviewComponent', () => {
it('should navigate to previous node in sub-folder', () => { it('should navigate to previous node in sub-folder', () => {
spyOn(router, 'navigate').and.stub(); spyOn(router, 'navigate').and.stub();
const clickEvent = new MouseEvent('click');
component.previewLocation = 'personal-files'; component.previewLocation = 'personal-files';
component.folderId = 'folder1'; component.folderId = 'folder1';
component.previousNodeId = 'previous1'; component.previousNodeId = 'previous1';
component.onNavigateBefore(); component.onNavigateBefore(clickEvent);
expect(router.navigate).toHaveBeenCalledWith([ expect(router.navigate).toHaveBeenCalledWith([
'personal-files', 'personal-files',
@ -107,11 +108,12 @@ describe('PreviewComponent', () => {
it('should navigate back to previous node in the root path', () => { it('should navigate back to previous node in the root path', () => {
spyOn(router, 'navigate').and.stub(); spyOn(router, 'navigate').and.stub();
const clickEvent = new MouseEvent('click');
component.previewLocation = 'personal-files'; component.previewLocation = 'personal-files';
component.folderId = null; component.folderId = null;
component.previousNodeId = 'previous1'; component.previousNodeId = 'previous1';
component.onNavigateBefore(); component.onNavigateBefore(clickEvent);
expect(router.navigate).toHaveBeenCalledWith([ expect(router.navigate).toHaveBeenCalledWith([
'personal-files', 'personal-files',
@ -122,20 +124,22 @@ describe('PreviewComponent', () => {
it('should not navigate back if node unset', () => { it('should not navigate back if node unset', () => {
spyOn(router, 'navigate').and.stub(); spyOn(router, 'navigate').and.stub();
const clickEvent = new MouseEvent('click');
component.previousNodeId = null; component.previousNodeId = null;
component.onNavigateBefore(); component.onNavigateBefore(clickEvent);
expect(router.navigate).not.toHaveBeenCalled(); expect(router.navigate).not.toHaveBeenCalled();
}); });
it('should navigate to next node in sub-folder', () => { it('should navigate to next node in sub-folder', () => {
spyOn(router, 'navigate').and.stub(); spyOn(router, 'navigate').and.stub();
const clickEvent = new MouseEvent('click');
component.previewLocation = 'personal-files'; component.previewLocation = 'personal-files';
component.folderId = 'folder1'; component.folderId = 'folder1';
component.nextNodeId = 'next1'; component.nextNodeId = 'next1';
component.onNavigateNext(); component.onNavigateNext(clickEvent);
expect(router.navigate).toHaveBeenCalledWith([ expect(router.navigate).toHaveBeenCalledWith([
'personal-files', 'personal-files',
@ -147,11 +151,12 @@ describe('PreviewComponent', () => {
it('should navigate to next node in the root path', () => { it('should navigate to next node in the root path', () => {
spyOn(router, 'navigate').and.stub(); spyOn(router, 'navigate').and.stub();
const clickEvent = new MouseEvent('click');
component.previewLocation = 'personal-files'; component.previewLocation = 'personal-files';
component.folderId = null; component.folderId = null;
component.nextNodeId = 'next1'; component.nextNodeId = 'next1';
component.onNavigateNext(); component.onNavigateNext(clickEvent);
expect(router.navigate).toHaveBeenCalledWith([ expect(router.navigate).toHaveBeenCalledWith([
'personal-files', 'personal-files',
@ -162,9 +167,10 @@ describe('PreviewComponent', () => {
it('should not navigate back if node unset', () => { it('should not navigate back if node unset', () => {
spyOn(router, 'navigate').and.stub(); spyOn(router, 'navigate').and.stub();
const clickEvent = new MouseEvent('click');
component.nextNodeId = null; component.nextNodeId = null;
component.onNavigateNext(); component.onNavigateNext(clickEvent);
expect(router.navigate).not.toHaveBeenCalled(); expect(router.navigate).not.toHaveBeenCalled();
}); });
@ -743,4 +749,48 @@ describe('PreviewComponent', () => {
store.dispatch(new ClosePreviewAction()); store.dispatch(new ClosePreviewAction());
expect(component.navigateToFileLocation).toHaveBeenCalled(); expect(component.navigateToFileLocation).toHaveBeenCalled();
})); }));
describe('Keyboard navigation', () => {
beforeEach(() => {
component.nextNodeId = 'nextNodeId';
component.previousNodeId = 'previousNodeId';
spyOn(router, 'navigate').and.stub();
});
afterEach(() => {
fixture.destroy();
});
it('should not navigate on keyboard event if target is child of sidebar container', () => {
const parent = document.createElement('div');
parent.className = 'adf-viewer__sidebar';
const child = document.createElement('button');
child.addEventListener('keyup', function(e) {
component.onNavigateNext(e);
});
parent.appendChild(child);
document.body.appendChild(parent);
child.dispatchEvent(new KeyboardEvent('keyup', { key: 'ArrowLeft' }));
expect(router.navigate).not.toHaveBeenCalled();
});
it('should not navigate on keyboard event if target is child of dialog container', () => {
const parent = document.createElement('div');
parent.className = 'mat-dialog-container';
const child = document.createElement('button');
child.addEventListener('keyup', function(e) {
component.onNavigateNext(e);
});
parent.appendChild(child);
document.body.appendChild(parent);
child.dispatchEvent(new KeyboardEvent('keyup', { key: 'ArrowLeft' }));
expect(router.navigate).not.toHaveBeenCalled();
});
});
}); });

View File

@ -113,6 +113,11 @@ export class PreviewComponent extends PageComponent
'-TYPE:"lnk:link"' '-TYPE:"lnk:link"'
]; ];
private containersSkipNavigation = [
'adf-viewer__sidebar',
'mat-dialog-container'
];
constructor( constructor(
private contentApi: ContentApiService, private contentApi: ContentApiService,
private preferences: UserPreferencesService, private preferences: UserPreferencesService,
@ -258,7 +263,14 @@ export class PreviewComponent extends PageComponent
} }
/** Handles navigation to a previous document */ /** Handles navigation to a previous document */
onNavigateBefore(): void { onNavigateBefore(event: MouseEvent | KeyboardEvent): void {
if (
event.type !== 'click' &&
this.shouldNavigate(event.target as HTMLElement)
) {
return;
}
if (this.previousNodeId) { if (this.previousNodeId) {
this.router.navigate( this.router.navigate(
this.getPreviewPath(this.folderId, this.previousNodeId) this.getPreviewPath(this.folderId, this.previousNodeId)
@ -267,7 +279,14 @@ export class PreviewComponent extends PageComponent
} }
/** Handles navigation to a next document */ /** Handles navigation to a next document */
onNavigateNext(): void { onNavigateNext(event: MouseEvent | KeyboardEvent): void {
if (
event.type !== 'click' &&
this.shouldNavigate(event.target as HTMLElement)
) {
return;
}
if (this.nextNodeId) { if (this.nextNodeId) {
this.router.navigate(this.getPreviewPath(this.folderId, this.nextNodeId)); this.router.navigate(this.getPreviewPath(this.folderId, this.nextNodeId));
} }
@ -487,4 +506,20 @@ export class PreviewComponent extends PageComponent
return acc; return acc;
}, []); }, []);
} }
private shouldNavigate(element: HTMLElement): boolean {
let currentElement = element.parentElement;
while (currentElement && !this.isChild(currentElement.classList)) {
currentElement = currentElement.parentElement;
}
return !!currentElement;
}
private isChild(list: DOMTokenList): boolean {
return Array.from(list).some((className: string) =>
this.containersSkipNavigation.includes(className)
);
}
} }

View File

@ -15,8 +15,8 @@
(showViewerChange)="onViewerVisibilityChanged()" (showViewerChange)="onViewerVisibilityChanged()"
[canNavigateBefore]="previousNodeId" [canNavigateBefore]="previousNodeId"
[canNavigateNext]="nextNodeId" [canNavigateNext]="nextNodeId"
(navigateBefore)="onNavigateBefore()" (navigateBefore)="onNavigateBefore($event)"
(navigateNext)="onNavigateNext()" (navigateNext)="onNavigateNext($event)"
> >
<adf-viewer-sidebar *ngIf="infoDrawerOpened$ | async"> <adf-viewer-sidebar *ngIf="infoDrawerOpened$ | async">
<aca-info-drawer [node]="selection.file"></aca-info-drawer> <aca-info-drawer [node]="selection.file"></aca-info-drawer>

View File

@ -112,6 +112,10 @@ export class AppViewerComponent implements OnInit, OnDestroy {
fileName: string; fileName: string;
private previewLocation: string; private previewLocation: string;
private containersSkipNavigation = [
'adf-viewer__sidebar',
'mat-dialog-container'
];
constructor( constructor(
private router: Router, private router: Router,
@ -237,13 +241,26 @@ export class AppViewerComponent implements OnInit, OnDestroy {
} }
} }
onNavigateBefore(): void { onNavigateBefore(event: MouseEvent | KeyboardEvent): void {
const location = this.getFileLocation(); if (
event.type !== 'click' &&
this.shouldNavigate(event.target as HTMLElement)
) {
return;
}
const location = this.getFileLocation();
this.store.dispatch(new ViewNodeAction(this.previousNodeId, { location })); this.store.dispatch(new ViewNodeAction(this.previousNodeId, { location }));
} }
onNavigateNext(): void { onNavigateNext(event: MouseEvent | KeyboardEvent): void {
if (
event.type !== 'click' &&
this.shouldNavigate(event.target as HTMLElement)
) {
return;
}
const location = this.getFileLocation(); const location = this.getFileLocation();
this.store.dispatch(new ViewNodeAction(this.nextNodeId, { location })); this.store.dispatch(new ViewNodeAction(this.nextNodeId, { location }));
} }
@ -437,4 +454,20 @@ export class AppViewerComponent implements OnInit, OnDestroy {
.parseUrl(this.navigationPath || this.router.url) .parseUrl(this.navigationPath || this.router.url)
.root.children[PRIMARY_OUTLET].toString(); .root.children[PRIMARY_OUTLET].toString();
} }
private shouldNavigate(element: HTMLElement): boolean {
let currentElement = element.parentElement;
while (currentElement && !this.isChild(currentElement.classList)) {
currentElement = currentElement.parentElement;
}
return !!currentElement;
}
private isChild(list: DOMTokenList): boolean {
return Array.from(list).some((className: string) =>
this.containersSkipNavigation.includes(className)
);
}
} }