[ADF-1805] rebased documentlist pagination removal ()

* [ADF-1805] rebased documentlist pagination removal

* [ADF-1805] fixed some wrong changes]
This commit is contained in:
Vito 2017-11-20 10:40:05 +00:00 committed by Popovics András
parent 0f0f22634a
commit 141bc0f8b4
12 changed files with 198 additions and 249 deletions

@ -30,6 +30,7 @@
"MAX_SIZE" : "Max size filter",
"ENABLE_VERSIONING" :"Enable versioning",
"DESCRIPTION_UPLOAD" : "Enable upload",
"ENABLE_INFINITE_SCROLL":"Enable Infinite Scrolling",
"MULTISELECT_DESCRIPTION" : "Use Cmd (Mac) or Ctrl (Windows) to toggle selection of multiple items",
"COLUMNS": {
"DISPLAY_NAME": "Display name",

@ -115,6 +115,9 @@
</adf-toolbar>
<adf-document-list
#documentList
[maxItems]="currentMaxItems"
[skipCount]="currentSkipCount"
[enableInfiniteScrolling]="infiniteScrolling"
[permissionsStyle]="permissionsStyle"
[currentFolderId]="currentFolderId"
[contextMenuActions]="true"
@ -251,6 +254,24 @@
</content-action>
</content-actions>
</adf-document-list>
<adf-pagination
*ngIf="!infiniteScrolling"
class="adf-documentlist-pagination"
[pagination]="pagination"
[supportedPageSizes]="supportedPages"
(changePageSize)="onChangePageSize($event)"
(changePageNumber)="onChangePageNumber($event)"
(nextPage)="onNextPage($event)"
(prevPage)="onPrevPage($event)">
</adf-pagination>
<adf-infinite-pagination
*ngIf="infiniteScrolling"
[pagination]="pagination"
[loading]="documentList.infiniteLoading"
[pageSize]="currentMaxItems"
(loadMore)="loadNextBatch($event)">
{{ 'ADF-DOCUMENT-LIST.LAYOUT.LOAD_MORE' | translate }}
</adf-infinite-pagination>
</adf-upload-drag-area>
<adf-info-drawer-layout *ngIf="showVersions" class="adf-manage-versions-sidebar" fxFlex="0 0 auto">
<div info-drawer-content>
@ -330,6 +351,12 @@
</mat-slide-toggle>
</section>
<section>
<mat-slide-toggle [color]="'primary'" [(ngModel)]="infiniteScrolling">
{{'DOCUMENT_LIST.ENABLE_INFINITE_SCROLL' | translate}}
</mat-slide-toggle>
</section>
<h5>Upload</h5>
<section *ngIf="acceptedFilesTypeShow">
<mat-form-field>

@ -21,11 +21,11 @@ import {
} from '@angular/core';
import { MatDialog } from '@angular/material';
import { ActivatedRoute, Params, Router } from '@angular/router';
import { MinimalNodeEntity, NodePaging } from 'alfresco-js-api';
import { MinimalNodeEntity, NodePaging, Pagination } from 'alfresco-js-api';
import {
AlfrescoApiService, ContentService, TranslationService,
FileUploadEvent, FolderCreatedEvent, LogService, NotificationService,
SiteModel, UploadService, DataColumn, DataRow
SiteModel, UploadService, DataColumn, DataRow, UserPreferencesService
} from '@alfresco/adf-core';
import { DocumentListComponent, PermissionStyleModel, DownloadZipDialogComponent } from '@alfresco/adf-content-services';
@ -92,13 +92,35 @@ export class FilesComponent implements OnInit, OnChanges, OnDestroy {
@Input()
nodeResult: NodePaging;
@Input()
pagination: Pagination;
@Output()
documentListReady: EventEmitter<any> = new EventEmitter();
@Output()
changedPageSize: EventEmitter<Pagination> = new EventEmitter();
@Output()
changedPageNumber: EventEmitter<Pagination> = new EventEmitter();
@Output()
turnedNextPage: EventEmitter<Pagination> = new EventEmitter();
@Output()
turnedPreviousPage: EventEmitter<Pagination> = new EventEmitter();
@Output()
loadNext: EventEmitter<Pagination> = new EventEmitter();
@ViewChild(DocumentListComponent)
documentList: DocumentListComponent;
permissionsStyle: PermissionStyleModel[] = [];
supportedPages: number[] = [5, 10, 15, 20];
infiniteScrolling: boolean;
currentMaxItems: number;
currentSkipCount: number = 0;
private onCreateFolder: Subscription;
private onEditFolder: Subscription;
@ -112,7 +134,8 @@ export class FilesComponent implements OnInit, OnChanges, OnDestroy {
private translateService: TranslationService,
private router: Router,
@Optional() private route: ActivatedRoute,
private logService: LogService) {
private logService: LogService,
private preference: UserPreferencesService) {
}
showFile(event) {
@ -134,6 +157,13 @@ export class FilesComponent implements OnInit, OnChanges, OnDestroy {
}
ngOnInit() {
if (!this.pagination) {
this.pagination = <Pagination>{
maxItems: this.preference.paginationSize,
skipCount: 0
};
this.currentMaxItems = this.preference.paginationSize;
}
if (this.route) {
this.route.params.forEach((params: Params) => {
if (params['id']) {
@ -225,6 +255,7 @@ export class FilesComponent implements OnInit, OnChanges, OnDestroy {
emitReadyEvent(event: any) {
this.documentListReady.emit(event);
this.pagination = event.list.pagination;
}
onContentActionError(errors) {
@ -376,4 +407,35 @@ export class FilesComponent implements OnInit, OnChanges, OnDestroy {
}
return false;
}
onChangePageSize(event: Pagination): void {
this.preference.paginationSize = event.maxItems;
this.currentMaxItems = event.maxItems;
this.currentSkipCount = event.skipCount;
this.changedPageSize.emit(event);
}
onChangePageNumber(event: Pagination): void {
this.currentMaxItems = event.maxItems;
this.currentSkipCount = event.skipCount;
this.changedPageNumber.emit(event);
}
onNextPage(event: Pagination): void {
this.currentMaxItems = event.maxItems;
this.currentSkipCount = event.skipCount;
this.turnedNextPage.emit(event);
}
loadNextBatch(event: Pagination) {
this.currentMaxItems = event.maxItems;
this.currentSkipCount = event.skipCount;
this.loadNext.emit(event);
}
onPrevPage(event: Pagination): void {
this.currentMaxItems = event.maxItems;
this.currentSkipCount = event.skipCount;
this.turnedPreviousPage.emit(event);
}
}

@ -1,4 +1,6 @@
<adf-search [searchTerm]="searchedWord"
[maxResults]="maxItems"
[skipResults]="skipCount"
(resultLoaded)="showSearchResult($event)"
#search>
</adf-search>
@ -6,5 +8,10 @@
<adf-files-component
[currentFolderId]="null"
[nodeResult]="resultNodePageList"
(documentListReady)="refreshResults($event)">
(documentListReady)="refreshResults($event)"
(changedPageSize)="refreshPage($event)"
(changedPageNumber)="refreshPage($event)"
(turnedNextPage)="refreshPage($event)"
(loadNext)="refreshPage($event)"
(turnedPreviousPage)="refreshPage($event)">
</adf-files-component>

@ -17,8 +17,9 @@
import { Component, OnInit, Optional, ViewChild } from '@angular/core';
import { Router, ActivatedRoute, Params } from '@angular/router';
import { NodePaging } from 'alfresco-js-api';
import { NodePaging, Pagination } from 'alfresco-js-api';
import { SearchComponent } from '@alfresco/adf-content-services';
import { UserPreferencesService } from '@alfresco/adf-core';
@Component({
selector: 'adf-search-result-component',
@ -36,9 +37,14 @@ export class SearchResultComponent implements OnInit {
fileShowed: boolean = false;
navigationMode: string = 'dblclick';
resultNodePageList: NodePaging;
maxItems: number;
skipCount: number = 0;
paging: Pagination;
constructor(public router: Router,
private preferences: UserPreferencesService,
@Optional() private route: ActivatedRoute) {
this.maxItems = this.preferences.paginationSize;
}
ngOnInit() {
@ -51,9 +57,15 @@ export class SearchResultComponent implements OnInit {
showSearchResult(event: NodePaging) {
this.resultNodePageList = event;
this.paging = event.list.pagination;
}
refreshResults(event: any) {
this.search.reload();
}
refreshPage(event: Pagination) {
this.maxItems = event.maxItems;
this.skipCount = event.skipCount;
}
}

@ -34,6 +34,7 @@
<adf-toolbar-title>
<adf-dropdown-breadcrumb *ngIf="needBreadcrumbs()"
class="adf-content-node-selector-content-breadcrumb"
(navigate)="clear()"
[target]="documentList"
[folderNode]="breadcrumbFolderNode"
data-automation-id="content-node-selector-content-breadcrumb">
@ -47,6 +48,9 @@
adf-highlight
adf-highlight-selector=".cell-value adf-datatable-cell .adf-datatable-cell-value"
[node]="nodes"
[maxItems]="pageSize"
[skipCount]="skipCount"
[enableInfiniteScrolling]="infiniteScroll"
[rowFilter]="rowFilter"
[imageResolver]="imageResolver"
[currentFolderId]="folderIdToShow"
@ -54,11 +58,8 @@
[contextMenuActions]="false"
[contentActions]="false"
[allowDropFiles]="false"
[enablePagination]="!showingSearchResults"
paginationStrategy="{{paginationStrategy}}"
[pageSize]="pageSize"
(folderChange)="onFolderChange()"
(ready)="onFolderLoaded()"
(ready)="onFolderLoaded($event)"
data-automation-id="content-node-selector-document-list">
<empty-folder-content>
<ng-template>
@ -68,7 +69,6 @@
</adf-document-list>
<adf-infinite-pagination
*ngIf="showingSearchResults && isSearchTermLongEnough()"
[pagination]="pagination"
[pageSize]="pageSize"
[loading]="loadingSearchResults"

@ -20,7 +20,7 @@ import { async, ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material';
import { By } from '@angular/platform-browser';
import { MinimalNodeEntryEntity } from 'alfresco-js-api';
import { ContentService, TranslationService, SearchService, SiteModel, SitesApiService } from '@alfresco/adf-core';
import { ContentService, TranslationService, SearchService, SiteModel, SitesApiService, UserPreferencesService } from '@alfresco/adf-core';
import { DataTableModule } from '@alfresco/adf-core';
import { Observable } from 'rxjs/Rx';
import { MaterialModule } from '../material.module';
@ -89,6 +89,7 @@ describe('ContentNodeSelectorComponent', () => {
DocumentListService,
SearchService,
ContentNodeSelectorService,
UserPreferencesService,
...plusProviders
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
@ -164,19 +165,21 @@ describe('ContentNodeSelectorComponent', () => {
describe('Cancel button', () => {
let dummyMdDialogRef;
let fakePreference: UserPreferencesService = <UserPreferencesService> jasmine.createSpyObj('UserPreferencesService', ['paginationSize']);
fakePreference.paginationSize = 10;
beforeEach(() => {
dummyMdDialogRef = <MatDialogRef<ContentNodeSelectorComponent>> { close: () => {} };
});
it('should be shown if dialogRef is injected', () => {
const componentInstance = new ContentNodeSelectorComponent(null, null, data, dummyMdDialogRef);
const componentInstance = new ContentNodeSelectorComponent(null, null, fakePreference, data, dummyMdDialogRef);
expect(componentInstance.inDialog).toBeTruthy();
});
it('should should call the close method in the injected dialogRef', () => {
spyOn(dummyMdDialogRef, 'close');
const componentInstance = new ContentNodeSelectorComponent(null, null, data, dummyMdDialogRef);
const componentInstance = new ContentNodeSelectorComponent(null, null, fakePreference, data, dummyMdDialogRef);
componentInstance.close();
@ -339,7 +342,7 @@ describe('ContentNodeSelectorComponent', () => {
skipCount,
rootNodeId,
nodeType: 'cm:folder',
maxItems: 10,
maxItems: 25,
orderBy: null
};
}
@ -524,7 +527,7 @@ describe('ContentNodeSelectorComponent', () => {
it('should NOT be shown by default', () => {
fixture.detectChanges();
const pagination = fixture.debugElement.query(By.css('[data-automation-id="content-node-selector-search-pagination"]'));
const pagination = fixture.debugElement.query(By.css('[data-automation-id="adf-infinite-pagination-button"]'));
expect(pagination).toBeNull();
});
@ -539,19 +542,6 @@ describe('ContentNodeSelectorComponent', () => {
});
}));
it('should NOT be shown when modifying searchTerm to be less then 4 characters after search results have been diplayed', async(() => {
typeToSearchBox('shenron');
respondWithSearchResults(ONE_FOLDER_RESULT);
fixture.whenStable().then(() => {
typeToSearchBox('sh');
fixture.detectChanges();
const pagination = fixture.debugElement.query(By.css('[data-automation-id="content-node-selector-search-pagination"]'));
expect(pagination).toBeNull();
});
}));
it('button\'s callback should load the next batch of results by calling the search api', () => {
const skipCount = 8;
component.searchTerm = 'kakarot';

@ -16,7 +16,7 @@
*/
import { Component, EventEmitter, Inject, Input, OnInit, Optional, Output, ViewChild, ViewEncapsulation } from '@angular/core';
import { ContentService, HighlightDirective, SiteModel } from '@alfresco/adf-core';
import { ContentService, HighlightDirective, SiteModel, UserPreferencesService } from '@alfresco/adf-core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material';
import { MinimalNodeEntryEntity, NodePaging, Pagination } from 'alfresco-js-api';
import { DocumentListComponent, PaginationStrategy } from '../document-list/components/document-list.component';
@ -52,6 +52,7 @@ export class ContentNodeSelectorComponent implements OnInit {
paginationStrategy: PaginationStrategy;
pagination: Pagination;
skipCount: number = 0;
infiniteScroll: boolean = false;
@Input()
title: string;
@ -66,7 +67,7 @@ export class ContentNodeSelectorComponent implements OnInit {
imageResolver: ImageResolver = null;
@Input()
pageSize: number = 10;
pageSize: number;
@Output()
select: EventEmitter<MinimalNodeEntryEntity[]> = new EventEmitter<MinimalNodeEntryEntity[]>();
@ -79,6 +80,7 @@ export class ContentNodeSelectorComponent implements OnInit {
constructor(private contentNodeSelectorService: ContentNodeSelectorService,
private contentService: ContentService,
private preferences: UserPreferencesService,
@Optional() @Inject(MAT_DIALOG_DATA) data?: ContentNodeSelectorComponentData,
@Optional() private containingDialog?: MatDialogRef<ContentNodeSelectorComponent>) {
if (data) {
@ -92,6 +94,7 @@ export class ContentNodeSelectorComponent implements OnInit {
if (this.containingDialog) {
this.inDialog = true;
}
this.pageSize = this.preferences.paginationSize;
}
ngOnInit() {
@ -180,6 +183,7 @@ export class ContentNodeSelectorComponent implements OnInit {
* @param event Pagination object
*/
getNextPageOfSearch(event: Pagination): void {
this.infiniteScroll = true;
this.skipCount = event.skipCount;
this.querySearch();
}
@ -245,14 +249,17 @@ export class ContentNodeSelectorComponent implements OnInit {
* Sets showingSearchResults state to be able to differentiate between search results or folder results
*/
onFolderChange(): void {
this.skipCount = 0;
this.infiniteScroll = false;
this.showingSearchResults = false;
}
/**
* Attempts to set the currently loaded node
*/
onFolderLoaded(): void {
onFolderLoaded(nodePage: NodePaging): void {
this.attemptNodeSelection(this.documentList.folderNode);
this.pagination = nodePage.list.pagination;
}
/**

@ -61,25 +61,3 @@
</loading-content-template>
</div>
</adf-datatable>
<ng-container *ngIf="isPaginationEnabled()">
<adf-pagination
*ngIf="isPaginationNeeded()"
class="adf-documentlist-pagination"
(changePageSize)="onChangePageSize($event)"
(changePageNumber)="onChangePageNumber($event)"
(nextPage)="onNextPage($event)"
(prevPage)="onPrevPage($event)"
[pagination]="pagination"
[supportedPageSizes]="supportedPageSizes">
</adf-pagination>
<adf-infinite-pagination
*ngIf="!isPaginationNeeded()"
[pagination]="pagination"
[pageSize]="pageSize"
[loading]="infiniteLoading"
(loadMore)="loadNextBatch($event)">
{{ 'ADF-DOCUMENT-LIST.LAYOUT.LOAD_MORE' | translate }}
</adf-infinite-pagination>
</ng-container>

@ -17,8 +17,7 @@
import { CUSTOM_ELEMENTS_SCHEMA, NgZone, SimpleChange, TemplateRef } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { Pagination } from 'alfresco-js-api';
import { AlfrescoApiService, TranslationService, AppConfigService, UserPreferencesService } from '@alfresco/adf-core';
import { AlfrescoApiService, TranslationService } from '@alfresco/adf-core';
import { DataColumn, DataTableComponent } from '@alfresco/adf-core';
import { DataTableModule } from '@alfresco/adf-core';
import { Observable, Subject } from 'rxjs/Rx';
@ -48,8 +47,6 @@ describe('DocumentList', () => {
let fixture: ComponentFixture<DocumentListComponent>;
let element: HTMLElement;
let eventMock: any;
let appConfig: AppConfigService;
let userPreferences: UserPreferencesService;
beforeEach(async(() => {
let zone = new NgZone({ enableLongStackTrace: false });
@ -87,8 +84,6 @@ describe('DocumentList', () => {
documentList = fixture.componentInstance;
documentListService = TestBed.get(DocumentListService);
apiService = TestBed.get(AlfrescoApiService);
userPreferences = TestBed.get(UserPreferencesService);
appConfig = TestBed.get(AppConfigService);
fixture.detectChanges();
});
@ -128,8 +123,7 @@ describe('DocumentList', () => {
it('should call action\'s handler with node', () => {
let node = new FileNode();
let action = new ContentActionModel();
action.handler = () => {
};
action.handler = () => { };
spyOn(action, 'handler').and.stub();
@ -141,8 +135,7 @@ describe('DocumentList', () => {
it('should call action\'s handler with node and permission', () => {
let node = new FileNode();
let action = new ContentActionModel();
action.handler = () => {
};
action.handler = () => { };
action.permission = 'fake-permission';
spyOn(action, 'handler').and.stub();
@ -154,8 +147,7 @@ describe('DocumentList', () => {
it('should call action\'s execute with node if it is defined', () => {
let node = new FileNode();
let action = new ContentActionModel();
action.execute = () => {
};
action.execute = () => { };
spyOn(action, 'execute').and.stub();
documentList.executeContentAction(node, action);
@ -168,8 +160,7 @@ describe('DocumentList', () => {
let node = new FileNode();
let action = new ContentActionModel();
action.handler = () => deleteObservable;
action.execute = () => {
};
action.execute = () => { };
spyOn(action, 'execute').and.stub();
documentList.executeContentAction(node, action);
@ -203,12 +194,14 @@ describe('DocumentList', () => {
it('should reset selection on loading folder by node id', () => {
spyOn(documentList, 'resetSelection').and.callThrough();
documentList.loadFolderByNodeId('-trashcan-');
expect(documentList.resetSelection).toHaveBeenCalled();
});
it('should reset selection in the datatable also', () => {
spyOn(documentList.dataTable, 'resetSelection').and.callThrough();
documentList.loadFolderByNodeId('-trashcan-');
expect(documentList.dataTable.resetSelection).toHaveBeenCalled();
});
@ -217,6 +210,7 @@ describe('DocumentList', () => {
documentList.currentFolderId = '1d26e465-dea3-42f3-b415-faa8364b9692';
documentList.folderNode = new NodeMinimal();
documentList.folderNode.id = '1d26e465-dea3-42f3-b415-faa8364b9692';
documentList.reload();
fixture.detectChanges();
@ -842,6 +836,7 @@ describe('DocumentList', () => {
it('should load folder by ID on init', () => {
documentList.currentFolderId = '1d26e465-dea3-42f3-b415-faa8364b9692';
spyOn(documentList, 'loadFolderNodesByFolderNodeId').and.returnValue(Promise.resolve());
documentList.ngOnChanges({ folderNode: new SimpleChange(null, documentList.currentFolderId, true) });
expect(documentList.loadFolderNodesByFolderNodeId).toHaveBeenCalled();
});
@ -888,11 +883,8 @@ describe('DocumentList', () => {
documentList.currentFolderId = '1d26e465-dea3-42f3-b415-faa8364b9692';
documentList.folderNode = new NodeMinimal();
documentList.folderNode.id = '1d26e465-dea3-42f3-b415-faa8364b9692';
documentList.skipCount = 5;
documentList.pageSize = 5;
spyOn(documentList, 'isPaginationEnabled').and.returnValue(true);
documentList.reload();
documentList.reload();
fixture.detectChanges();
documentList.ready.subscribe(() => {
@ -920,8 +912,6 @@ describe('DocumentList', () => {
documentList.currentFolderId = '1d26e465-dea3-42f3-b415-faa8364b9692';
documentList.folderNode = new NodeMinimal();
documentList.folderNode.id = '1d26e465-dea3-42f3-b415-faa8364b9692';
documentList.skipCount = 5;
documentList.pageSize = 5;
spyOn(documentListService, 'getFolderNode').and.returnValue(Promise.resolve(fakeNodeWithCreatePermission));
spyOn(documentListService, 'getFolder').and.returnValue(Promise.resolve(fakeNodeAnswerWithNOEntries));
@ -940,8 +930,7 @@ describe('DocumentList', () => {
documentList.currentFolderId = '1d26e465-dea3-42f3-b415-faa8364b9692';
documentList.folderNode = new NodeMinimal();
documentList.folderNode.id = '1d26e465-dea3-42f3-b415-faa8364b9692';
documentList.skipCount = 5;
documentList.pageSize = 5;
spyOn(documentListService, 'getFolderNode').and.returnValue(Promise.resolve(fakeNodeWithNoPermission));
spyOn(documentListService, 'getFolder').and.returnValue(Promise.resolve(fakeNodeAnswerWithNOEntries));
@ -1106,59 +1095,11 @@ describe('DocumentList', () => {
documentList.loadFolderByNodeId('-recent-');
});
it('should switch to another page', () => {
spyOn(documentList, 'reload').and.stub();
const page1: Pagination = {
maxItems: 5,
skipCount: 0
};
const page2: Pagination = {
maxItems: 5,
skipCount: 10
};
documentList.onChangePageNumber(page1);
expect(documentList.pageSize).toBe(page1.maxItems);
expect(documentList.skipCount).toBe(page1.skipCount);
documentList.onChangePageNumber(page2);
expect(documentList.pageSize).toBe(page2.maxItems);
expect(documentList.skipCount).toBe(page2.skipCount);
expect(documentList.reload).toHaveBeenCalledTimes(2);
});
it('should reset pagination when switching sources', () => {
spyOn(documentList, 'resetPagination').and.callThrough();
documentList.ngOnChanges({ currentFolderId: new SimpleChange(null, '-trashcan-', false) });
documentList.ngOnChanges({ currentFolderId: new SimpleChange(null, '-sites-', false) });
expect(documentList.resetPagination).toHaveBeenCalledTimes(2);
});
it('should reset folder node upon changing current folder id', () => {
documentList.folderNode = <any> {};
documentList.ngOnChanges({ currentFolderId: new SimpleChange(null, '-sites-', false) });
expect(documentList.folderNode).toBeNull();
});
it('should fallback to first page size supported', () => {
userPreferences.paginationSize = 10;
appConfig.config = Object.assign(appConfig.config, {
'document-list': {
supportedPageSizes: [20, 30, 40]
}
});
let customFixture = TestBed.createComponent<DocumentListComponent>(DocumentListComponent);
let component: DocumentListComponent = customFixture.componentInstance;
customFixture.detectChanges();
expect(component.supportedPageSizes).toEqual([20, 30, 40]);
expect(component.pageSize).toBe(20);
});
});

@ -33,7 +33,6 @@ import {
MinimalNodeEntity,
MinimalNodeEntryEntity,
NodePaging,
Pagination,
PersonEntry,
SitePaging
} from 'alfresco-js-api';
@ -91,9 +90,6 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni
@Input()
multiselect: boolean = false;
@Input()
enablePagination: boolean = true;
@Input()
contentActions: boolean = false;
@ -103,9 +99,6 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni
@Input()
contextMenuActions: boolean = false;
@Input()
pageSize: number = DocumentListComponent.DEFAULT_PAGE_SIZE;
@Input()
emptyFolderImageUrl: string = require('../../assets/images/empty_doc_lib.svg');
@ -124,19 +117,6 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni
@Input()
loading: boolean = false;
@Input()
paginationStrategy: PaginationStrategy = PaginationStrategy.Finite;
@Input()
supportedPageSizes: number[];
infiniteLoading: boolean = false;
noPermission: boolean = false;
selection = new Array<MinimalNodeEntity>();
skipCount: number = 0;
pagination: Pagination;
@Input()
rowFilter: RowFilter | null = null;
@ -153,6 +133,15 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni
@Input()
node: NodePaging = null;
@Input()
maxItems: number;
@Input()
skipCount: number = 0;
@Input()
enableInfiniteScrolling: boolean = false;
@Output()
nodeClick: EventEmitter<NodeEntityEvent> = new EventEmitter<NodeEntityEvent>();
@ -180,11 +169,13 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni
noPermissionTemplate: TemplateRef<any>;
contextActionHandler: Subject<any> = new Subject();
data: ShareDataTableAdapter;
infiniteLoading: boolean = false;
noPermission: boolean = false;
selection = new Array<MinimalNodeEntity>();
private layoutPresets = {};
private currentNodeAllowableOperations: string[] = [];
private CREATE_PERMISSION = 'create';
private defaultPageSizes = [5, 10, 15, 20];
constructor(private documentListService: DocumentListService,
private ngZone: NgZone,
@ -192,7 +183,7 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni
private apiService: AlfrescoApiService,
private appConfig: AppConfigService,
private preferences: UserPreferencesService) {
this.supportedPageSizes = appConfig.get('document-list.supportedPageSizes', this.defaultPageSizes);
this.maxItems = this.preferences.paginationSize;
}
getContextActions(node: MinimalNodeEntity) {
@ -221,19 +212,7 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni
return this.columnList && this.columnList.columns && this.columnList.columns.length > 0;
}
getDefaultPageSize(): number {
let result = this.preferences.paginationSize;
const pageSizes = this.supportedPageSizes || this.defaultPageSizes;
if (pageSizes && pageSizes.length > 0 && pageSizes.indexOf(result) < 0) {
result = pageSizes[0];
}
return result;
}
ngOnInit() {
this.pageSize = this.getDefaultPageSize();
this.loadLayoutPresets();
this.data = new ShareDataTableAdapter(this.documentListService, null, this.getDefaultSorting());
this.data.thumbnails = this.thumbnails;
@ -272,11 +251,14 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni
}
ngOnChanges(changes: SimpleChanges) {
if (this.isSkipCountChanged(changes) ||
this.isMaxItemsChanged(changes)) {
this.reload(this.enableInfiniteScrolling);
}
if (changes.folderNode && changes.folderNode.currentValue) {
this.loadFolder();
} else if (changes.currentFolderId && changes.currentFolderId.currentValue) {
if (changes.currentFolderId.previousValue !== changes.currentFolderId.currentValue) {
this.resetPagination();
this.folderNode = null;
}
if (!this.hasCustomLayout) {
@ -290,7 +272,7 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni
} else if (changes.rowFilter) {
this.data.setFilter(changes.rowFilter.currentValue);
if (this.currentFolderId) {
this.loadFolderNodesByFolderNodeId(this.currentFolderId, this.pageSize, this.skipCount);
this.loadFolderNodesByFolderNodeId(this.currentFolderId, this.maxItems, this.skipCount);
}
} else if (changes.imageResolver) {
this.data.setImageResolver(changes.imageResolver.currentValue);
@ -308,7 +290,7 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni
this.loadFolderByNodeId(this.currentFolderId);
} else if (this.node) {
this.data.loadPage(this.node);
this.ready.emit();
this.ready.emit(this.node);
}
});
}
@ -339,14 +321,6 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni
return !this.data || this.data.getRows().length === 0;
}
isPaginationEnabled() {
return this.enablePagination && !this.isEmpty();
}
isPaginationNeeded() {
return this.paginationStrategy === PaginationStrategy.Finite;
}
getNodeActions(node: MinimalNodeEntity | any): ContentActionModel[] {
let target = null;
@ -445,7 +419,7 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni
let nodeId = this.folderNode ? this.folderNode.id : this.currentFolderId;
if (nodeId) {
this.loadFolderNodesByFolderNodeId(nodeId, this.pageSize, this.skipCount, merge).catch(err => this.error.emit(err));
this.loadFolderNodesByFolderNodeId(nodeId, this.maxItems, this.skipCount, merge).catch(err => this.error.emit(err));
}
}
@ -474,7 +448,7 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni
this.currentFolderId = node.id;
this.skipCount = 0;
this.currentNodeAllowableOperations = node['allowableOperations'] ? node['allowableOperations'] : [];
return this.loadFolderNodesByFolderNodeId(node.id, this.pageSize, this.skipCount);
return this.loadFolderNodesByFolderNodeId(node.id, this.maxItems, this.skipCount);
})
.catch(err => {
if (JSON.parse(err.message).error.statusCode === 403) {
@ -496,25 +470,16 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni
rootFolderId: id
})
.subscribe(
val => {
if (this.isCurrentPageEmpty(val, skipCount)) {
this.updateSkipCount(skipCount - maxItems);
this.loadFolderNodesByFolderNodeId(id, maxItems, skipCount - maxItems).then(
() => resolve(true),
error => reject(error)
);
} else {
this.data.loadPage(<NodePaging> val, merge);
this.pagination = val.list.pagination;
this.loading = false;
this.infiniteLoading = false;
this.ready.emit();
resolve(true);
}
},
error => {
reject(error);
});
val => {
this.data.loadPage(<NodePaging> val, merge);
this.loading = false;
this.infiniteLoading = false;
this.ready.emit(val);
resolve(true);
},
error => {
reject(error);
});
});
}
@ -524,14 +489,23 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni
this.selection = [];
}
resetPagination() {
this.skipCount = 0;
private isSkipCountChanged(changePage: SimpleChanges) {
return changePage.skipCount &&
changePage.skipCount.currentValue !== null &&
changePage.skipCount.currentValue !== undefined &&
changePage.skipCount.currentValue !== changePage.skipCount.previousValue;
}
private isMaxItemsChanged(changePage: SimpleChanges) {
return changePage.maxItems &&
changePage.maxItems.currentValue &&
changePage.maxItems.currentValue !== changePage.maxItems.previousValue;
}
private loadTrashcan(): void {
const options = {
include: ['path', 'properties'],
maxItems: this.pageSize,
maxItems: this.maxItems,
skipCount: this.skipCount
};
this.apiService.nodesApi.getDeletedNodes(options)
@ -542,7 +516,7 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni
private loadSharedLinks(): void {
const options = {
include: ['properties', 'allowableOperations', 'path'],
maxItems: this.pageSize,
maxItems: this.maxItems,
skipCount: this.skipCount
};
this.apiService.sharedLinksApi.findSharedLinks(options)
@ -553,7 +527,7 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni
private loadSites(): void {
const options = {
include: ['properties'],
maxItems: this.pageSize,
maxItems: this.maxItems,
skipCount: this.skipCount
};
@ -565,7 +539,7 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni
private loadMemberSites(): void {
const options = {
include: ['properties'],
maxItems: this.pageSize,
maxItems: this.maxItems,
skipCount: this.skipCount
};
@ -588,7 +562,7 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni
private loadFavorites(): void {
const options = {
maxItems: this.pageSize,
maxItems: this.maxItems,
skipCount: this.skipCount,
where: '(EXISTS(target/file) OR EXISTS(target/folder))',
include: ['properties', 'allowableOperations', 'path']
@ -638,7 +612,7 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni
ascending: false
}],
paging: {
maxItems: this.pageSize,
maxItems: this.maxItems,
skipCount: this.skipCount
}
};
@ -652,24 +626,11 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni
private onPageLoaded(page: NodePaging) {
if (page) {
this.data.loadPage(page);
this.pagination = page.list.pagination;
this.loading = false;
this.ready.emit();
this.ready.emit(page);
}
}
private isCurrentPageEmpty(node, skipCount): boolean {
return !this.hasNodeEntries(node) && this.hasPages(skipCount);
}
private hasPages(skipCount): boolean {
return skipCount > 0 && this.isPaginationEnabled();
}
private hasNodeEntries(node): boolean {
return node && node.list && node.list.entries && node.list.entries.length > 0;
}
/**
* Creates a set of predefined columns.
*/
@ -795,34 +756,6 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni
}
}
onChangePageSize(event: Pagination): void {
this.preferences.paginationSize = event.maxItems;
this.pageSize = event.maxItems;
this.skipCount = 0;
this.reload();
}
onChangePageNumber(page: Pagination): void {
this.pageSize = page.maxItems;
this.skipCount = page.skipCount;
this.reload();
}
onNextPage(event: Pagination): void {
this.skipCount = event.skipCount;
this.reload();
}
loadNextBatch(event: Pagination) {
this.skipCount = event.skipCount;
this.reload(true);
}
onPrevPage(event: Pagination): void {
this.skipCount = event.skipCount;
this.reload();
}
private enforceSingleClickNavigationForMobile(): void {
if (this.isMobile()) {
this.navigationMode = DocumentListComponent.SINGLE_CLICK_NAVIGATION;
@ -860,10 +793,6 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni
return false;
}
updateSkipCount(newSkipCount) {
this.skipCount = newSkipCount;
}
hasCurrentNodePermission(permission: string): boolean {
let hasPermission: boolean = false;
if (this.currentNodeAllowableOperations.length > 0) {

@ -56,11 +56,6 @@ export class PaginationComponent implements OnInit {
@Input()
supportedPageSizes: number[] = [ 25, 50, 100 ];
/** @deprecated */
/** "pagination" object already has "maxItems" */
@Input()
maxItems: number = PaginationComponent.DEFAULT_PAGE_SIZE;
@Input()
pagination: Pagination;