[ADF-2016] pagination integration for document list (#2718)

* pagination integration for document list

* reload data only if needed

* unit tests for document list

* pagination tests

* update docs
This commit is contained in:
Denys Vuika
2017-11-27 10:14:08 +00:00
committed by Eugenio Romano
parent d77db4e8f6
commit a9d61e5d6e
9 changed files with 263 additions and 93 deletions

View File

@@ -116,10 +116,9 @@
</button> </button>
</mat-menu> </mat-menu>
</adf-toolbar> </adf-toolbar>
<adf-document-list <adf-document-list
#documentList #documentList
[maxItems]="currentMaxItems"
[skipCount]="currentSkipCount"
[enableInfiniteScrolling]="infiniteScrolling" [enableInfiniteScrolling]="infiniteScrolling"
[permissionsStyle]="permissionsStyle" [permissionsStyle]="permissionsStyle"
[currentFolderId]="currentFolderId" [currentFolderId]="currentFolderId"
@@ -274,7 +273,7 @@
#standardPagination #standardPagination
*ngIf="!infiniteScrolling" *ngIf="!infiniteScrolling"
class="adf-documentlist-pagination" class="adf-documentlist-pagination"
[pagination]="pagination" [target]="documentList"
[supportedPageSizes]="supportedPages" [supportedPageSizes]="supportedPages"
(changePageSize)="onChangePageSize($event)" (changePageSize)="onChangePageSize($event)"
(changePageNumber)="onChangePageNumber($event)" (changePageNumber)="onChangePageNumber($event)"

View File

@@ -126,8 +126,6 @@ export class FilesComponent implements OnInit, OnChanges, OnDestroy {
permissionsStyle: PermissionStyleModel[] = []; permissionsStyle: PermissionStyleModel[] = [];
supportedPages: number[] = [5, 10, 15, 20]; supportedPages: number[] = [5, 10, 15, 20];
infiniteScrolling: boolean; infiniteScrolling: boolean;
currentMaxItems: number;
currentSkipCount: number = 0;
private onCreateFolder: Subscription; private onCreateFolder: Subscription;
private onEditFolder: Subscription; private onEditFolder: Subscription;
@@ -169,7 +167,6 @@ export class FilesComponent implements OnInit, OnChanges, OnDestroy {
maxItems: this.preference.paginationSize, maxItems: this.preference.paginationSize,
skipCount: 0 skipCount: 0
}; };
this.currentMaxItems = this.preference.paginationSize;
} }
if (this.route) { if (this.route) {
this.route.params.forEach((params: Params) => { this.route.params.forEach((params: Params) => {
@@ -446,32 +443,22 @@ export class FilesComponent implements OnInit, OnChanges, OnDestroy {
onChangePageSize(event: Pagination): void { onChangePageSize(event: Pagination): void {
this.preference.paginationSize = event.maxItems; this.preference.paginationSize = event.maxItems;
this.currentMaxItems = event.maxItems;
this.currentSkipCount = event.skipCount;
this.changedPageSize.emit(event); this.changedPageSize.emit(event);
} }
onChangePageNumber(event: Pagination): void { onChangePageNumber(event: Pagination): void {
this.currentMaxItems = event.maxItems;
this.currentSkipCount = event.skipCount;
this.changedPageNumber.emit(event); this.changedPageNumber.emit(event);
} }
onNextPage(event: Pagination): void { onNextPage(event: Pagination): void {
this.currentMaxItems = event.maxItems;
this.currentSkipCount = event.skipCount;
this.turnedNextPage.emit(event); this.turnedNextPage.emit(event);
} }
loadNextBatch(event: Pagination) { loadNextBatch(event: Pagination) {
this.currentMaxItems = event.maxItems;
this.currentSkipCount = event.skipCount;
this.loadNext.emit(event); this.loadNext.emit(event);
} }
onPrevPage(event: Pagination): void { onPrevPage(event: Pagination): void {
this.currentMaxItems = event.maxItems;
this.currentSkipCount = event.skipCount;
this.turnedPreviousPage.emit(event); this.turnedPreviousPage.emit(event);
} }
} }

View File

@@ -31,12 +31,22 @@ Adds pagination to the component it is used with.
</adf-pagination> </adf-pagination>
``` ```
## Integrating with Document List
```html
<adf-document-list #documentList ...></adf-document-list>
<adf-pagination [target]="documentList" ...>
</adf-pagination>
```
### Properties ### Properties
| Name | Type | Default | Description | | Name | Type | Default | Description |
| --- | --- | --- | --- | | --- | --- | --- | --- |
| pagination | Pagination | | Pagination object | | pagination | Pagination | | Pagination object |
| supportedPageSizes | Array&lt;number&gt; | [ 25, 50, 100 ] | An array of page sizes | | supportedPageSizes | Array&lt;number&gt; | [ 25, 50, 100 ] | An array of page sizes |
| target | PaginatedComponent | | Component that provides custom pagination support |
### Events ### Events
@@ -54,6 +64,23 @@ The pagination object is a generic component to paginate component. The Alfresco
Each event helps to detect the certain action that user have made using the component. Each event helps to detect the certain action that user have made using the component.
For `change` event, a [PaginationQueryParams](https://github.com/Alfresco/alfresco-ng2-components/blob/development/ng2-components/ng2-alfresco-core/src/components/pagination/pagination-query-params.interface.ts) (including the query params supported by the REST API, `skipCount` and `maxItems`) is returned. For `change` event, a [PaginationQueryParams](https://github.com/Alfresco/alfresco-ng2-components/blob/development/ng2-components/ng2-alfresco-core/src/components/pagination/pagination-query-params.interface.ts) (including the query parameters supported by the REST API, `skipCount` and `maxItems`) is returned.
For all events other than `change`, a new Pagination object is returned as in the folowing example, with updated properties to be used to query further. For all events other than `change`, a new Pagination object is returned as in the following example, with updated properties to be used to query further.
### Custom pagination
The component also provides light integration with external implementations of the pagination.
Any component can implement the `PaginatedComponent` and be used as a value for the `target` property.
```js
export interface PaginatedComponent {
pagination: Subject<Pagination>;
updatePagination(params: PaginationQueryParams);
}
```
Your component needs to provide a `pagination` subject to allow Pagination component to reflect to changes.
Every time user interacts with the Pagination, it will call the `updatePagination` method and pass the parameters.

View File

@@ -1103,4 +1103,47 @@ describe('DocumentList', () => {
expect(documentList.folderNode).toBeNull(); expect(documentList.folderNode).toBeNull();
}); });
it('should update pagination settings', () => {
spyOn(documentList, 'reload').and.stub();
documentList.maxItems = 0;
documentList.skipCount = 0;
documentList.updatePagination({
maxItems: 10,
skipCount: 10
});
expect(documentList.maxItems).toBe(10);
expect(documentList.skipCount).toBe(10);
});
it('should reload data upon changing pagination settings', () => {
spyOn(documentList, 'reload').and.stub();
documentList.maxItems = 0;
documentList.skipCount = 0;
documentList.updatePagination({
maxItems: 10,
skipCount: 10
});
expect(documentList.reload).toHaveBeenCalled();
});
it('should not reload data if pagination settings are same', () => {
spyOn(documentList, 'reload').and.stub();
documentList.maxItems = 10;
documentList.skipCount = 10;
documentList.updatePagination({
maxItems: 10,
skipCount: 10
});
expect(documentList.reload).not.toHaveBeenCalled();
});
}); });

