From 252b3673eea2a9bcd68f35af7fbe51b0c05fc5e3 Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Thu, 8 Feb 2024 16:14:38 +0100 Subject: [PATCH 1/3] 108915: Fixed issue that redirected you to 404 page when deleting the process on the process page --- src/app/process-page/detail/process-detail.component.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/app/process-page/detail/process-detail.component.ts b/src/app/process-page/detail/process-detail.component.ts index e86797d66e2..a9348f6589c 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 } 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 { isRefreshing$: Observable; + isDeleting: boolean; + /** * Reference to NgbModal */ @@ -113,6 +115,7 @@ export class ProcessDetailComponent implements OnInit { return [data.process as RemoteData]; } }), + filter(() => !this.isDeleting), redirectOn4xx(this.router, this.authService), ); @@ -203,15 +206,17 @@ export class ProcessDetailComponent implements OnInit { * @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; } }); } From ecb20bbcbfa8c35bc2d60fb62bd93546a1ef60a9 Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Thu, 8 Feb 2024 16:16:06 +0100 Subject: [PATCH 2/3] 108915: Fixed Proxy Timout error when retrieving a non-existing process --- .../core/data/processes/process-data.service.ts | 14 ++++++++------ .../process-page/process-breadcrumb.resolver.ts | 10 +++++----- .../process-page/process-breadcrumbs.service.ts | 7 ++++++- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/app/core/data/processes/process-data.service.ts b/src/app/core/data/processes/process-data.service.ts index f11367f6ecf..ac459068b1b 100644 --- a/src/app/core/data/processes/process-data.service.ts +++ b/src/app/core/data/processes/process-data.service.ts @@ -175,12 +175,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); - - this.activelyBeingPolled.set(processId, nextTimeout); + if (processRD.hasSucceeded) { + const nextTimeout = this.timer(() => { + this.activelyBeingPolled.delete(processId); + this.invalidateByHref(processRD.payload._links.self.href); + }, pollingIntervalInMs); + + this.activelyBeingPolled.set(processId, nextTimeout); + } }); // When the process completes create a one off subscription (the `find` completes the 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([]); + } } } From 8ddc62168ef82f32d00a89ce387003c49ad21af1 Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Mon, 19 Feb 2024 18:56:43 +0100 Subject: [PATCH 3/3] 108915: Prevent self links & unresolved followLinks to be added as dependencies --- .../core/data/base/base-data.service.spec.ts | 6 ++-- src/app/core/data/base/base-data.service.ts | 30 +++++++++++-------- 2 files changed, 22 insertions(+), 14 deletions(-) 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 c10f52d8a50..1ea35756d33 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', @@ -407,7 +409,7 @@ describe('BaseDataService', () => { expectObservable(service.findByHref(selfLink, false, false, ...linksToFollow)).toBe(expected, values); flush(); - expect(objectCache.addDependency).toHaveBeenCalledTimes(4); + expect(objectCache.addDependency).toHaveBeenCalledTimes(3); }); }); }); @@ -610,7 +612,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 473dbae0c73..aef680578b2 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); + } } } }