From f8d1480f29e48c37498f25ec329b1f1ff6d184dc Mon Sep 17 00:00:00 2001 From: Eugenio Romano Date: Fri, 13 Apr 2018 10:08:02 +0100 Subject: [PATCH] [ADF-2682] Fix pagination, bradcrumb, general reload scenarios (#3184) * skipcount page reset in new folder * fix files component reload multiple times * fix folderNode scenario --- demo-shell/src/app/app.routes.ts | 3 +- .../app/components/files/files.component.html | 2 - .../app/components/files/files.component.ts | 64 +++++-------------- .../breadcrumb/breadcrumb.component.ts | 2 +- .../navigable-component.interface.ts | 20 ++++++ lib/content-services/breadcrumb/public-api.ts | 1 + .../document-list.component.spec.ts | 4 +- .../components/document-list.component.ts | 59 ++++++++--------- 8 files changed, 70 insertions(+), 85 deletions(-) create mode 100644 lib/content-services/breadcrumb/navigable-component.interface.ts diff --git a/demo-shell/src/app/app.routes.ts b/demo-shell/src/app/app.routes.ts index 6c8b8b166c..16e2693843 100644 --- a/demo-shell/src/app/app.routes.ts +++ b/demo-shell/src/app/app.routes.ts @@ -80,8 +80,7 @@ export const appRoutes: Routes = [ }, { path: 'files', - component: FilesComponent, - canActivate: [AuthGuardEcm] + redirectTo: 'files/-my-' }, { path: 'files/:id', diff --git a/demo-shell/src/app/components/files/files.component.html b/demo-shell/src/app/components/files/files.component.html index 8a51b8c35f..c55424740f 100644 --- a/demo-shell/src/app/components/files/files.component.html +++ b/demo-shell/src/app/components/files/files.component.html @@ -50,7 +50,6 @@ @@ -193,7 +192,6 @@ (success)="resetError()" (ready)="emitReadyEvent($event)" (preview)="showFile($event)" - (folderChange)="onFolderChange($event)" (permissionError)="handlePermissionError($event)"> diff --git a/demo-shell/src/app/components/files/files.component.ts b/demo-shell/src/app/components/files/files.component.ts index b5bd1018a5..3f9a86ca93 100644 --- a/demo-shell/src/app/components/files/files.component.ts +++ b/demo-shell/src/app/components/files/files.component.ts @@ -15,20 +15,12 @@ * limitations under the License. */ -import { - Component, Input, OnInit, OnChanges, OnDestroy, ChangeDetectorRef, - EventEmitter, Optional, ViewChild, SimpleChanges, Output +import { Component, Input, OnInit, OnChanges, OnDestroy, + EventEmitter, ViewChild, SimpleChanges, Output } from '@angular/core'; import { MatDialog } from '@angular/material'; -import { ActivatedRoute, Params, Router } from '@angular/router'; -import { - MinimalNodeEntity, - NodePaging, - Pagination, - PathElementEntity, - MinimalNodeEntryEntity, - SiteEntry -} from 'alfresco-js-api'; +import { Router } from '@angular/router'; +import { MinimalNodeEntity, NodePaging, Pagination, MinimalNodeEntryEntity, SiteEntry } from 'alfresco-js-api'; import { AuthenticationService, AppConfigService, ContentService, TranslationService, FileUploadEvent, FolderCreatedEvent, LogService, NotificationService, @@ -70,8 +62,8 @@ export class FilesComponent implements OnInit, OnChanges, OnDestroy { { value: 'multiple', viewValue: 'Multiple' } ]; + // The identifier of a node. You can also use one of these well-known aliases: -my- | -shared- | -root- @Input() - // The identifier of a node. You can also use one of these well-known aliases: -my- | -shared- | -root- currentFolderId: string = DEFAULT_FOLDER_TO_SHOW; formValues: FormValues = {}; @@ -157,8 +149,7 @@ export class FilesComponent implements OnInit, OnChanges, OnDestroy { private onCreateFolder: Subscription; private onEditFolder: Subscription; - constructor(private changeDetector: ChangeDetectorRef, - private notificationService: NotificationService, + constructor(private notificationService: NotificationService, private uploadService: UploadService, private contentService: ContentService, private dialog: MatDialog, @@ -166,7 +157,6 @@ export class FilesComponent implements OnInit, OnChanges, OnDestroy { private router: Router, private logService: LogService, private preference: UserPreferencesService, - @Optional() private route: ActivatedRoute, private appConfig: AppConfigService, public authenticationService: AuthenticationService) { this.preference.select(UserPreferenceValues.SupportedPageSizes) @@ -182,15 +172,6 @@ export class FilesComponent implements OnInit, OnChanges, OnDestroy { } } - onFolderChange($event) { - this.currentFolderId = $event.value.id; - this.router.navigate(['/files', $event.value.id]); - } - - onBreadcrumbNavigate(route: PathElementEntity) { - this.router.navigate(['/files', route.id]); - } - toggleFolder() { this.multipleFileUpload = false; this.folderUpload = !this.folderUpload; @@ -204,14 +185,6 @@ export class FilesComponent implements OnInit, OnChanges, OnDestroy { skipCount: 0 }; } - if (this.route) { - this.route.params.forEach((params: Params) => { - if (params['id']) { - this.currentFolderId = params['id']; - this.changeDetector.detectChanges(); - } - }); - } // this.disableDragArea = false; this.uploadService.fileUploadComplete.asObservable().debounceTime(300).subscribe(value => this.onFileUploadEvent(value)); @@ -294,10 +267,7 @@ export class FilesComponent implements OnInit, OnChanges, OnDestroy { action: event.action, type: event.type }).subscribe((message) => { - this.notificationService.openSnackMessage( - message, - 4000 - ); + this.openSnackMessage(message); }); } @@ -308,13 +278,9 @@ export class FilesComponent implements OnInit, OnChanges, OnDestroy { ); } - emitReadyEvent(event: any) { - if (this.standardPagination && this.pageIsEmpty(event)) { - this.standardPagination.goPrevious(); - } else { - this.documentListReady.emit(event); - this.pagination = event.list.pagination; - } + emitReadyEvent(event: NodePaging) { + this.documentListReady.emit(event); + this.router.navigate(['/files', event.list.source.id]); } pageIsEmpty(node: NodePaging) { @@ -336,12 +302,12 @@ export class FilesComponent implements OnInit, OnChanges, OnDestroy { translatedErrorMessage = this.translateService.get('OPERATION.ERROR.UNKNOWN'); } - this.notificationService.openSnackMessage(translatedErrorMessage.value, 4000); + this.openSnackMessage(translatedErrorMessage.value); } onContentActionSuccess(message) { const translatedMessage: any = this.translateService.get(message); - this.notificationService.openSnackMessage(translatedMessage.value, 4000); + this.openSnackMessage(translatedMessage.value); this.reloadForInfiniteScrolling(); } @@ -349,7 +315,7 @@ export class FilesComponent implements OnInit, OnChanges, OnDestroy { this.uploadService.fileDeleted.next(message); this.deleteElementSuccess.emit(); this.reloadForInfiniteScrolling(); - this.notificationService.openSnackMessage(message, 4000); + this.openSnackMessage(message); } onPermissionRequested(node) { @@ -376,7 +342,7 @@ export class FilesComponent implements OnInit, OnChanges, OnDestroy { }); } else { const translatedErrorMessage: any = this.translateService.get('OPERATION.ERROR.PERMISSION'); - this.notificationService.openSnackMessage(translatedErrorMessage.value, 4000); + this.openSnackMessage(translatedErrorMessage.value); } } @@ -391,7 +357,7 @@ export class FilesComponent implements OnInit, OnChanges, OnDestroy { }); } else { const translatedErrorMessage: any = this.translateService.get('OPERATION.ERROR.PERMISSION'); - this.notificationService.openSnackMessage(translatedErrorMessage.value, 4000); + this.openSnackMessage(translatedErrorMessage.value); } } diff --git a/lib/content-services/breadcrumb/breadcrumb.component.ts b/lib/content-services/breadcrumb/breadcrumb.component.ts index aafeb39cf4..564d9197b6 100644 --- a/lib/content-services/breadcrumb/breadcrumb.component.ts +++ b/lib/content-services/breadcrumb/breadcrumb.component.ts @@ -144,7 +144,7 @@ export class BreadcrumbComponent implements OnInit, OnChanges { this.navigate.emit(route); if (this.target) { - this.target.loadFolderByNodeId(route.id); + this.target.navigateTo(route.id); } } } diff --git a/lib/content-services/breadcrumb/navigable-component.interface.ts b/lib/content-services/breadcrumb/navigable-component.interface.ts new file mode 100644 index 0000000000..903f84a7b4 --- /dev/null +++ b/lib/content-services/breadcrumb/navigable-component.interface.ts @@ -0,0 +1,20 @@ +/*! + * @license + * Copyright 2016 Alfresco Software, Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export interface NavigableComponentInterface { + navigateTo(nodeId: string); +} diff --git a/lib/content-services/breadcrumb/public-api.ts b/lib/content-services/breadcrumb/public-api.ts index 1e8ac5ddb4..f3bab7fe2e 100644 --- a/lib/content-services/breadcrumb/public-api.ts +++ b/lib/content-services/breadcrumb/public-api.ts @@ -17,5 +17,6 @@ export * from './breadcrumb.component'; export * from './dropdown-breadcrumb.component'; +export * from './navigable-component.interface'; export * from './breadcrumb.module'; diff --git a/lib/content-services/document-list/components/document-list.component.spec.ts b/lib/content-services/document-list/components/document-list.component.spec.ts index b1cf9176b0..053065ce46 100644 --- a/lib/content-services/document-list/components/document-list.component.spec.ts +++ b/lib/content-services/document-list/components/document-list.component.spec.ts @@ -898,10 +898,10 @@ describe('DocumentList', () => { it('should load folder by ID on init', () => { documentList.currentFolderId = '1d26e465-dea3-42f3-b415-faa8364b9692'; - spyOn(documentList, 'loadFolderNodesByFolderNodeId').and.returnValue(Promise.resolve()); + spyOn(documentList, 'loadFolder').and.returnValue(Promise.resolve()); documentList.ngOnChanges({ folderNode: new SimpleChange(null, documentList.currentFolderId, true) }); - expect(documentList.loadFolderNodesByFolderNodeId).toHaveBeenCalled(); + expect(documentList.loadFolder).toHaveBeenCalled(); }); it('should emit error when getFolderNode fails', (done) => { diff --git a/lib/content-services/document-list/components/document-list.component.ts b/lib/content-services/document-list/components/document-list.component.ts index c266c88122..a1030e94b6 100644 --- a/lib/content-services/document-list/components/document-list.component.ts +++ b/lib/content-services/document-list/components/document-list.component.ts @@ -42,6 +42,7 @@ import { PermissionStyleModel } from './../models/permissions-style.model'; import { DocumentListService } from './../services/document-list.service'; import { NodeEntityEvent, NodeEntryEvent } from './node.event'; import { CustomResourcesService } from './../services/custom-resources.service'; +import { NavigableComponentInterface } from '../../breadcrumb/navigable-component.interface'; export enum PaginationStrategy { Finite, @@ -54,7 +55,7 @@ export enum PaginationStrategy { templateUrl: './document-list.component.html', encapsulation: ViewEncapsulation.None }) -export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, AfterContentInit, PaginatedComponent { +export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, AfterContentInit, PaginatedComponent, NavigableComponentInterface { static SINGLE_CLICK_NAVIGATION: string = 'click'; static DOUBLE_CLICK_NAVIGATION: string = 'dblclick'; @@ -167,6 +168,7 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte @Input() currentFolderId: string = null; + /** @deprecated 2.3.0 use currentFolderId or node */ /** Currently displayed folder node */ @Input() folderNode: MinimalNodeEntryEntity = null; @@ -368,18 +370,12 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte this.resetSelection(); if (changes.folderNode && changes.folderNode.currentValue) { + this.currentFolderId = changes.folderNode.currentValue.id; + this.resetNewFolderPagination(); this.loadFolder(); } else if (changes.currentFolderId && changes.currentFolderId.currentValue) { - if (changes.currentFolderId.previousValue !== changes.currentFolderId.currentValue) { - this.folderNode = null; - } - if (!this.hasCustomLayout) { - this.setupDefaultColumns(changes.currentFolderId.currentValue); - } - - this.loading = true; - - this.loadFolderByNodeId(changes.currentFolderId.currentValue); + this.resetNewFolderPagination(); + this.loadFolder(); } else if (this.data) { if (changes.node && changes.node.currentValue) { this.data.loadPage(changes.node.currentValue); @@ -398,15 +394,11 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte reload() { this.ngZone.run(() => { this.resetSelection(); - - if (this.folderNode) { - this.loadFolder(); - } else if (this.currentFolderId) { - this.loading = true; - this.loadFolderByNodeId(this.currentFolderId); - } else if (this.node) { + if (this.node) { this.data.loadPage(this.node); this.onDataReady(this.node); + } else { + this.loadFolder(); } }); } @@ -473,9 +465,9 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte } updateFolderData(node: MinimalNodeEntity): void { + this.folderNode = null; this.currentFolderId = node.entry.id; - this.folderNode = node.entry; - this.loadFolder(); + this.reload(); this.folderChange.emit(new NodeEntryEvent(node.entry)); } @@ -512,13 +504,15 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte this.loading = true; } - let nodeId = this.folderNode ? this.folderNode.id : this.currentFolderId; - if (!this.hasCustomLayout) { - this.setupDefaultColumns(nodeId); + this.setupDefaultColumns(this.currentFolderId); } - if (nodeId) { - this.loadFolderNodesByFolderNodeId(nodeId, this.pagination.getValue()); + + if (this.folderNode) { + return this.loadFolderNodesByFolderNodeId(this.folderNode.id, this.pagination.getValue()) + .catch(err => this.handleError(err)); + } else { + this.loadFolderByNodeId(this.currentFolderId); } } @@ -536,10 +530,6 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte .getFolderNode(nodeId, this.includeFields) .subscribe((node: MinimalNodeEntryEntity) => { this.folderNode = node; - - if (node.id) { - this.currentFolderId = node.id; - } return this.loadFolderNodesByFolderNodeId(node.id, this.pagination.getValue()) .catch(err => this.handleError(err)); }, err => { @@ -746,6 +736,17 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte this.reload(); } + navigateTo(nodeId: string) { + this.currentFolderId = nodeId; + this.resetNewFolderPagination(); + this.loadFolder(); + } + + private resetNewFolderPagination() { + this.folderNode = null; + this.pagination.value.skipCount = 0; + } + // TODO: remove it from here getCorrespondingNodeIds(nodeId: string): Observable { if (this.customResourcesService.isCustomSource(nodeId)) {