View File

@@ -21,7 +21,9 @@ import {
DataRowActionEvent, DataRowActionEvent,
DataSorting, DataSorting,
DataTableComponent, DataTableComponent,
ObjectDataColumn ObjectDataColumn,
PaginatedComponent,
PaginationQueryParams
} from '@alfresco/adf-core'; } from '@alfresco/adf-core';
import { AlfrescoApiService, AppConfigService, DataColumnListComponent, UserPreferencesService } from '@alfresco/adf-core'; import { AlfrescoApiService, AppConfigService, DataColumnListComponent, UserPreferencesService } from '@alfresco/adf-core';
import { import {
@@ -34,7 +36,8 @@ import {
MinimalNodeEntryEntity, MinimalNodeEntryEntity,
NodePaging, NodePaging,
PersonEntry, PersonEntry,
SitePaging SitePaging,
Pagination
} from 'alfresco-js-api'; } from 'alfresco-js-api';
import { Observable } from 'rxjs/Observable'; import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject'; import { Subject } from 'rxjs/Subject';
@@ -58,7 +61,7 @@ export enum PaginationStrategy {
templateUrl: './document-list.component.html', templateUrl: './document-list.component.html',
encapsulation: ViewEncapsulation.None encapsulation: ViewEncapsulation.None
}) })
export class DocumentListComponent implements OnInit, OnChanges, AfterContentInit { export class DocumentListComponent implements OnInit, OnChanges, AfterContentInit, PaginatedComponent {
static SINGLE_CLICK_NAVIGATION: string = 'click'; static SINGLE_CLICK_NAVIGATION: string = 'click';
static DOUBLE_CLICK_NAVIGATION: string = 'dblclick'; static DOUBLE_CLICK_NAVIGATION: string = 'dblclick';
@@ -169,6 +172,7 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni
infiniteLoading: boolean = false; infiniteLoading: boolean = false;
noPermission: boolean = false; noPermission: boolean = false;
selection = new Array<MinimalNodeEntity>(); selection = new Array<MinimalNodeEntity>();
pagination = new Subject<Pagination>();
private layoutPresets = {}; private layoutPresets = {};
private currentNodeAllowableOperations: string[] = []; private currentNodeAllowableOperations: string[] = [];
@@ -180,7 +184,14 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni
private apiService: AlfrescoApiService, private apiService: AlfrescoApiService,
private appConfig: AppConfigService, private appConfig: AppConfigService,
private preferences: UserPreferencesService) { private preferences: UserPreferencesService) {
this.maxItems = this.preferences.paginationSize; this.maxItems = this.preferences.paginationSize;
this.pagination.next(<Pagination> {
maxItems: this.preferences.paginationSize,
skipCount: 0,
totalItems: 0,
hasMoreItems: false
});
} }
getContextActions(node: MinimalNodeEntity) { getContextActions(node: MinimalNodeEntity) {
@@ -287,7 +298,7 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni
this.loadFolderByNodeId(this.currentFolderId, merge); this.loadFolderByNodeId(this.currentFolderId, merge);
} else if (this.node) { } else if (this.node) {
this.data.loadPage(this.node); this.data.loadPage(this.node);
this.ready.emit(this.node); this.onDataReady(this.node);
} }
}); });
} }
@@ -487,7 +498,7 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni
this.data.loadPage(<NodePaging> val, merge); this.data.loadPage(<NodePaging> val, merge);
this.loading = false; this.loading = false;
this.infiniteLoading = false; this.infiniteLoading = false;
this.ready.emit(val); this.onDataReady(val);
resolve(true); resolve(true);
}, },
error => { error => {
@@ -643,7 +654,7 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni
if (page) { if (page) {
this.data.loadPage(page, merge); this.data.loadPage(page, merge);
this.loading = false; this.loading = false;
this.ready.emit(page); this.onDataReady(page);
} }
} }
@@ -830,10 +841,30 @@ export class DocumentListComponent implements OnInit, OnChanges, AfterContentIni
} else { } else {
this.layoutPresets = presetsDefaultModel; this.layoutPresets = presetsDefaultModel;
} }
} }
private getLayoutPreset(name: string = 'default'): DataColumn[] { private getLayoutPreset(name: string = 'default'): DataColumn[] {
return (this.layoutPresets[name] || this.layoutPresets['default']).map(col => new ObjectDataColumn(col)); return (this.layoutPresets[name] || this.layoutPresets['default']).map(col => new ObjectDataColumn(col));
} }
private onDataReady(page: NodePaging) {
this.ready.emit(page);
if (page && page.list && page.list.pagination) {
this.pagination.next(page.list.pagination);
} else {
this.pagination.next(null);
}
}
updatePagination(params: PaginationQueryParams) {
const needsReload = this.maxItems !== params.maxItems || this.skipCount !== params.skipCount;
this.maxItems = params.maxItems;
this.skipCount = params.skipCount;
if (needsReload) {
this.reload(this.enableInfiniteScrolling);
}
}
} }

