mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-05-19 17:14:57 +00:00
[ADF-1805] rebased documentlist pagination removal (#2668)
* [ADF-1805] rebased documentlist pagination removal * [ADF-1805] fixed some wrong changes]
This commit is contained in:
parent
0f0f22634a
commit
141bc0f8b4
demo-shell
resources/i18n
src/app/components
lib
content-services
content-node-selector
content-node-selector.component.htmlcontent-node-selector.component.spec.tscontent-node-selector.component.ts
document-list/components
core/pagination
@ -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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user