diff --git a/src/app/core/data/base/base-data.service.spec.ts b/src/app/core/data/base/base-data.service.spec.ts index 6a18ae27e58..3366209179d 100644 --- a/src/app/core/data/base/base-data.service.spec.ts +++ b/src/app/core/data/base/base-data.service.spec.ts @@ -78,6 +78,8 @@ describe('BaseDataService', () => { const msToLive = 15 * 60 * 1000; const payload = { foo: 'bar', + followLink1: {}, + followLink2: {}, _links: { self: Object.assign(new HALLink(), { href: 'self-test-link', @@ -413,7 +415,7 @@ describe('BaseDataService', () => { expectObservable(service.findByHref(selfLink, false, false, ...linksToFollow)).toBe(expected, values); flush(); - expect(objectCache.addDependency).toHaveBeenCalledTimes(4); + expect(objectCache.addDependency).toHaveBeenCalledTimes(3); }); }); }); @@ -621,7 +623,7 @@ describe('BaseDataService', () => { expectObservable(service.findListByHref(selfLink, findListOptions, false, false, ...linksToFollow)).toBe(expected, values); flush(); - expect(objectCache.addDependency).toHaveBeenCalledTimes(4); + expect(objectCache.addDependency).toHaveBeenCalledTimes(3); }); }); }); diff --git a/src/app/core/data/base/base-data.service.ts b/src/app/core/data/base/base-data.service.ts index 35f5e432993..5694cd77911 100644 --- a/src/app/core/data/base/base-data.service.ts +++ b/src/app/core/data/base/base-data.service.ts @@ -282,12 +282,15 @@ export class BaseDataService implements HALDataServic // Ensure all followLinks from the cached object are automatically invalidated when invalidating the cached object tap((remoteDataObject: RemoteData) => { if (hasValue(remoteDataObject?.payload?._links)) { - for (const followLink of Object.values(remoteDataObject.payload._links)) { - // followLink can be either an individual HALLink or a HALLink[] - const followLinksList: HALLink[] = [].concat(followLink); - for (const individualFollowLink of followLinksList) { - if (hasValue(individualFollowLink?.href)) { - this.addDependency(response$, individualFollowLink.href); + for (const followLinkName of Object.keys(remoteDataObject.payload._links)) { + // only add the followLinks if they are embedded + if (hasValue(remoteDataObject.payload[followLinkName]) && followLinkName !== 'self') { + // followLink can be either an individual HALLink or a HALLink[] + const followLinksList: HALLink[] = [].concat(remoteDataObject.payload._links[followLinkName]); + for (const individualFollowLink of followLinksList) { + if (hasValue(individualFollowLink?.href)) { + this.addDependency(response$, individualFollowLink.href); + } } } } @@ -334,12 +337,15 @@ export class BaseDataService implements HALDataServic if (hasValue(remoteDataObject?.payload?.page)) { for (const object of remoteDataObject.payload.page) { if (hasValue(object?._links)) { - for (const followLink of Object.values(object._links)) { - // followLink can be either an individual HALLink or a HALLink[] - const followLinksList: HALLink[] = [].concat(followLink); - for (const individualFollowLink of followLinksList) { - if (hasValue(individualFollowLink?.href)) { - this.addDependency(response$, individualFollowLink.href); + for (const followLinkName of Object.keys(object._links)) { + // only add the followLinks if they are embedded + if (hasValue(object[followLinkName]) && followLinkName !== 'self') { + // followLink can be either an individual HALLink or a HALLink[] + const followLinksList: HALLink[] = [].concat(object._links[followLinkName]); + for (const individualFollowLink of followLinksList) { + if (hasValue(individualFollowLink?.href)) { + this.addDependency(response$, individualFollowLink.href); + } } } } diff --git a/src/app/core/data/processes/process-data.service.ts b/src/app/core/data/processes/process-data.service.ts index 50a77c63a4b..080a4a4c09f 100644 --- a/src/app/core/data/processes/process-data.service.ts +++ b/src/app/core/data/processes/process-data.service.ts @@ -245,12 +245,14 @@ export class ProcessDataService extends IdentifiableDataService impleme ) ).subscribe((processRD: RemoteData) => { this.clearCurrentTimeout(processId); - const nextTimeout = this.timer(() => { - this.activelyBeingPolled.delete(processId); - this.invalidateByHref(processRD.payload._links.self.href); - }, pollingIntervalInMs); + if (processRD.hasSucceeded) { + const nextTimeout = this.timer(() => { + this.activelyBeingPolled.delete(processId); + this.invalidateByHref(processRD.payload._links.self.href); + }, pollingIntervalInMs); - this.activelyBeingPolled.set(processId, nextTimeout); + this.activelyBeingPolled.set(processId, nextTimeout); + } }); this.subs.set(processId, sub); diff --git a/src/app/process-page/detail/process-detail.component.ts b/src/app/process-page/detail/process-detail.component.ts index af6b56dcb47..793721dbd81 100644 --- a/src/app/process-page/detail/process-detail.component.ts +++ b/src/app/process-page/detail/process-detail.component.ts @@ -2,7 +2,7 @@ import { HttpClient } from '@angular/common/http'; import { Component, Inject, NgZone, OnInit, PLATFORM_ID, OnDestroy } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; import { BehaviorSubject, Observable } from 'rxjs'; -import { finalize, map, switchMap, take, tap, find, startWith } from 'rxjs/operators'; +import { finalize, map, switchMap, take, tap, find, startWith, filter } from 'rxjs/operators'; import { AuthService } from '../../core/auth/auth.service'; import { DSONameService } from '../../core/breadcrumbs/dso-name.service'; import { BitstreamDataService } from '../../core/data/bitstream-data.service'; @@ -80,6 +80,8 @@ export class ProcessDetailComponent implements OnInit, OnDestroy { isRefreshing$: Observable; + isDeleting: boolean; + protected autoRefreshingID: string; /** @@ -116,6 +118,7 @@ export class ProcessDetailComponent implements OnInit, OnDestroy { return [data.process as RemoteData]; } }), + filter(() => !this.isDeleting), redirectOn4xx(this.router, this.authService), ); @@ -215,15 +218,17 @@ export class ProcessDetailComponent implements OnInit, OnDestroy { * @param process */ deleteProcess(process: Process) { + this.isDeleting = true; this.processService.delete(process.processId).pipe( getFirstCompletedRemoteData() ).subscribe((rd) => { if (rd.hasSucceeded) { this.notificationsService.success(this.translateService.get('process.detail.delete.success')); this.closeModal(); - this.router.navigateByUrl(getProcessListRoute()); + void this.router.navigateByUrl(getProcessListRoute()); } else { this.notificationsService.error(this.translateService.get('process.detail.delete.error')); + this.isDeleting = false; } }); } diff --git a/src/app/process-page/process-breadcrumb.resolver.ts b/src/app/process-page/process-breadcrumb.resolver.ts index 23e3dca0a8a..fd0c1ad735a 100644 --- a/src/app/process-page/process-breadcrumb.resolver.ts +++ b/src/app/process-page/process-breadcrumb.resolver.ts @@ -6,8 +6,9 @@ import { Process } from './processes/process.model'; import { followLink } from '../shared/utils/follow-link-config.model'; import { ProcessDataService } from '../core/data/processes/process-data.service'; import { BreadcrumbConfig } from '../breadcrumbs/breadcrumb/breadcrumb-config.model'; -import { getRemoteDataPayload, getFirstSucceededRemoteData } from '../core/shared/operators'; +import { getFirstCompletedRemoteData } from '../core/shared/operators'; import { ProcessBreadcrumbsService } from './process-breadcrumbs.service'; +import { RemoteData } from '../core/data/remote-data'; /** * This class represents a resolver that requests a specific process before the route is activated @@ -28,12 +29,11 @@ export class ProcessBreadcrumbResolver implements Resolve { + getFirstCompletedRemoteData(), + map((object: RemoteData) => { const fullPath = state.url; const url = fullPath.substr(0, fullPath.indexOf(id)) + id; - return { provider: this.breadcrumbService, key: object, url: url }; + return { provider: this.breadcrumbService, key: object.payload, url: url }; }) ); } diff --git a/src/app/process-page/process-breadcrumbs.service.ts b/src/app/process-page/process-breadcrumbs.service.ts index 26b0787a536..ac490138b8f 100644 --- a/src/app/process-page/process-breadcrumbs.service.ts +++ b/src/app/process-page/process-breadcrumbs.service.ts @@ -3,6 +3,7 @@ import { Injectable } from '@angular/core'; import { BreadcrumbsProviderService } from '../core/breadcrumbs/breadcrumbsProviderService'; import { Breadcrumb } from '../breadcrumbs/breadcrumb/breadcrumb.model'; import { Process } from './processes/process.model'; +import { hasValue } from '../shared/empty.util'; /** * Service to calculate process breadcrumbs for a single part of the route @@ -16,6 +17,10 @@ export class ProcessBreadcrumbsService implements BreadcrumbsProviderService { - return observableOf([new Breadcrumb(key.processId + ' - ' + key.scriptName, url)]); + if (hasValue(key)) { + return observableOf([new Breadcrumb(key.processId + ' - ' + key.scriptName, url)]); + } else { + return observableOf([]); + } } }