diff --git a/src/app/process-page/overview/table/process-overview-table.component.html b/src/app/process-page/overview/table/process-overview-table.component.html index 7433c0c401..cedfa68416 100644 --- a/src/app/process-page/overview/table/process-overview-table.component.html +++ b/src/app/process-page/overview/table/process-overview-table.component.html @@ -26,15 +26,15 @@ - - {{process.processStatus}} - {{process.scriptName}} - {{ePersonName}} - {{getInfoValueMethod(process)}} + + {{tableEntry.process.processStatus}} + {{tableEntry.process.scriptName}} + {{tableEntry.user}} + {{tableEntry.info}} diff --git a/src/app/process-page/overview/table/process-overview-table.component.ts b/src/app/process-page/overview/table/process-overview-table.component.ts index e89c4f7580..459a475ed2 100644 --- a/src/app/process-page/overview/table/process-overview-table.component.ts +++ b/src/app/process-page/overview/table/process-overview-table.component.ts @@ -1,6 +1,6 @@ import { Component, Input, OnInit } from '@angular/core'; import { ProcessStatus } from '../../processes/process-status.model'; -import { Observable } from 'rxjs'; +import { Observable, mergeMap, from as observableFrom } from 'rxjs'; import { RemoteData } from '../../../core/data/remote-data'; import { PaginatedList } from '../../../core/data/paginated-list.model'; import { Process } from '../../processes/process.model'; @@ -10,7 +10,7 @@ import { ProcessBulkDeleteService } from '../process-bulk-delete.service'; import { EPersonDataService } from '../../../core/eperson/eperson-data.service'; import { DSONameService } from '../../../core/breadcrumbs/dso-name.service'; import { getFirstSucceededRemoteDataPayload } from '../../../core/shared/operators'; -import { map, switchMap } from 'rxjs/operators'; +import { map, switchMap, toArray } from 'rxjs/operators'; import { EPerson } from '../../../core/eperson/models/eperson.model'; import { PaginationService } from 'src/app/core/pagination/pagination.service'; import { FindListOptions } from '../../../core/data/find-list-options.model'; @@ -18,6 +18,16 @@ import { redirectOn4xx } from '../../../core/shared/authorized.operators'; import { Router } from '@angular/router'; import { AuthService } from '../../../core/auth/auth.service'; +/** + * An interface to store a process and extra information related to the process + * that is displayed in the overview table. + */ +export interface ProcessOverviewTableEntry { + process: Process, + user: string, + info: string, +} + @Component({ selector: 'ds-process-overview-table', templateUrl: './process-overview-table.component.html' @@ -46,9 +56,9 @@ export class ProcessOverviewTableComponent implements OnInit { @Input() getInfoValueMethod: (process: Process) => string; /** - * List of processes to be shown in this table + * List of processes and their info to be shown in this table */ - processesRD$: Observable>>; + processesRD$: Observable>>; /** * The pagination ID for this overview section @@ -81,17 +91,66 @@ export class ProcessOverviewTableComponent implements OnInit { pageSize: 5, }); + // Get the current pagination from the route this.paginationOptions$ = this.paginationService.getCurrentPagination(this.paginationId, defaultPaginationOptions); + + // Once we have the pagination, retrieve the processes matching the process type and the pagination + // + // Reasoning why this monstrosity is the way it is: + // To avoid having to recalculate the names of the submitters every time the page reloads, these have to be + // retrieved beforehand and stored with the process. This is where the ProcessOverviewTableEntry interface comes in. + // By storing the process together with the submitters name and the additional information to be shown in the table, + // the template can be as dumb as possible. As the retrieval of the name also is done through an observable, this + // complicates the construction of the data a bit though. + // The reason why we store these as RemoteData> and not simply as + // ProcessOverviewTableEntry[] is as follows: + // When storing the PaginatedList and ProcessOverviewTableEntry[] separately, there is a small delay + // between the update of the paginatedList and the entryArray. This results in the processOverviewPage showing + // no processes for a split second every time the processes are updated which in turn causes the different + // sections of the page to jump around. By combining these and causing the page to update only once this is avoided. this.processesRD$ = this.paginationOptions$ .pipe( + // Map the paginationOptions to findListOptions map((paginationOptions: PaginationComponentOptions) => this.processOverviewService.getFindListOptions(paginationOptions)), + // Use the findListOptions to retrieve the relevant processes every interval switchMap((findListOptions: FindListOptions) => this.processOverviewService.getProcessesByProcessStatus( this.processStatus, findListOptions, this.useAutoRefreshingSearchBy ? this.autoRefreshInterval : null) ), + // Redirect the user when he is logged out redirectOn4xx(this.router, this.auth), + // Map RemoteData> to RemoteData> + switchMap((processesRD: RemoteData>) => { + // Create observable emitting all processes one by one + return observableFrom(processesRD.payload.page).pipe( + // Map every Process to ProcessOverviewTableEntry + mergeMap((process: Process) => { + return this.getEPersonName(process.userId).pipe( + map((name) => { + return { + process: process, + user: name, + info: this.getInfoValueMethod(process), + }; + }), + ); + }), + // Collect processOverviewTableEntries into array + toArray(), + // Create RemoteData> + map((entries: ProcessOverviewTableEntry[]) => { + const entriesPL: PaginatedList = + Object.assign(new PaginatedList(), processesRD.payload, { page: entries }); + const entriesRD: RemoteData> = + Object.assign({}, processesRD, { payload: entriesPL }); + return entriesRD; + }), + ); + }), + ); + } /** @@ -104,4 +163,5 @@ export class ProcessOverviewTableComponent implements OnInit { map((eperson: EPerson) => this.dsoNameService.getName(eperson)), ); } + }