Skip to content

Commit b06bfef

Browse files
[DURACOM-294] Fix pagination in ORCID queue table when discarding entries
1 parent db695d1 commit b06bfef

3 files changed

Lines changed: 83 additions & 22 deletions

File tree

src/app/item-page/orcid-page/orcid-queue/orcid-queue.component.html

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,16 @@
33
<div class="container">
44
<h2>{{ 'person.orcid.registry.queue' | translate }}</h2>
55

6-
<ds-alert *ngIf="(processing$ | async) !== true && (getList() | async)?.payload?.totalElements === 0"
6+
<ds-alert *ngIf="(processing$ | async) !== true && listDataRD?.payload?.totalElements === 0"
77
[type]="AlertTypeEnum.Info">
88
{{ 'person.page.orcid.sync-queue.empty-message' | translate}}
99
</ds-alert>
10-
<ds-pagination *ngIf="(processing$ | async) !== true && (getList() | async)?.payload?.totalElements > 0"
10+
<ds-pagination *ngIf="listDataRD?.payload?.totalElements > 0"
1111
[paginationOptions]="paginationOptions"
12-
[collectionSize]="(getList() | async)?.payload?.totalElements"
13-
[retainScrollPosition]="false" [hideGear]="true" (paginationChange)="updateList()">
12+
[collectionSize]="listDataRD?.payload?.totalElements"
13+
[retainScrollPosition]="true"
14+
[hideGear]="true"
15+
(paginationChange)="onPaginationChange()">
1416

1517
<div class="table-responsive">
1618
<table id="groups" class="table table-sm table-striped table-hover table-bordered">
@@ -22,7 +24,7 @@ <h2>{{ 'person.orcid.registry.queue' | translate }}</h2>
2224
</tr>
2325
</thead>
2426
<tbody>
25-
<tr *ngFor="let entry of (getList() | async)?.payload?.page" data-test="orcidQueueElementRow">
27+
<tr *ngFor="let entry of listDataRD?.payload?.page" data-test="orcidQueueElementRow">
2628
<td style="width: 15%" class="text-center align-middle">
2729
<i [ngClass]="getIconClass(entry)" [ngbTooltip]="getIconTooltip(entry) | translate"
2830
class="fa-2x" aria-hidden="true"></i>
@@ -51,3 +53,4 @@ <h2>{{ 'person.orcid.registry.queue' | translate }}</h2>
5153
</ds-pagination>
5254
</div>
5355
</div>
56+

