mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
* #1014 use document list to diplay search results * #1014 refactor pagination * #1014 documentation and scripts update * fix random erros on tests executrion * #1014 fix travis scripts and raise timeout jasmine * #1014 fix appveyor script * #1014 type nodeId
This commit is contained in:
committed by
Denys Vuika
parent
9e00b1d4f1
commit
b05247dade
@@ -441,6 +441,31 @@ let schema = ObjectDataTableAdapter.generateSchema(data);
|
||||
|
||||
```
|
||||
|
||||
# Pagination Component
|
||||
|
||||
The pagination object is a generic component to paginate component. The Alfresco API are paginated and returns a Pagination object. You can use the pagination object to feed the pagination component and then listen to the event which return the current pagination and query again the API with the options choose by the user.
|
||||
|
||||

|
||||
|
||||
|
||||
### Properties
|
||||
|
||||
| Name | Type | Default | Description
|
||||
| --- | --- | --- | --- |
|
||||
| `supportedPageSizes` | numer[] | [5, 10, 20, 50, 100] | This array describe the set of options showed in the pick list |
|
||||
| `maxItems` | boolean | false | Max number of element showed per page. If you pick another size from the pick list this option will be overwritten |
|
||||
| `pagination` | Pagination | {count: 0, totalItems: 0, skipCount: 0, maxItems: 20 , hasMoreItems: true} | The Alfresco Api return a pagination object, you can use it to feed the pagination component, or create your own. |
|
||||
|
||||
### Events
|
||||
|
||||
| Name | Description
|
||||
| --- | --- |
|
||||
| `changePageSize` | Emitted when user picks one of the options from the pick list |
|
||||
| `nextPage` | Emitted when user clicks next page button |
|
||||
| `prevPage` | Emitted when user clicks prev page button |
|
||||
|
||||
All the events carry with them the current pagination object.
|
||||
|
||||
## Build from sources
|
||||
|
||||
Alternatively you can build component from sources with the following commands:
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
@@ -1,7 +1,14 @@
|
||||
// Tun on full stack traces in errors to help debugging
|
||||
Error.stackTraceLimit = Infinity;
|
||||
|
||||
// jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000;
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 100000;
|
||||
|
||||
window.componentHandler = {
|
||||
upgradeAllRegistered: function () {
|
||||
},
|
||||
upgradeElement: function () {
|
||||
}
|
||||
};
|
||||
|
||||
__karma__.loaded = function() {};
|
||||
|
||||
|
@@ -15,5 +15,4 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export * from './paginationProvider.interface';
|
||||
export * from './pagination.component';
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<div *ngIf="provider" class="mdl-paging">
|
||||
<div class="mdl-paging">
|
||||
<span class="mdl-paging__per-page">
|
||||
<span class="mdl-paging__per-page-label">Rows per page:</span>
|
||||
<span class="mdl-paging__per-page-value" [attr.data-automation-id]="'rows_per_page_' + pageSize">{{pageSize}}</span>
|
||||
<span class="mdl-paging__per-page-value" [attr.data-automation-id]="'rows_per_page_' + pageSize">{{pagination.maxItems}}</span>
|
||||
<button alfresco-mdl-button id="pageSizePicker" class="mdl-button--icon mdl-paging__per-page-dropdown">
|
||||
<i class="material-icons">arrow_drop_down</i>
|
||||
</button>
|
||||
@@ -15,12 +15,12 @@
|
||||
</span>
|
||||
<span class="mdl-paging__count">{{summary}}</span>
|
||||
<button (click)="showPrevPage()"
|
||||
[disabled]="!prevPageAvail"
|
||||
[disabled]="!prevPageAvail()"
|
||||
alfresco-mdl-button class="mdl-button--icon mdl-paging__prev" [attr.data-automation-id]="prev_page">
|
||||
<i class="material-icons">keyboard_arrow_left</i>
|
||||
</button>
|
||||
<button (click)="showNextPage()"
|
||||
[disabled]="!nextPageAvail"
|
||||
[disabled]="!nextPageAvail()"
|
||||
alfresco-mdl-button class="mdl-button--icon mdl-paging__next" [attr.data-automation-id]="next_page">
|
||||
<i class="material-icons">keyboard_arrow_right</i>
|
||||
</button>
|
||||
|
@@ -16,17 +16,9 @@
|
||||
*/
|
||||
|
||||
import { PaginationComponent } from '../pagination/pagination.component';
|
||||
import { PaginationProvider, DataLoadedEventEmitter} from '../pagination/paginationProvider.interface';
|
||||
import { Injector } from '@angular/core';
|
||||
import { getTestBed, TestBed} from '@angular/core/testing';
|
||||
|
||||
class CustomPaginationProvider implements PaginationProvider {
|
||||
skipCount: number = 0;
|
||||
dataLoaded: DataLoadedEventEmitter;
|
||||
count: number = 200;
|
||||
hasMoreItems: boolean = false;
|
||||
maxItems: number = 20;
|
||||
}
|
||||
import { PaginationData } from '../../models/pagination.data';
|
||||
import { Injector, SimpleChange } from '@angular/core';
|
||||
import { getTestBed, TestBed } from '@angular/core/testing';
|
||||
|
||||
describe('PaginationComponent', () => {
|
||||
let injector: Injector;
|
||||
@@ -40,7 +32,13 @@ describe('PaginationComponent', () => {
|
||||
});
|
||||
injector = getTestBed();
|
||||
paginationComponent = injector.get(PaginationComponent);
|
||||
paginationComponent.provider = new CustomPaginationProvider();
|
||||
paginationComponent.pagination = new PaginationData(0, 0, 0, 20, true);
|
||||
});
|
||||
|
||||
it('should create Pagination object on init if no object pagination is passed', () => {
|
||||
paginationComponent.pagination = null;
|
||||
paginationComponent.ngOnInit();
|
||||
expect(paginationComponent.pagination).not.toBe(null);
|
||||
});
|
||||
|
||||
it('is defined', () => {
|
||||
@@ -48,35 +46,63 @@ describe('PaginationComponent', () => {
|
||||
});
|
||||
|
||||
it('page size', () => {
|
||||
expect(paginationComponent.pageSize).toBe(20);
|
||||
expect(paginationComponent.pagination.maxItems).toBe(20);
|
||||
});
|
||||
|
||||
it('set page size', () => {
|
||||
paginationComponent.pageSize = 100;
|
||||
expect(paginationComponent.pageSize).toBe(100);
|
||||
paginationComponent.pagination.maxItems = 100;
|
||||
expect(paginationComponent.pagination.maxItems).toBe(100);
|
||||
});
|
||||
|
||||
it('prevPageAvail', () => {
|
||||
expect(paginationComponent.prevPageAvail).toBe(false);
|
||||
it('prevPageAvail dafault false', () => {
|
||||
expect(paginationComponent.prevPageAvail()).toBe(false);
|
||||
});
|
||||
|
||||
it('nextPageAvail', () => {
|
||||
expect(paginationComponent.nextPageAvail).toBe(false);
|
||||
it('nextPageAvail default true', () => {
|
||||
expect(paginationComponent.nextPageAvail()).toBe(true);
|
||||
});
|
||||
|
||||
it('showNextPage', () => {
|
||||
expect(paginationComponent.provider.skipCount).toBe(0);
|
||||
expect(paginationComponent.pagination.skipCount).toBe(0);
|
||||
paginationComponent.showNextPage();
|
||||
expect(paginationComponent.provider.skipCount).toBe(20);
|
||||
expect(paginationComponent.pagination.skipCount).toBe(20);
|
||||
});
|
||||
|
||||
it('showPrevPage', () => {
|
||||
paginationComponent.provider.skipCount = 100;
|
||||
paginationComponent.pagination.skipCount = 100;
|
||||
paginationComponent.showPrevPage();
|
||||
expect(paginationComponent.provider.skipCount).toBe(80);
|
||||
expect(paginationComponent.pagination.skipCount).toBe(80);
|
||||
});
|
||||
|
||||
it('PaginationProvider', () => {
|
||||
expect(paginationComponent.provider instanceof CustomPaginationProvider).toBeTruthy();
|
||||
it('should update the summary on nextpage click', () => {
|
||||
spyOn(paginationComponent, 'updateSummary');
|
||||
|
||||
paginationComponent.showNextPage();
|
||||
|
||||
expect(paginationComponent.updateSummary).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should update the summary on prevpage click', () => {
|
||||
spyOn(paginationComponent, 'updateSummary');
|
||||
|
||||
paginationComponent.showPrevPage();
|
||||
|
||||
expect(paginationComponent.updateSummary).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should update the summary on chage page size click', () => {
|
||||
spyOn(paginationComponent, 'updateSummary');
|
||||
|
||||
paginationComponent.setPageSize(100);
|
||||
|
||||
expect(paginationComponent.updateSummary).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should update the summary on input pagination parameter change', () => {
|
||||
spyOn(paginationComponent, 'updateSummary');
|
||||
|
||||
paginationComponent.ngOnChanges({pagination: new SimpleChange(null, new PaginationData(0, 0, 0, 20, true))});
|
||||
|
||||
expect(paginationComponent.updateSummary).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
@@ -15,8 +15,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { PaginationProvider } from './paginationProvider.interface';
|
||||
import { SimpleChanges, OnChanges, EventEmitter, Output, Component, Input, OnInit } from '@angular/core';
|
||||
import { PaginationData } from '../../models/pagination.data';
|
||||
import { Pagination } from 'alfresco-js-api';
|
||||
|
||||
@Component({
|
||||
moduleId: module.id,
|
||||
@@ -24,68 +25,81 @@ import { PaginationProvider } from './paginationProvider.interface';
|
||||
templateUrl: './pagination.component.html',
|
||||
styleUrls: ['./pagination.component.css']
|
||||
})
|
||||
export class PaginationComponent implements OnInit {
|
||||
export class PaginationComponent implements OnInit, OnChanges {
|
||||
|
||||
DEFAULT_PAGE_SIZE: number = 20;
|
||||
static DEFAULT_PAGE_SIZE: number = 20;
|
||||
|
||||
private _summary: string = '';
|
||||
private summary: string = '';
|
||||
|
||||
@Input()
|
||||
supportedPageSizes: number[] = [5, 10, 20, 50, 100];
|
||||
|
||||
@Input()
|
||||
provider: PaginationProvider;
|
||||
maxItems: number = PaginationComponent.DEFAULT_PAGE_SIZE;
|
||||
|
||||
get pageSize(): number {
|
||||
if (this.provider) {
|
||||
return this.provider.maxItems;
|
||||
}
|
||||
return this.DEFAULT_PAGE_SIZE;
|
||||
@Input()
|
||||
pagination: Pagination;
|
||||
|
||||
@Output()
|
||||
changePageSize: EventEmitter<Pagination> = new EventEmitter();
|
||||
|
||||
@Output()
|
||||
nextPage: EventEmitter<Pagination> = new EventEmitter();
|
||||
|
||||
@Output()
|
||||
prevPage: EventEmitter<Pagination> = new EventEmitter();
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
set pageSize(value: number) {
|
||||
if (this.provider) {
|
||||
this.provider.maxItems = value;
|
||||
ngOnInit() {
|
||||
if (!this.pagination) {
|
||||
this.pagination = new PaginationData(0, 0, 0, this.maxItems, true);
|
||||
}
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
if (changes['pagination']) {
|
||||
if (changes['pagination'].currentValue) {
|
||||
this.pagination = changes['pagination'].currentValue;
|
||||
this.updateSummary();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setPageSize(value: number) {
|
||||
this.pageSize = value;
|
||||
this.pagination.maxItems = value;
|
||||
this.updateSummary();
|
||||
this.changePageSize.emit(this.pagination);
|
||||
}
|
||||
|
||||
get summary(): string {
|
||||
return this._summary;
|
||||
nextPageAvail(): boolean {
|
||||
return this.pagination.hasMoreItems;
|
||||
}
|
||||
|
||||
get nextPageAvail(): boolean {
|
||||
return this.provider.hasMoreItems;
|
||||
}
|
||||
|
||||
get prevPageAvail(): boolean {
|
||||
return this.provider.skipCount > 0;
|
||||
prevPageAvail(): boolean {
|
||||
return this.pagination.skipCount > 0;
|
||||
}
|
||||
|
||||
showNextPage() {
|
||||
this.provider.skipCount += this.provider.maxItems;
|
||||
this.pagination.skipCount += this.pagination.maxItems;
|
||||
this.updateSummary();
|
||||
this.nextPage.emit(this.pagination);
|
||||
}
|
||||
|
||||
showPrevPage() {
|
||||
this.provider.skipCount -= this.provider.maxItems;
|
||||
this.pagination.skipCount -= this.pagination.maxItems;
|
||||
this.updateSummary();
|
||||
this.prevPage.emit(this.pagination);
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.provider.dataLoaded.subscribe(() => {
|
||||
this.updateSummary();
|
||||
});
|
||||
}
|
||||
|
||||
private updateSummary() {
|
||||
let from = this.provider.skipCount;
|
||||
updateSummary() {
|
||||
let from = this.pagination.skipCount;
|
||||
if (from === 0) {
|
||||
from = 1;
|
||||
}
|
||||
let to = this.provider.skipCount + this.provider.count;
|
||||
let of = this.provider.totalItems;
|
||||
this._summary = `${from}-${to} of ${of}`;
|
||||
let to = this.pagination.skipCount + this.pagination.count;
|
||||
let of = this.pagination.totalItems;
|
||||
this.summary = `${from}-${to} of ${of}`;
|
||||
}
|
||||
}
|
||||
|
@@ -15,9 +15,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Subject } from 'rxjs/Rx';
|
||||
import { Pagination } from 'alfresco-js-api';
|
||||
|
||||
export interface PaginationProvider {
|
||||
export class PaginationData implements Pagination {
|
||||
|
||||
/**
|
||||
* The number of objects in the collection.
|
||||
@@ -34,7 +34,7 @@ export interface PaginationProvider {
|
||||
* An integer describing the total number of entities in the collection.
|
||||
* The API might not be able to determine this value, in which case this property will not be present.
|
||||
*/
|
||||
totalItems?: number;
|
||||
totalItems: number;
|
||||
|
||||
/**
|
||||
* An integer describing how many entities exist in the collection before those included in this list.
|
||||
@@ -47,18 +47,11 @@ export interface PaginationProvider {
|
||||
*/
|
||||
maxItems: number;
|
||||
|
||||
/**
|
||||
* An event that is emitted every time data is loaded.
|
||||
*/
|
||||
dataLoaded: DataLoadedEventEmitter;
|
||||
}
|
||||
|
||||
export class DataLoadedEventEmitter extends Subject<any> {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
emit(value) {
|
||||
super.next(value);
|
||||
constructor(count: number, totalItems: number, skipCount: number, maxItems: number, hasMoreItems: boolean) {
|
||||
this.count = count;
|
||||
this.hasMoreItems = hasMoreItems;
|
||||
this.totalItems = totalItems;
|
||||
this.skipCount = skipCount;
|
||||
this.maxItems = maxItems;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user