View File

@@ -0,0 +1,28 @@
/*!
* @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.
*/
import { Pagination } from 'alfresco-js-api';
import { Subject } from 'rxjs/Subject';
import { PaginationQueryParams } from './pagination-query-params.interface';
export interface PaginatedComponent {
pagination: Subject<Pagination>;
updatePagination(params: PaginationQueryParams);
}

View File

@@ -19,18 +19,19 @@ import { HttpClientModule } from '@angular/common/http';
import { NO_ERRORS_SCHEMA } from '@angular/core'; import { NO_ERRORS_SCHEMA } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { Pagination } from 'alfresco-js-api';
import { MaterialModule } from '../material.module'; import { MaterialModule } from '../material.module';
import { AppConfigService } from '../app-config/app-config.service'; import { AppConfigService } from '../app-config/app-config.service';
import { LogService } from '../services/log.service'; import { LogService } from '../services/log.service';
import { TranslateLoaderService } from '../services/translate-loader.service'; import { TranslateLoaderService } from '../services/translate-loader.service';
import { TranslationService } from '../services/translation.service'; import { TranslationService } from '../services/translation.service';
import { PaginationComponent } from './pagination.component'; import { PaginationComponent } from './pagination.component';
import { PaginatedComponent } from './public-api';
import { Subject } from 'rxjs/Subject';
declare let jasmine: any; class FakePaginationInput implements Pagination {
count: number;
class FakePaginationInput { hasMoreItems: boolean;
count: string = 'Not applicable / not used';
hasMoreItems: string = 'Not applicable / not used';
totalItems: number = null; totalItems: number = null;
skipCount: number = null; skipCount: number = null;
maxItems: number = 25; maxItems: number = 25;
@@ -44,14 +45,12 @@ class FakePaginationInput {
describe('PaginationComponent', () => { describe('PaginationComponent', () => {
let fixture: ComponentFixture<PaginationComponent>; let fixture: ComponentFixture<PaginationComponent>;
let component: PaginationComponent;
beforeEach(() => { let changePageNumberSpy: jasmine.Spy;
jasmine.Ajax.install(); let changePageSizeSpy: jasmine.Spy;
}); let nextPageSpy: jasmine.Spy;
let prevPageSpy: jasmine.Spy;
afterEach(() => {
jasmine.Ajax.uninstall();
});
beforeEach(async(() => { beforeEach(async(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
@@ -77,19 +76,16 @@ describe('PaginationComponent', () => {
}).compileComponents() }).compileComponents()
.then(() => { .then(() => {
fixture = TestBed.createComponent(PaginationComponent); fixture = TestBed.createComponent(PaginationComponent);
const component: PaginationComponent = fixture.componentInstance; component = fixture.componentInstance;
(<any> component).ngAfterViewInit = jasmine (<any> component).ngAfterViewInit = jasmine
.createSpy('ngAfterViewInit').and .createSpy('ngAfterViewInit').and
.callThrough(); .callThrough();
spyOn(component.changePageNumber, 'emit'); changePageNumberSpy = spyOn(component.changePageNumber, 'emit');
spyOn(component.changePageSize, 'emit'); changePageSizeSpy = spyOn(component.changePageSize, 'emit');
spyOn(component.nextPage, 'emit'); nextPageSpy = spyOn(component.nextPage, 'emit');
spyOn(component.prevPage, 'emit'); prevPageSpy = spyOn(component.prevPage, 'emit');
this.fixture = fixture;
this.component = component;
fixture.detectChanges(); fixture.detectChanges();
}); });
@@ -97,38 +93,38 @@ describe('PaginationComponent', () => {
describe('Single page', () => { describe('Single page', () => {
beforeEach(() => { beforeEach(() => {
this.component.pagination = new FakePaginationInput(1, 1, 10); component.pagination = new FakePaginationInput(1, 1, 10);
}); });
it('has a single page', () => { it('has a single page', () => {
expect(this.component.pages.length).toBe(1); expect(component.pages.length).toBe(1);
}); });
it('has current page 1', () => { it('has current page 1', () => {
expect(this.component.current).toBe(1); expect(component.current).toBe(1);
}); });
it('is first and last page', () => { it('is first and last page', () => {
expect(this.component.isFirstPage).toBe(true); expect(component.isFirstPage).toBe(true);
expect(this.component.isLastPage).toBe(true); expect(component.isLastPage).toBe(true);
}); });
it('has range', () => { it('has range', () => {
expect(this.component.range).toEqual([ 1, 10 ]); expect(component.range).toEqual([ 1, 10 ]);
}); });
}); });
describe('Single full page', () => { describe('Single full page', () => {
beforeEach(() => { beforeEach(() => {
this.component.pagination = new FakePaginationInput(1, 1, 25); component.pagination = new FakePaginationInput(1, 1, 25);
}); });
it('has a single page', () => { it('has a single page', () => {
expect(this.component.pages.length).toBe(1); expect(component.pages.length).toBe(1);
}); });
it('has range', () => { it('has range', () => {
expect(this.component.range).toEqual([ 1, 25 ]); expect(component.range).toEqual([ 1, 25 ]);
}); });
}); });
@@ -138,74 +134,63 @@ describe('PaginationComponent', () => {
// and last page has 5 items // and last page has 5 items
beforeEach(() => { beforeEach(() => {
this.component.pagination = new FakePaginationInput(6, 3, 5); component.pagination = new FakePaginationInput(6, 3, 5);
}); });
it('has more pages', () => { it('has more pages', () => {
expect(this.component.pages.length).toBe(6); expect(component.pages.length).toBe(6);
}); });
it('has the last page', () => { it('has the last page', () => {
expect(this.component.lastPage).toBe(6); expect(component.lastPage).toBe(6);
}); });
it('is on the 3rd page', () => { it('is on the 3rd page', () => {
expect(this.component.current).toBe(3); expect(component.current).toBe(3);
}); });
it('has previous and next page', () => { it('has previous and next page', () => {
expect(this.component.previous).toBe(2); expect(component.previous).toBe(2);
expect(this.component.next).toBe(4); expect(component.next).toBe(4);
}); });
it('is not first, nor last', () => { it('is not first, nor last', () => {
expect(this.component.isFirstPage).toBe(false); expect(component.isFirstPage).toBe(false);
expect(this.component.isLastPage).toBe(false); expect(component.isLastPage).toBe(false);
}); });
it('has range', () => { it('has range', () => {
expect(this.component.range).toEqual([ 51, 75 ]); expect(component.range).toEqual([ 51, 75 ]);
}); });
it('goes next', () => { it('goes next', () => {
const { component } = this;
component.goNext(); component.goNext();
const { emit: { calls } } = component.nextPage; const { skipCount } = nextPageSpy.calls.mostRecent().args[0];
const { skipCount } = calls.mostRecent().args[0];
expect(skipCount).toBe(75); expect(skipCount).toBe(75);
}); });
it('goes previous', () => { it('goes previous', () => {
const { component } = this;
component.goPrevious(); component.goPrevious();
const { emit: { calls } } = component.prevPage; const { skipCount } = prevPageSpy.calls.mostRecent().args[0];
const { skipCount } = calls.mostRecent().args[0];
expect(skipCount).toBe(25); expect(skipCount).toBe(25);
}); });
it('changes page size', () => { it('changes page size', () => {
const { component } = this;
component.onChangePageSize(50); component.onChangePageSize(50);
const { emit: { calls } } = component.changePageSize; const { maxItems } = changePageSizeSpy.calls.mostRecent().args[0];
const { maxItems } = calls.mostRecent().args[0];
expect(maxItems).toBe(50); expect(maxItems).toBe(50);
}); });
it('changes page number', () => { it('changes page number', () => {
const { component } = this;
component.onChangePageNumber(5); component.onChangePageNumber(5);
const { emit: { calls } } = component.changePageNumber; const { skipCount } = changePageNumberSpy.calls.mostRecent().args[0];
const { skipCount } = calls.mostRecent().args[0];
expect(skipCount).toBe(100); expect(skipCount).toBe(100);
}); });
@@ -216,24 +201,24 @@ describe('PaginationComponent', () => {
// This test describes 10 pages being on the first page // This test describes 10 pages being on the first page
beforeEach(() => { beforeEach(() => {
this.component.pagination = new FakePaginationInput(10, 1, 5); component.pagination = new FakePaginationInput(10, 1, 5);
}); });
it('is on the first page', () => { it('is on the first page', () => {
expect(this.component.current).toBe(1); expect(component.current).toBe(1);
expect(this.component.isFirstPage).toBe(true); expect(component.isFirstPage).toBe(true);
}); });
it('has the same, previous page', () => { it('has the same, previous page', () => {
expect(this.component.previous).toBe(1); expect(component.previous).toBe(1);
}); });
it('has next page', () => { it('has next page', () => {
expect(this.component.next).toBe(2); expect(component.next).toBe(2);
}); });
it('has range', () => { it('has range', () => {
expect(this.component.range).toEqual([ 1, 25 ]); expect(component.range).toEqual([ 1, 25 ]);
}); });
}); });
@@ -242,24 +227,24 @@ describe('PaginationComponent', () => {
// This test describes 10 pages being on the last page // This test describes 10 pages being on the last page
beforeEach(() => { beforeEach(() => {
this.component.pagination = new FakePaginationInput(10, 10, 5); component.pagination = new FakePaginationInput(10, 10, 5);
}); });
it('is on the last page', () => { it('is on the last page', () => {
expect(this.component.current).toBe(10); expect(component.current).toBe(10);
expect(this.component.isLastPage).toBe(true); expect(component.isLastPage).toBe(true);
}); });
it('has the same, next page', () => { it('has the same, next page', () => {
expect(this.component.next).toBe(10); expect(component.next).toBe(10);
}); });
it('has previous page', () => { it('has previous page', () => {
expect(this.component.previous).toBe(9); expect(component.previous).toBe(9);
}); });
it('has range', () => { it('has range', () => {
expect(this.component.range).toEqual([ 226, 230 ]); expect(component.range).toEqual([ 226, 230 ]);
}); });
}); });
@@ -268,7 +253,7 @@ describe('PaginationComponent', () => {
const { const {
current, lastPage, isFirstPage, isLastPage, current, lastPage, isFirstPage, isLastPage,
next, previous, range, pages next, previous, range, pages
} = this.component; } = component;
expect(lastPage).toBe(1, 'lastPage'); expect(lastPage).toBe(1, 'lastPage');
expect(previous).toBe(1, 'previous'); expect(previous).toBe(1, 'previous');
@@ -282,4 +267,54 @@ describe('PaginationComponent', () => {
expect(pages).toEqual([ 1 ], 'pages'); expect(pages).toEqual([ 1 ], 'pages');
}); });
}); });
describe('with paginated component', () => {
it('should take pagination from the external component', () => {
const pagination: Pagination = {};
const customComponent = <PaginatedComponent> {
pagination: new Subject<Pagination>()
};
component.target = customComponent;
component.ngOnInit();
customComponent.pagination.next(pagination);
expect(component.pagination).toBe(pagination);
});
it('should update pagination by subscription', () => {
const pagination1: Pagination = {};
const pagination2: Pagination = {};
const customComponent = <PaginatedComponent> {
pagination: new Subject<Pagination>()
};
component.target = customComponent;
component.ngOnInit();
customComponent.pagination.next(pagination1);
expect(component.pagination).toBe(pagination1);
customComponent.pagination.next(pagination2);
expect(component.pagination).toBe(pagination2);
});
it('should send pagination event to paginated component', () => {
const customComponent = <PaginatedComponent> {
pagination: new Subject<Pagination>(),
updatePagination() {}
};
spyOn(customComponent, 'updatePagination').and.stub();
component.target = customComponent;
component.ngOnInit();
component.goNext();
expect(customComponent.updatePagination).toHaveBeenCalled();
});
});
}); });

View File

@@ -22,11 +22,13 @@ import {
Input, Input,
OnInit, OnInit,
Output, Output,
ViewEncapsulation ViewEncapsulation,
ChangeDetectorRef
} from '@angular/core'; } from '@angular/core';
import { Pagination } from 'alfresco-js-api'; import { Pagination } from 'alfresco-js-api';
import { PaginationQueryParams } from './pagination-query-params.interface'; import { PaginationQueryParams } from './pagination-query-params.interface';
import { PaginatedComponent } from './paginated-component.interface';
@Component({ @Component({
selector: 'adf-pagination', selector: 'adf-pagination',
@@ -53,6 +55,9 @@ export class PaginationComponent implements OnInit {
CHANGE_PAGE_NUMBER: 'CHANGE_PAGE_NUMBER' CHANGE_PAGE_NUMBER: 'CHANGE_PAGE_NUMBER'
}; };
@Input()
target: PaginatedComponent;
@Input() @Input()
supportedPageSizes: number[] = [ 25, 50, 100 ]; supportedPageSizes: number[] = [ 25, 50, 100 ];
@@ -74,7 +79,16 @@ export class PaginationComponent implements OnInit {
@Output() @Output()
prevPage: EventEmitter<Pagination> = new EventEmitter<Pagination>(); prevPage: EventEmitter<Pagination> = new EventEmitter<Pagination>();
constructor(private cdr: ChangeDetectorRef) {
}
ngOnInit() { ngOnInit() {
if (this.target) {
this.target.pagination.subscribe(page => {
this.pagination = page;
this.cdr.detectChanges();
});
}
if (!this.pagination) { if (!this.pagination) {
this.pagination = PaginationComponent.DEFAULT_PAGINATION; this.pagination = PaginationComponent.DEFAULT_PAGINATION;
} }
@@ -201,5 +215,9 @@ export class PaginationComponent implements OnInit {
} }
change.emit(params); change.emit(params);
if (this.target) {
this.target.updatePagination(params);
}
} }
} }

View File

@@ -17,3 +17,5 @@
export * from './pagination.component'; export * from './pagination.component';
export * from './infinite-pagination.component'; export * from './infinite-pagination.component';
export * from './paginated-component.interface';
export * from './pagination-query-params.interface';