Fix pagination issues

This commit is contained in:
Giuseppe Digilio
2017-07-28 20:19:54 +02:00
parent 713d00f96d
commit aa6afea6e2
7 changed files with 142 additions and 62 deletions

View File

@@ -1,6 +1,6 @@
import {
ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy,
OnInit
ChangeDetectionStrategy, ChangeDetectorRef, Component, DoCheck, OnChanges, OnDestroy,
OnInit, SimpleChanges
} from '@angular/core';
import { ActivatedRoute, Params } from '@angular/router';
@@ -16,6 +16,8 @@ import { Item } from '../core/shared/item.model';
import { SortOptions, SortDirection } from '../core/cache/models/sort-options.model';
import { PaginationComponentOptions } from '../shared/pagination/pagination-component-options.model';
import { hasValue } from '../shared/empty.util';
import { PageInfo } from '../core/shared/page-info.model';
import { isUndefined } from 'util';
@Component({
selector: 'ds-collection-page',
@@ -23,7 +25,7 @@ import { hasValue } from '../shared/empty.util';
templateUrl: './collection-page.component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class CollectionPageComponent implements OnInit, OnDestroy {
export class CollectionPageComponent implements OnChanges, OnInit, OnDestroy {
collectionData: RemoteData<Collection>;
itemData: RemoteData<Item[]>;
logoData: RemoteData<Bitstream>;
@@ -31,6 +33,7 @@ export class CollectionPageComponent implements OnInit, OnDestroy {
sortConfig: SortOptions;
private subs: Subscription[] = [];
private collectionId: string;
private pageInfoState: PageInfo;
constructor(
private collectionDataService: CollectionDataService,
@@ -41,6 +44,10 @@ export class CollectionPageComponent implements OnInit, OnDestroy {
}
ngOnChanges(changes: SimpleChanges) {
console.log(changes);
}
ngOnInit(): void {
this.subs.push(this.route.params.map((params: Params) => params.id)
.subscribe((id: string) => {
@@ -84,13 +91,20 @@ export class CollectionPageComponent implements OnInit, OnDestroy {
}
updateResults() {
this.itemData = undefined;
this.itemData = null;
this.ref.markForCheck();
this.itemData = this.itemDataService.findAll({
scopeID: this.collectionId,
currentPage: this.config.currentPage,
elementsPerPage: this.config.pageSize,
sort: this.sortConfig
});
// this.ref.detectChanges();
this.itemData.pageInfo.subscribe((pageInfo) => {
if (isUndefined(this.pageInfoState) || this.pageInfoState !== pageInfo) {
this.pageInfoState = pageInfo;
this.ref.detectChanges();
}
});
}
}

View File

@@ -36,7 +36,6 @@ export class ResponseCacheService {
get(key: string): Observable<ResponseCacheEntry> {
return this.store.select<ResponseCacheEntry>('core', 'cache', 'response', key)
.filter((entry) => this.isValid(entry))
.distinctUntilChanged()
}
/**

View File

@@ -1,4 +1,5 @@
<ds-pagination [paginationOptions]="config"
[pageInfoState]="pageInfo"
[collectionSize]="(pageInfo | async)?.totalElements"
[sortOptions]="sortConfig"
[hideGear]="hideGear"

View File

@@ -5,7 +5,7 @@ import {
ViewEncapsulation,
ChangeDetectionStrategy,
OnInit,
Output
Output, SimpleChanges, OnChanges, ChangeDetectorRef, DoCheck
} from '@angular/core';
import { Observable } from 'rxjs/Observable';
@@ -25,7 +25,7 @@ import { SortOptions, SortDirection } from '../../core/cache/models/sort-options
styleUrls: ['../../object-list/object-list.component.scss'],
templateUrl: '../../object-list/object-list.component.html'
})
export class ObjectListComponent implements OnInit {
export class ObjectListComponent implements OnChanges, OnInit {
@Input() objects: RemoteData<DSpaceObject[]>;
@Input() config: PaginationComponentOptions;
@@ -59,10 +59,26 @@ export class ObjectListComponent implements OnInit {
@Output() sortFieldChange: EventEmitter<string> = new EventEmitter<string>();
data: any = {};
ngOnChanges(changes: SimpleChanges) {
if (changes.objects && !changes.objects.isFirstChange()) {
this.pageInfo = this.objects.pageInfo;
}
}
ngOnInit(): void {
this.pageInfo = this.objects.pageInfo;
}
/**
* @param route
* Route is a singleton service provided by Angular.
* @param router
* Router is a singleton service provided by Angular.
*/
constructor(
private cdRef: ChangeDetectorRef) {
}
onPageChange(event) {
this.pageChange.emit(event);
}

View File

@@ -1,4 +1,5 @@
<div *ngIf="!hideGear" class="pagination-masked clearfix top">
<div *ngIf="currentPageState == undefined || currentPageState == currentPage">
<div *ngIf="!hideGear" class="pagination-masked clearfix top">
<div class="row">
<div class="col pagination-info">
<span class="align-middle hidden-xs-down">{{ 'pagination.showing.label' | translate }}</span>
@@ -16,11 +17,11 @@
</div>
</div>
</div>
</div>
</div>
<ng-content></ng-content>
<ng-content></ng-content>
<div *ngIf="shouldShowBottomPager" class="pagination justify-content-center clearfix bottom">
<div *ngIf="shouldShowBottomPager" class="pagination justify-content-center clearfix bottom">
<ngb-pagination [boundaryLinks]="paginationOptions.boundaryLinks"
[collectionSize]="collectionSize"
[disabled]="paginationOptions.disabled"
@@ -31,4 +32,5 @@
[pageSize]="pageSize"
[rotate]="paginationOptions.rotate"
[size]="(isXs)?'sm':paginationOptions.size"></ngb-pagination>
</div>
</div>

View File

@@ -2,6 +2,7 @@
import { CommonModule } from '@angular/common';
import {
ChangeDetectorRef,
Component,
CUSTOM_ELEMENTS_SCHEMA,
DebugElement
@@ -161,6 +162,7 @@ describe('Pagination component', () => {
{ provide: GLOBAL_CONFIG, useValue: ENV_CONFIG },
{ provide: Router, useValue: routerStub },
{ provide: HostWindowService, useValue: hostWindowServiceStub },
ChangeDetectorRef,
PaginationComponent
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]

View File

@@ -1,12 +1,12 @@
import {
ChangeDetectionStrategy,
ChangeDetectionStrategy, ChangeDetectorRef,
Component,
EventEmitter,
Input,
OnChanges,
OnDestroy,
OnInit,
Output,
Output, SimpleChanges,
ViewEncapsulation
} from '@angular/core'
@@ -22,6 +22,10 @@ import { HostWindowState } from '../host-window.reducer';
import { PaginationComponentOptions } from './pagination-component-options.model';
import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model';
import { hasValue } from '../empty.util';
import { PageInfo } from '../../core/shared/page-info.model';
import { isUndefined } from 'util';
import { Store } from '@ngrx/store';
import { ObjectCacheState } from '../../core/cache/object-cache.reducer';
/**
* The default pagination controls component.
@@ -33,13 +37,18 @@ import { hasValue } from '../empty.util';
changeDetection: ChangeDetectionStrategy.Default,
encapsulation: ViewEncapsulation.Emulated
})
export class PaginationComponent implements OnDestroy, OnInit {
export class PaginationComponent implements OnChanges, OnDestroy, OnInit {
/**
* Number of items in collection.
*/
@Input() collectionSize: number;
/**
* Page state of a Remote paginated objects.
*/
@Input() pageInfoState: Observable<PageInfo> = undefined;
/**
* Configuration for the NgbPagination component.
*/
@@ -87,7 +96,12 @@ export class PaginationComponent implements OnDestroy, OnInit {
/**
* Current page.
*/
public currentPage = 1;
public currentPage;
/**
* Current page in the state of a Remote paginated objects.
*/
public currentPageState: number = undefined;
/**
* Current URL query parameters
@@ -113,12 +127,12 @@ export class PaginationComponent implements OnDestroy, OnInit {
/**
* Number of items per page.
*/
public pageSize = 10;
public pageSize;
/**
* Declare SortDirection enumeration to use it in the template
*/
public sortDirections = SortDirection
public sortDirections = SortDirection;
/**
* A number array that represents options for a context pagination limit.
@@ -154,6 +168,15 @@ export class PaginationComponent implements OnDestroy, OnInit {
total: null
};
ngOnChanges(changes: SimpleChanges) {
if (changes.pageInfoState && !changes.pageInfoState.isFirstChange()) {
this.subs.push(this.pageInfoState.subscribe((pageInfo) => {
/* TODO: this is a temporary fix for the pagination start index (0 or 1) discrepancy between the rest and the frontend respectively */
this.currentPageState = pageInfo.currentPage + 1;
}));
}
}
/**
* Method provided by Angular. Invoked after the constructor.
*/
@@ -161,28 +184,39 @@ export class PaginationComponent implements OnDestroy, OnInit {
this.subs.push(this.hostWindowService.isXs()
.subscribe((status: boolean) => {
this.isXs = status;
this.cdRef.markForCheck();
}));
this.checkConfig(this.paginationOptions);
if (this.pageInfoState) {
this.subs.push(this.pageInfoState.subscribe((pageInfo) => {
/* TODO: this is a temporary fix for the pagination start index (0 or 1) discrepancy between the rest and the frontend respectively */
this.currentPageState = pageInfo.currentPage + 1;
}));
}
this.id = this.paginationOptions.id || null;
this.currentPage = this.paginationOptions.currentPage;
this.pageSize = this.paginationOptions.pageSize;
this.pageSizeOptions = this.paginationOptions.pageSizeOptions;
this.sortDirection = this.sortOptions.direction;
this.sortField = this.sortOptions.field;
this.subs.push(this.route.queryParams
.filter((queryParams) => hasValue(queryParams))
.subscribe((queryParams) => {
this.currentQueryParams = queryParams;
// tslint:disable:triple-equals
if (this.id == queryParams.pageId
&& (this.paginationOptions.currentPage != queryParams.page
|| this.paginationOptions.pageSize != queryParams.pageSize
|| this.sortOptions.direction !== queryParams.sortDirection
if (this.id === queryParams.pageId
&& (this.paginationOptions.currentPage !== +queryParams.page
|| this.paginationOptions.pageSize !== +queryParams.pageSize
|| this.sortOptions.direction !== +queryParams.sortDirection
|| this.sortOptions.field !== queryParams.sortField)
) {
this.validateParams(queryParams.page, queryParams.pageSize, queryParams.sortDirection, queryParams.sortField);
} else if (isUndefined(queryParams.pageId) && !isUndefined(this.currentPage)) {
// When moving back from a page with query params to page without them, initialize to the first page
this.doPageChange(1);
} else {
this.currentPage = this.paginationOptions.currentPage;
this.pageSize = this.paginationOptions.pageSize;
this.sortDirection = this.sortOptions.direction;
this.sortField = this.sortOptions.field;
}
// tslint:enable:triple-equals
}));
this.setShowingDetail();
}
@@ -203,6 +237,7 @@ export class PaginationComponent implements OnDestroy, OnInit {
* Router is a singleton service provided by Angular.
*/
constructor(
private cdRef: ChangeDetectorRef,
private route: ActivatedRoute,
private router: Router,
public hostWindowService: HostWindowService) {
@@ -317,19 +352,30 @@ export class PaginationComponent implements OnDestroy, OnInit {
sortDirection: sortDirection,
sortField: sortField
}
}
);
});
} else {
// (+) converts string to a number
if (this.currentPage !== +page) {
this.currentPage = +page;
this.pageSize = +pageSize;
this.sortDirection = +sortDirection;
this.sortField = sortField;
this.pageChange.emit(this.currentPage);
}
if (this.pageSize !== +pageSize) {
this.pageSize = +pageSize;
this.pageSizeChange.emit(this.pageSize);
}
if (this.sortDirection !== +sortDirection) {
this.sortDirection = +sortDirection;
this.sortDirectionChange.emit(this.sortDirection);
}
if (this.sortField !== sortField) {
this.sortField = sortField;
this.sortFieldChange.emit(this.sortField);
}
this.cdRef.detectChanges();
}
}
/**