@@ -51,3 +53,4 @@ {{ 'person.orcid.registry.queue' | translate }}
+
diff --git a/src/app/item-page/orcid-page/orcid-queue/orcid-queue.component.spec.ts b/src/app/item-page/orcid-page/orcid-queue/orcid-queue.component.spec.ts
index a32c7ef7a51..be4e73e41f1 100644
--- a/src/app/item-page/orcid-page/orcid-queue/orcid-queue.component.spec.ts
+++ b/src/app/item-page/orcid-page/orcid-queue/orcid-queue.component.spec.ts
@@ -8,6 +8,7 @@ import {
waitForAsync,
} from '@angular/core/testing';
import { By } from '@angular/platform-browser';
+import { Router } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
import {
TranslateLoader,
@@ -21,10 +22,14 @@ import { OrcidHistoryDataService } from '../../../core/orcid/orcid-history-data.
import { OrcidQueueDataService } from '../../../core/orcid/orcid-queue-data.service';
import { PaginationService } from '../../../core/pagination/pagination.service';
import { Item } from '../../../core/shared/item.model';
+import { RouterMock } from '../../../shared/mocks/router.mock';
import { TranslateLoaderMock } from '../../../shared/mocks/translate-loader.mock';
import { NotificationsService } from '../../../shared/notifications/notifications.service';
import { PaginationComponent } from '../../../shared/pagination/pagination.component';
-import { createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils';
+import {
+ createNoContentRemoteDataObject$,
+ createSuccessfulRemoteDataObject$,
+} from '../../../shared/remote-data.utils';
import { NotificationsServiceStub } from '../../../shared/testing/notifications-service.stub';
import { PaginationServiceStub } from '../../../shared/testing/pagination-service.stub';
import { createPaginatedList } from '../../../shared/testing/utils.test';
@@ -111,7 +116,7 @@ describe('OrcidQueueComponent test suite', () => {
const orcidQueueElements = [orcidQueueElement(1), orcidQueueElement(2)];
- const orcidQueueServiceSpy = jasmine.createSpyObj('orcidQueueService', ['searchByProfileItemId', 'clearFindByProfileItemRequests']);
+ const orcidQueueServiceSpy = jasmine.createSpyObj('orcidQueueService', ['searchByProfileItemId', 'clearFindByProfileItemRequests', 'deleteById']);
orcidQueueServiceSpy.searchByProfileItemId.and.returnValue(createSuccessfulRemoteDataObject$>(createPaginatedList(orcidQueueElements)));
beforeEach(waitForAsync(() => {
@@ -136,6 +141,7 @@ describe('OrcidQueueComponent test suite', () => {
{ provide: OrcidHistoryDataService, useValue: {} },
{ provide: PaginationService, useValue: new PaginationServiceStub() },
{ provide: NotificationsService, useValue: new NotificationsServiceStub() },
+ { provide: Router, useValue: new RouterMock() },
],
schemas: [NO_ERRORS_SCHEMA],
})
@@ -166,4 +172,18 @@ describe('OrcidQueueComponent test suite', () => {
expect(table.length).toBe(2);
});
+ it('should handle pagination change', () => {
+ spyOn(component, 'updateList');
+ component.onPaginationChange();
+ expect(component.updateList).toHaveBeenCalled();
+ });
+
+ it('should discard an entry', waitForAsync(() => {
+ spyOn(component, 'removeEntryFromList');
+ orcidQueueServiceSpy.deleteById.and.returnValue(createNoContentRemoteDataObject$());
+ component.discardEntry(orcidQueueElements[0]);
+ fixture.whenStable().then(() => {
+ expect(component.removeEntryFromList).toHaveBeenCalledWith(orcidQueueElements[0].id);
+ });
+ }));
});
diff --git a/src/app/item-page/orcid-page/orcid-queue/orcid-queue.component.ts b/src/app/item-page/orcid-page/orcid-queue/orcid-queue.component.ts
index dfc7fac5265..d4b0d657be7 100644
--- a/src/app/item-page/orcid-page/orcid-queue/orcid-queue.component.ts
+++ b/src/app/item-page/orcid-page/orcid-queue/orcid-queue.component.ts
@@ -1,12 +1,17 @@
-import { CommonModule } from '@angular/common';
+import {
+ CommonModule,
+ DOCUMENT,
+} from '@angular/common';
import {
Component,
+ Inject,
Input,
OnChanges,
OnDestroy,
OnInit,
SimpleChanges,
} from '@angular/core';
+import { Router } from '@angular/router';
import { NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap';
import {
TranslateModule,
@@ -40,6 +45,7 @@ import { AlertType } from '../../../shared/alert/alert-type';
import { hasValue } from '../../../shared/empty.util';
import { ThemedLoadingComponent } from '../../../shared/loading/themed-loading.component';
import { NotificationsService } from '../../../shared/notifications/notifications.service';
+import { ObjectTableComponent } from '../../../shared/object-table/object-table.component';
import { PaginationComponent } from '../../../shared/pagination/pagination.component';
import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model';
@@ -54,6 +60,7 @@ import { PaginationComponentOptions } from '../../../shared/pagination/paginatio
ThemedLoadingComponent,
AlertComponent,
PaginationComponent,
+ ObjectTableComponent,
],
standalone: true,
})
@@ -70,6 +77,7 @@ export class OrcidQueueComponent implements OnInit, OnDestroy, OnChanges {
public paginationOptions: PaginationComponentOptions = Object.assign(new PaginationComponentOptions(), {
id: 'oqp',
pageSize: 5,
+ currentPage: 1,
});
/**
@@ -80,7 +88,7 @@ export class OrcidQueueComponent implements OnInit, OnDestroy, OnChanges {
/**
* A list of orcid queue records
*/
- private list$: BehaviorSubject>> = new BehaviorSubject>>({} as any);
+ listDataRD: RemoteData>;
/**
* The AlertType enumeration
@@ -100,6 +108,8 @@ export class OrcidQueueComponent implements OnInit, OnDestroy, OnChanges {
private paginationService: PaginationService,
private notificationsService: NotificationsService,
private orcidHistoryService: OrcidHistoryDataService,
+ private router: Router,
+ @Inject(DOCUMENT) private _document: Document,
) {
}
@@ -119,24 +129,36 @@ export class OrcidQueueComponent implements OnInit, OnDestroy, OnChanges {
updateList() {
this.subs.push(
this.paginationService.getCurrentPagination(this.paginationOptions.id, this.paginationOptions).pipe(
- debounceTime(100),
+ debounceTime(300),
distinctUntilChanged(),
tap(() => this.processing$.next(true)),
- switchMap((config: PaginationComponentOptions) => this.orcidQueueService.searchByProfileItemId(this.item.id, config, false)),
+ switchMap((currentPaginationOptions) => this.orcidQueueService.searchByProfileItemId(this.item.id, currentPaginationOptions, false)),
getFirstCompletedRemoteData(),
- ).subscribe((result: RemoteData>) => {
- this.processing$.next(false);
- this.list$.next(result);
- this.orcidQueueService.clearFindByProfileItemRequests();
+ ).subscribe({
+ next: (result: RemoteData>) => {
+ this.paginationOptions = Object.assign(this.paginationOptions, {
+ currentPage: result.payload.pageInfo.currentPage,
+ });
+ this.processing$.next(false);
+ this.listDataRD = result;
+ this.orcidQueueService.clearFindByProfileItemRequests();
+ },
}),
);
}
/**
- * Return the list of orcid queue records
+ * Handle pagination change.
+ * Scroll to the pagination element and update the list with the new page
*/
- getList(): Observable>> {
- return this.list$.asObservable();
+ onPaginationChange(){
+ const element = this._document.getElementById(`p-${this.paginationOptions.id}`);
+ if (element) {
+ setTimeout(() => {
+ element.scrollIntoView({ behavior: 'smooth', block: 'end', inline: 'nearest' });
+ }, 300);
+ }
+ this.updateList();
}
/**
@@ -222,20 +244,40 @@ export class OrcidQueueComponent implements OnInit, OnDestroy, OnChanges {
* @param orcidQueue The OrcidQueue object to discard
*/
discardEntry(orcidQueue: OrcidQueue) {
- this.processing$.next(true);
this.subs.push(this.orcidQueueService.deleteById(orcidQueue.id).pipe(
getFirstCompletedRemoteData(),
).subscribe((remoteData) => {
- this.processing$.next(false);
if (remoteData.isSuccess) {
+ this.removeEntryFromList(orcidQueue.id);
this.notificationsService.success(this.translateService.get('person.page.orcid.sync-queue.discard.success'));
- this.updateList();
} else {
this.notificationsService.error(this.translateService.get('person.page.orcid.sync-queue.discard.error'));
}
}));
}
+ /**
+ * Remove an entry from the list.
+ * If the last element of the page is removed, navigate to the previous page.
+ * @param id The id of the entry to remove
+ */
+ removeEntryFromList(id: number) {
+ const index = this.listDataRD?.payload?.page.findIndex((item) => item.id === id);
+ if (index > -1) {
+ this.listDataRD.payload.page.splice(index, 1);
+ if (this.listDataRD.payload.page.length === 0 && this.listDataRD.payload.pageInfo.currentPage > 0) {
+ this.paginationOptions.currentPage = this.paginationOptions.currentPage - 1;
+ this.router.navigate([], {
+ queryParams: {
+ [`${this.paginationOptions.id}.page`]: this.paginationOptions.currentPage,
+ },
+ fragment: `p-${this.paginationOptions.id}`,
+ });
+ this.updateList();
+ }
+ }
+ }
+
/**
* Send a queue entry to orcid for the synchronization
*
@@ -327,7 +369,6 @@ export class OrcidQueueComponent implements OnInit, OnDestroy, OnChanges {
* Unsubscribe from all subscriptions
*/
ngOnDestroy(): void {
- this.list$ = null;
this.subs.filter((subscription) => hasValue(subscription))
.forEach((subscription) => subscription.unsubscribe());
}
|