mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-08 02:24:11 +00:00
Fix pagination issues
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy,
|
ChangeDetectionStrategy, ChangeDetectorRef, Component, DoCheck, OnChanges, OnDestroy,
|
||||||
OnInit
|
OnInit, SimpleChanges
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { ActivatedRoute, Params } from '@angular/router';
|
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 { SortOptions, SortDirection } from '../core/cache/models/sort-options.model';
|
||||||
import { PaginationComponentOptions } from '../shared/pagination/pagination-component-options.model';
|
import { PaginationComponentOptions } from '../shared/pagination/pagination-component-options.model';
|
||||||
import { hasValue } from '../shared/empty.util';
|
import { hasValue } from '../shared/empty.util';
|
||||||
|
import { PageInfo } from '../core/shared/page-info.model';
|
||||||
|
import { isUndefined } from 'util';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-collection-page',
|
selector: 'ds-collection-page',
|
||||||
@@ -23,7 +25,7 @@ import { hasValue } from '../shared/empty.util';
|
|||||||
templateUrl: './collection-page.component.html',
|
templateUrl: './collection-page.component.html',
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
})
|
})
|
||||||
export class CollectionPageComponent implements OnInit, OnDestroy {
|
export class CollectionPageComponent implements OnChanges, OnInit, OnDestroy {
|
||||||
collectionData: RemoteData<Collection>;
|
collectionData: RemoteData<Collection>;
|
||||||
itemData: RemoteData<Item[]>;
|
itemData: RemoteData<Item[]>;
|
||||||
logoData: RemoteData<Bitstream>;
|
logoData: RemoteData<Bitstream>;
|
||||||
@@ -31,6 +33,7 @@ export class CollectionPageComponent implements OnInit, OnDestroy {
|
|||||||
sortConfig: SortOptions;
|
sortConfig: SortOptions;
|
||||||
private subs: Subscription[] = [];
|
private subs: Subscription[] = [];
|
||||||
private collectionId: string;
|
private collectionId: string;
|
||||||
|
private pageInfoState: PageInfo;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private collectionDataService: CollectionDataService,
|
private collectionDataService: CollectionDataService,
|
||||||
@@ -41,6 +44,10 @@ export class CollectionPageComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnChanges(changes: SimpleChanges) {
|
||||||
|
console.log(changes);
|
||||||
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.subs.push(this.route.params.map((params: Params) => params.id)
|
this.subs.push(this.route.params.map((params: Params) => params.id)
|
||||||
.subscribe((id: string) => {
|
.subscribe((id: string) => {
|
||||||
@@ -84,13 +91,20 @@ export class CollectionPageComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateResults() {
|
updateResults() {
|
||||||
this.itemData = undefined;
|
this.itemData = null;
|
||||||
|
this.ref.markForCheck();
|
||||||
this.itemData = this.itemDataService.findAll({
|
this.itemData = this.itemDataService.findAll({
|
||||||
scopeID: this.collectionId,
|
scopeID: this.collectionId,
|
||||||
currentPage: this.config.currentPage,
|
currentPage: this.config.currentPage,
|
||||||
elementsPerPage: this.config.pageSize,
|
elementsPerPage: this.config.pageSize,
|
||||||
sort: this.sortConfig
|
sort: this.sortConfig
|
||||||
});
|
});
|
||||||
// this.ref.detectChanges();
|
this.itemData.pageInfo.subscribe((pageInfo) => {
|
||||||
|
if (isUndefined(this.pageInfoState) || this.pageInfoState !== pageInfo) {
|
||||||
|
this.pageInfoState = pageInfo;
|
||||||
|
this.ref.detectChanges();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
1
src/app/core/cache/response-cache.service.ts
vendored
1
src/app/core/cache/response-cache.service.ts
vendored
@@ -36,7 +36,6 @@ export class ResponseCacheService {
|
|||||||
get(key: string): Observable<ResponseCacheEntry> {
|
get(key: string): Observable<ResponseCacheEntry> {
|
||||||
return this.store.select<ResponseCacheEntry>('core', 'cache', 'response', key)
|
return this.store.select<ResponseCacheEntry>('core', 'cache', 'response', key)
|
||||||
.filter((entry) => this.isValid(entry))
|
.filter((entry) => this.isValid(entry))
|
||||||
.distinctUntilChanged()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
<ds-pagination [paginationOptions]="config"
|
<ds-pagination [paginationOptions]="config"
|
||||||
|
[pageInfoState]="pageInfo"
|
||||||
[collectionSize]="(pageInfo | async)?.totalElements"
|
[collectionSize]="(pageInfo | async)?.totalElements"
|
||||||
[sortOptions]="sortConfig"
|
[sortOptions]="sortConfig"
|
||||||
[hideGear]="hideGear"
|
[hideGear]="hideGear"
|
||||||
|
@@ -5,7 +5,7 @@ import {
|
|||||||
ViewEncapsulation,
|
ViewEncapsulation,
|
||||||
ChangeDetectionStrategy,
|
ChangeDetectionStrategy,
|
||||||
OnInit,
|
OnInit,
|
||||||
Output
|
Output, SimpleChanges, OnChanges, ChangeDetectorRef, DoCheck
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
|
|
||||||
import { Observable } from 'rxjs/Observable';
|
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'],
|
styleUrls: ['../../object-list/object-list.component.scss'],
|
||||||
templateUrl: '../../object-list/object-list.component.html'
|
templateUrl: '../../object-list/object-list.component.html'
|
||||||
})
|
})
|
||||||
export class ObjectListComponent implements OnInit {
|
export class ObjectListComponent implements OnChanges, OnInit {
|
||||||
|
|
||||||
@Input() objects: RemoteData<DSpaceObject[]>;
|
@Input() objects: RemoteData<DSpaceObject[]>;
|
||||||
@Input() config: PaginationComponentOptions;
|
@Input() config: PaginationComponentOptions;
|
||||||
@@ -59,10 +59,26 @@ export class ObjectListComponent implements OnInit {
|
|||||||
@Output() sortFieldChange: EventEmitter<string> = new EventEmitter<string>();
|
@Output() sortFieldChange: EventEmitter<string> = new EventEmitter<string>();
|
||||||
data: any = {};
|
data: any = {};
|
||||||
|
|
||||||
|
ngOnChanges(changes: SimpleChanges) {
|
||||||
|
if (changes.objects && !changes.objects.isFirstChange()) {
|
||||||
|
this.pageInfo = this.objects.pageInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.pageInfo = this.objects.pageInfo;
|
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) {
|
onPageChange(event) {
|
||||||
this.pageChange.emit(event);
|
this.pageChange.emit(event);
|
||||||
}
|
}
|
||||||
|
@@ -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="row">
|
||||||
<div class="col pagination-info">
|
<div class="col pagination-info">
|
||||||
<span class="align-middle hidden-xs-down">{{ 'pagination.showing.label' | translate }}</span>
|
<span class="align-middle hidden-xs-down">{{ 'pagination.showing.label' | translate }}</span>
|
||||||
@@ -16,11 +17,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</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"
|
<ngb-pagination [boundaryLinks]="paginationOptions.boundaryLinks"
|
||||||
[collectionSize]="collectionSize"
|
[collectionSize]="collectionSize"
|
||||||
[disabled]="paginationOptions.disabled"
|
[disabled]="paginationOptions.disabled"
|
||||||
@@ -31,4 +32,5 @@
|
|||||||
[pageSize]="pageSize"
|
[pageSize]="pageSize"
|
||||||
[rotate]="paginationOptions.rotate"
|
[rotate]="paginationOptions.rotate"
|
||||||
[size]="(isXs)?'sm':paginationOptions.size"></ngb-pagination>
|
[size]="(isXs)?'sm':paginationOptions.size"></ngb-pagination>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
ChangeDetectorRef,
|
||||||
Component,
|
Component,
|
||||||
CUSTOM_ELEMENTS_SCHEMA,
|
CUSTOM_ELEMENTS_SCHEMA,
|
||||||
DebugElement
|
DebugElement
|
||||||
@@ -161,6 +162,7 @@ describe('Pagination component', () => {
|
|||||||
{ provide: GLOBAL_CONFIG, useValue: ENV_CONFIG },
|
{ provide: GLOBAL_CONFIG, useValue: ENV_CONFIG },
|
||||||
{ provide: Router, useValue: routerStub },
|
{ provide: Router, useValue: routerStub },
|
||||||
{ provide: HostWindowService, useValue: hostWindowServiceStub },
|
{ provide: HostWindowService, useValue: hostWindowServiceStub },
|
||||||
|
ChangeDetectorRef,
|
||||||
PaginationComponent
|
PaginationComponent
|
||||||
],
|
],
|
||||||
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
||||||
|
@@ -1,12 +1,12 @@
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
ChangeDetectionStrategy,
|
ChangeDetectionStrategy, ChangeDetectorRef,
|
||||||
Component,
|
Component,
|
||||||
EventEmitter,
|
EventEmitter,
|
||||||
Input,
|
Input,
|
||||||
|
OnChanges,
|
||||||
OnDestroy,
|
OnDestroy,
|
||||||
OnInit,
|
OnInit,
|
||||||
Output,
|
Output, SimpleChanges,
|
||||||
ViewEncapsulation
|
ViewEncapsulation
|
||||||
} from '@angular/core'
|
} from '@angular/core'
|
||||||
|
|
||||||
@@ -22,6 +22,10 @@ import { HostWindowState } from '../host-window.reducer';
|
|||||||
import { PaginationComponentOptions } from './pagination-component-options.model';
|
import { PaginationComponentOptions } from './pagination-component-options.model';
|
||||||
import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model';
|
import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model';
|
||||||
import { hasValue } from '../empty.util';
|
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.
|
* The default pagination controls component.
|
||||||
@@ -33,13 +37,18 @@ import { hasValue } from '../empty.util';
|
|||||||
changeDetection: ChangeDetectionStrategy.Default,
|
changeDetection: ChangeDetectionStrategy.Default,
|
||||||
encapsulation: ViewEncapsulation.Emulated
|
encapsulation: ViewEncapsulation.Emulated
|
||||||
})
|
})
|
||||||
export class PaginationComponent implements OnDestroy, OnInit {
|
export class PaginationComponent implements OnChanges, OnDestroy, OnInit {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of items in collection.
|
* Number of items in collection.
|
||||||
*/
|
*/
|
||||||
@Input() collectionSize: number;
|
@Input() collectionSize: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Page state of a Remote paginated objects.
|
||||||
|
*/
|
||||||
|
@Input() pageInfoState: Observable<PageInfo> = undefined;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration for the NgbPagination component.
|
* Configuration for the NgbPagination component.
|
||||||
*/
|
*/
|
||||||
@@ -87,7 +96,12 @@ export class PaginationComponent implements OnDestroy, OnInit {
|
|||||||
/**
|
/**
|
||||||
* Current page.
|
* 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
|
* Current URL query parameters
|
||||||
@@ -113,12 +127,12 @@ export class PaginationComponent implements OnDestroy, OnInit {
|
|||||||
/**
|
/**
|
||||||
* Number of items per page.
|
* Number of items per page.
|
||||||
*/
|
*/
|
||||||
public pageSize = 10;
|
public pageSize;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Declare SortDirection enumeration to use it in the template
|
* 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.
|
* A number array that represents options for a context pagination limit.
|
||||||
@@ -154,6 +168,15 @@ export class PaginationComponent implements OnDestroy, OnInit {
|
|||||||
total: null
|
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.
|
* Method provided by Angular. Invoked after the constructor.
|
||||||
*/
|
*/
|
||||||
@@ -161,28 +184,39 @@ export class PaginationComponent implements OnDestroy, OnInit {
|
|||||||
this.subs.push(this.hostWindowService.isXs()
|
this.subs.push(this.hostWindowService.isXs()
|
||||||
.subscribe((status: boolean) => {
|
.subscribe((status: boolean) => {
|
||||||
this.isXs = status;
|
this.isXs = status;
|
||||||
|
this.cdRef.markForCheck();
|
||||||
}));
|
}));
|
||||||
this.checkConfig(this.paginationOptions);
|
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.id = this.paginationOptions.id || null;
|
||||||
this.currentPage = this.paginationOptions.currentPage;
|
|
||||||
this.pageSize = this.paginationOptions.pageSize;
|
|
||||||
this.pageSizeOptions = this.paginationOptions.pageSizeOptions;
|
this.pageSizeOptions = this.paginationOptions.pageSizeOptions;
|
||||||
this.sortDirection = this.sortOptions.direction;
|
|
||||||
this.sortField = this.sortOptions.field;
|
|
||||||
this.subs.push(this.route.queryParams
|
this.subs.push(this.route.queryParams
|
||||||
.filter((queryParams) => hasValue(queryParams))
|
.filter((queryParams) => hasValue(queryParams))
|
||||||
.subscribe((queryParams) => {
|
.subscribe((queryParams) => {
|
||||||
this.currentQueryParams = queryParams;
|
this.currentQueryParams = queryParams;
|
||||||
// tslint:disable:triple-equals
|
if (this.id === queryParams.pageId
|
||||||
if (this.id == queryParams.pageId
|
&& (this.paginationOptions.currentPage !== +queryParams.page
|
||||||
&& (this.paginationOptions.currentPage != queryParams.page
|
|| this.paginationOptions.pageSize !== +queryParams.pageSize
|
||||||
|| this.paginationOptions.pageSize != queryParams.pageSize
|
|| this.sortOptions.direction !== +queryParams.sortDirection
|
||||||
|| this.sortOptions.direction !== queryParams.sortDirection
|
|
||||||
|| this.sortOptions.field !== queryParams.sortField)
|
|| this.sortOptions.field !== queryParams.sortField)
|
||||||
) {
|
) {
|
||||||
this.validateParams(queryParams.page, queryParams.pageSize, queryParams.sortDirection, 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();
|
this.setShowingDetail();
|
||||||
}
|
}
|
||||||
@@ -203,6 +237,7 @@ export class PaginationComponent implements OnDestroy, OnInit {
|
|||||||
* Router is a singleton service provided by Angular.
|
* Router is a singleton service provided by Angular.
|
||||||
*/
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
|
private cdRef: ChangeDetectorRef,
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
private router: Router,
|
private router: Router,
|
||||||
public hostWindowService: HostWindowService) {
|
public hostWindowService: HostWindowService) {
|
||||||
@@ -317,19 +352,30 @@ export class PaginationComponent implements OnDestroy, OnInit {
|
|||||||
sortDirection: sortDirection,
|
sortDirection: sortDirection,
|
||||||
sortField: sortField
|
sortField: sortField
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
// (+) converts string to a number
|
// (+) converts string to a number
|
||||||
|
if (this.currentPage !== +page) {
|
||||||
this.currentPage = +page;
|
this.currentPage = +page;
|
||||||
this.pageSize = +pageSize;
|
|
||||||
this.sortDirection = +sortDirection;
|
|
||||||
this.sortField = sortField;
|
|
||||||
this.pageChange.emit(this.currentPage);
|
this.pageChange.emit(this.currentPage);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.pageSize !== +pageSize) {
|
||||||
|
this.pageSize = +pageSize;
|
||||||
this.pageSizeChange.emit(this.pageSize);
|
this.pageSizeChange.emit(this.pageSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.sortDirection !== +sortDirection) {
|
||||||
|
this.sortDirection = +sortDirection;
|
||||||
this.sortDirectionChange.emit(this.sortDirection);
|
this.sortDirectionChange.emit(this.sortDirection);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.sortField !== sortField) {
|
||||||
|
this.sortField = sortField;
|
||||||
this.sortFieldChange.emit(this.sortField);
|
this.sortFieldChange.emit(this.sortField);
|
||||||
}
|
}
|
||||||
|
this.cdRef.detectChanges();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user