src/app/item-page/orcid-page/orcid-queue/orcid-queue.component.spec.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,13 @@ import { Item } from '../../../core/shared/item.model';
2424
import { TranslateLoaderMock } from '../../../shared/mocks/translate-loader.mock';
2525
import { NotificationsService } from '../../../shared/notifications/notifications.service';
2626
import { PaginationComponent } from '../../../shared/pagination/pagination.component';
27-
import { createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils';
27+
import { createNoContentRemoteDataObject$, createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils';
2828
import { NotificationsServiceStub } from '../../../shared/testing/notifications-service.stub';
2929
import { PaginationServiceStub } from '../../../shared/testing/pagination-service.stub';
3030
import { createPaginatedList } from '../../../shared/testing/utils.test';
3131
import { OrcidQueueComponent } from './orcid-queue.component';
32+
import { Router } from '@angular/router';
33+
import { RouterMock } from "../../../shared/mocks/router.mock";
3234

3335
describe('OrcidQueueComponent test suite', () => {
3436
let component: OrcidQueueComponent;
@@ -111,7 +113,7 @@ describe('OrcidQueueComponent test suite', () => {
111113

112114
const orcidQueueElements = [orcidQueueElement(1), orcidQueueElement(2)];
113115

114-
const orcidQueueServiceSpy = jasmine.createSpyObj('orcidQueueService', ['searchByProfileItemId', 'clearFindByProfileItemRequests']);
116+
const orcidQueueServiceSpy = jasmine.createSpyObj('orcidQueueService', ['searchByProfileItemId', 'clearFindByProfileItemRequests', 'deleteById']);
115117
orcidQueueServiceSpy.searchByProfileItemId.and.returnValue(createSuccessfulRemoteDataObject$<PaginatedList<OrcidQueue>>(createPaginatedList<OrcidQueue>(orcidQueueElements)));
116118

117119
beforeEach(waitForAsync(() => {
@@ -136,6 +138,7 @@ describe('OrcidQueueComponent test suite', () => {
136138
{ provide: OrcidHistoryDataService, useValue: {} },
137139
{ provide: PaginationService, useValue: new PaginationServiceStub() },
138140
{ provide: NotificationsService, useValue: new NotificationsServiceStub() },
141+
{ provide: Router, useValue: new RouterMock() },
139142
],
140143
schemas: [NO_ERRORS_SCHEMA],
141144
})
@@ -166,4 +169,18 @@ describe('OrcidQueueComponent test suite', () => {
166169
expect(table.length).toBe(2);
167170
});
168171

172+
it('should handle pagination change', () => {
173+
spyOn(component, 'updateList');
174+
component.onPaginationChange();
175+
expect(component.updateList).toHaveBeenCalled();
176+
});
177+
178+
it('should discard an entry', waitForAsync(() => {
179+
spyOn(component, 'removeEntryFromList');
180+
orcidQueueServiceSpy.deleteById.and.returnValue(createNoContentRemoteDataObject$());
181+
component.discardEntry(orcidQueueElements[0]);
182+
fixture.whenStable().then(() => {
183+
expect(component.removeEntryFromList).toHaveBeenCalledWith(orcidQueueElements[0].id);
184+
});
185+
}));
169186
});

src/app/item-page/orcid-page/orcid-queue/orcid-queue.component.ts

Lines changed: 56 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
1-
import { CommonModule } from '@angular/common';
1+
import {
2+
CommonModule,
3+
DOCUMENT,
4+
} from '@angular/common';
25
import {
36
Component,
7+
Inject,
48
Input,
59
OnChanges,
610
OnDestroy,
711
OnInit,
812
SimpleChanges,
913
} from '@angular/core';
14+
import { Router } from '@angular/router';
1015
import { NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap';
1116
import {
1217
TranslateModule,
@@ -40,6 +45,7 @@ import { AlertType } from '../../../shared/alert/alert-type';
4045
import { hasValue } from '../../../shared/empty.util';
4146
import { ThemedLoadingComponent } from '../../../shared/loading/themed-loading.component';
4247
import { NotificationsService } from '../../../shared/notifications/notifications.service';
48+
import { ObjectTableComponent } from '../../../shared/object-table/object-table.component';
4349
import { PaginationComponent } from '../../../shared/pagination/pagination.component';
4450
import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model';
4551

@@ -54,6 +60,7 @@ import { PaginationComponentOptions } from '../../../shared/pagination/paginatio
5460
ThemedLoadingComponent,
5561
AlertComponent,
5662
PaginationComponent,
63+
ObjectTableComponent,
5764
],
5865
standalone: true,
5966
})
@@ -70,6 +77,7 @@ export class OrcidQueueComponent implements OnInit, OnDestroy, OnChanges {
7077
public paginationOptions: PaginationComponentOptions = Object.assign(new PaginationComponentOptions(), {
7178
id: 'oqp',
7279
pageSize: 5,
80+
currentPage: 1,
7381
});
7482

7583
/**
@@ -80,7 +88,7 @@ export class OrcidQueueComponent implements OnInit, OnDestroy, OnChanges {
8088
/**
8189
* A list of orcid queue records
8290
*/
83-
private list$: BehaviorSubject<RemoteData<PaginatedList<OrcidQueue>>> = new BehaviorSubject<RemoteData<PaginatedList<OrcidQueue>>>({} as any);
91+
listDataRD: RemoteData<PaginatedList<OrcidQueue>>;
8492

8593
/**
8694
* The AlertType enumeration
@@ -100,6 +108,8 @@ export class OrcidQueueComponent implements OnInit, OnDestroy, OnChanges {
100108
private paginationService: PaginationService,
101109
private notificationsService: NotificationsService,
102110
private orcidHistoryService: OrcidHistoryDataService,
111+
private router: Router,
112+
@Inject(DOCUMENT) private _document: Document,
103113
) {
104114
}
105115

@@ -119,24 +129,36 @@ export class OrcidQueueComponent implements OnInit, OnDestroy, OnChanges {
119129
updateList() {
120130
this.subs.push(
121131
this.paginationService.getCurrentPagination(this.paginationOptions.id, this.paginationOptions).pipe(
122-
debounceTime(100),
132+
debounceTime(300),
123133
distinctUntilChanged(),
124134
tap(() => this.processing$.next(true)),
125-
switchMap((config: PaginationComponentOptions) => this.orcidQueueService.searchByProfileItemId(this.item.id, config, false)),
135+
switchMap((currentPaginationOptions) => this.orcidQueueService.searchByProfileItemId(this.item.id, currentPaginationOptions, false)),
126136
getFirstCompletedRemoteData(),
127-
).subscribe((result: RemoteData<PaginatedList<OrcidQueue>>) => {
128-
this.processing$.next(false);
129-
this.list$.next(result);
130-
this.orcidQueueService.clearFindByProfileItemRequests();
137+
).subscribe({
138+
next: (result: RemoteData<PaginatedList<OrcidQueue>>) => {
139+
this.paginationOptions = Object.assign(this.paginationOptions, {
140+
currentPage: result.payload.pageInfo.currentPage,
141+
});
142+
this.processing$.next(false);
143+
this.listDataRD = result;
144+
this.orcidQueueService.clearFindByProfileItemRequests();
145+
},
131146
}),
132147
);
133148
}
134149

135150
/**
136-
* Return the list of orcid queue records
151+
* Handle pagination change.
152+
* Scroll to the pagination element and update the list with the new page
137153
*/
138-
getList(): Observable<RemoteData<PaginatedList<OrcidQueue>>> {
139-
return this.list$.asObservable();
154+
onPaginationChange(){
155+
const element = this._document.getElementById(`p-${this.paginationOptions.id}`);
156+
if (element) {
157+
setTimeout(() => {
158+
element.scrollIntoView({ behavior: 'smooth', block: 'end', inline: 'nearest' });
159+
}, 300);
160+
}
161+
this.updateList();
140162
}
141163

142164
/**
@@ -222,20 +244,40 @@ export class OrcidQueueComponent implements OnInit, OnDestroy, OnChanges {
222244
* @param orcidQueue The OrcidQueue object to discard
223245
*/
224246
discardEntry(orcidQueue: OrcidQueue) {
225-
this.processing$.next(true);
226247
this.subs.push(this.orcidQueueService.deleteById(orcidQueue.id).pipe(
227248
getFirstCompletedRemoteData(),
228249
).subscribe((remoteData) => {
229-
this.processing$.next(false);
230250
if (remoteData.isSuccess) {
251+
this.removeEntryFromList(orcidQueue.id);
231252
this.notificationsService.success(this.translateService.get('person.page.orcid.sync-queue.discard.success'));
232-
this.updateList();
233253
} else {
234254
this.notificationsService.error(this.translateService.get('person.page.orcid.sync-queue.discard.error'));
235255
}
236256
}));
237257
}
238258

259+
/**
260+
* Remove an entry from the list.
261+
* If the last element of the page is removed, navigate to the previous page.
262+
* @param id The id of the entry to remove
263+
*/
264+
removeEntryFromList(id: number) {
265+
const index = this.listDataRD?.payload?.page.findIndex((item) => item.id === id);
266+
if (index > -1) {
267+
this.listDataRD.payload.page.splice(index, 1);
268+
if (this.listDataRD.payload.page.length === 0 && this.listDataRD.payload.pageInfo.currentPage > 0) {
269+
this.paginationOptions.currentPage = this.paginationOptions.currentPage - 1;
270+
this.router.navigate([], {
271+
queryParams: {
272+
[`${this.paginationOptions.id}.page`]: this.paginationOptions.currentPage,
273+
},
274+
fragment: `p-${this.paginationOptions.id}`,
275+
});
276+
this.updateList();
277+
}
278+
}
279+
}
280+
239281
/**
240282
* Send a queue entry to orcid for the synchronization
241283
*
@@ -327,7 +369,6 @@ export class OrcidQueueComponent implements OnInit, OnDestroy, OnChanges {
327369
* Unsubscribe from all subscriptions
328370
*/
329371
ngOnDestroy(): void {
330-
this.list$ = null;
331372
this.subs.filter((subscription) => hasValue(subscription))
332373
.forEach((subscription) => subscription.unsubscribe());
333374
}

0 commit comments

Comments
 (0)