From 8b90d999acc4b332ff55f38a0fa5f6e0dde86e4e Mon Sep 17 00:00:00 2001 From: Andreas Awouters Date: Wed, 5 Feb 2025 13:59:19 +0100 Subject: [PATCH 01/26] 125969: Move constructor to server-cookie.service This makes it possible to remove the REQUEST import from cookie.service.ts which solves a typescript issue. --- src/app/core/services/cookie.service.ts | 8 +------- src/app/core/services/server-cookie.service.ts | 7 ++++++- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/app/core/services/cookie.service.ts b/src/app/core/services/cookie.service.ts index 0098e3ace4..939e19f317 100644 --- a/src/app/core/services/cookie.service.ts +++ b/src/app/core/services/cookie.service.ts @@ -1,7 +1,4 @@ -import { Inject, Injectable } from '@angular/core'; - -import { REQUEST } from '@nguniversal/express-engine/tokens'; - +import { Injectable } from '@angular/core'; import { Subject , Observable } from 'rxjs'; import { CookieAttributes } from 'js-cookie'; @@ -22,9 +19,6 @@ export abstract class CookieService implements ICookieService { protected readonly cookieSource = new Subject<{ readonly [key: string]: any }>(); public readonly cookies$ = this.cookieSource.asObservable(); - constructor(@Inject(REQUEST) protected req: any) { - } - public abstract set(name: string, value: any, options?: CookieAttributes): void; public abstract remove(name: string, options?: CookieAttributes): void; diff --git a/src/app/core/services/server-cookie.service.ts b/src/app/core/services/server-cookie.service.ts index 6ae3525c74..1cc7d4414f 100644 --- a/src/app/core/services/server-cookie.service.ts +++ b/src/app/core/services/server-cookie.service.ts @@ -1,10 +1,15 @@ -import { Injectable } from '@angular/core'; +import { Injectable, Inject } from '@angular/core'; import { CookieAttributes } from 'js-cookie'; import { CookieService, ICookieService } from './cookie.service'; +import { REQUEST } from '@nguniversal/express-engine/tokens'; @Injectable() export class ServerCookieService extends CookieService implements ICookieService { + constructor(@Inject(REQUEST) protected req: any) { + super(); + } + public set(name: string, value: any, options?: CookieAttributes): void { return; } From f82426b1dc8853b6a984fba2523474f145ecd3eb Mon Sep 17 00:00:00 2001 From: Andreas Awouters Date: Wed, 5 Feb 2025 16:05:48 +0100 Subject: [PATCH 02/26] 125969: Get rid of REQUEST and RESPONSE imports in AuthService --- src/app/core/auth/auth.service.ts | 30 +++++------- src/app/core/auth/server-auth.service.ts | 60 ++++++++++++++++++++++-- 2 files changed, 68 insertions(+), 22 deletions(-) diff --git a/src/app/core/auth/auth.service.ts b/src/app/core/auth/auth.service.ts index 6604936cde..b2bf590184 100644 --- a/src/app/core/auth/auth.service.ts +++ b/src/app/core/auth/auth.service.ts @@ -1,7 +1,6 @@ -import { Inject, Injectable, Optional } from '@angular/core'; +import { Inject, Injectable } from '@angular/core'; import { Router } from '@angular/router'; import { HttpHeaders } from '@angular/common/http'; -import { REQUEST, RESPONSE } from '@nguniversal/express-engine/tokens'; import { Observable, of as observableOf } from 'rxjs'; import { filter, map, startWith, switchMap, take } from 'rxjs/operators'; @@ -79,18 +78,17 @@ export class AuthService { */ private tokenRefreshTimer; - constructor(@Inject(REQUEST) protected req: any, - @Inject(NativeWindowService) protected _window: NativeWindowRef, - @Optional() @Inject(RESPONSE) private response: any, - protected authRequestService: AuthRequestService, - protected epersonService: EPersonDataService, - protected router: Router, - protected routeService: RouteService, - protected storage: CookieService, - protected store: Store, - protected hardRedirectService: HardRedirectService, - private notificationService: NotificationsService, - private translateService: TranslateService + constructor( + @Inject(NativeWindowService) protected _window: NativeWindowRef, + protected authRequestService: AuthRequestService, + protected epersonService: EPersonDataService, + protected router: Router, + protected routeService: RouteService, + protected storage: CookieService, + protected store: Store, + protected hardRedirectService: HardRedirectService, + protected notificationService: NotificationsService, + protected translateService: TranslateService ) { this.store.pipe( // when this service is constructed the store is not fully initialized yet @@ -473,10 +471,6 @@ export class AuthService { if (this._window.nativeWindow.location) { // Hard redirect to login page, so that all state is definitely lost this._window.nativeWindow.location.href = redirectUrl; - } else if (this.response) { - if (!this.response._headerSent) { - this.response.redirect(302, redirectUrl); - } } else { this.router.navigateByUrl(redirectUrl); } diff --git a/src/app/core/auth/server-auth.service.ts b/src/app/core/auth/server-auth.service.ts index fc8ab18bfb..e2d5ec8131 100644 --- a/src/app/core/auth/server-auth.service.ts +++ b/src/app/core/auth/server-auth.service.ts @@ -1,15 +1,25 @@ -import { Injectable } from '@angular/core'; +import { Injectable, Inject, Optional } from '@angular/core'; import { HttpHeaders } from '@angular/common/http'; - +import { REQUEST, RESPONSE } from '@nguniversal/express-engine/tokens'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; - import { hasValue, isNotEmpty } from '../../shared/empty.util'; import { HttpOptions } from '../dspace-rest/dspace-rest.service'; -import { AuthService } from './auth.service'; +import { AuthService, LOGIN_ROUTE } from './auth.service'; import { AuthStatus } from './models/auth-status.model'; import { AuthTokenInfo } from './models/auth-token-info.model'; import { RemoteData } from '../data/remote-data'; +import { NativeWindowService, NativeWindowRef } from '../services/window.service'; +import { AuthRequestService } from './auth-request.service'; +import { EPersonDataService } from '../eperson/eperson-data.service'; +import { Router } from '@angular/router'; +import { RouteService } from '../services/route.service'; +import { CookieService } from '../services/cookie.service'; +import { Store } from '@ngrx/store'; +import { AppState } from '../../app.reducer'; +import { HardRedirectService } from '../services/hard-redirect.service'; +import { NotificationsService } from '../../shared/notifications/notifications.service'; +import { TranslateService } from '@ngx-translate/core'; /** * The auth service. @@ -17,6 +27,34 @@ import { RemoteData } from '../data/remote-data'; @Injectable() export class ServerAuthService extends AuthService { + constructor( + @Inject(REQUEST) protected req: any, + @Optional() @Inject(RESPONSE) private response: any, + @Inject(NativeWindowService) protected _window: NativeWindowRef, + protected authRequestService: AuthRequestService, + protected epersonService: EPersonDataService, + protected router: Router, + protected routeService: RouteService, + protected storage: CookieService, + protected store: Store, + protected hardRedirectService: HardRedirectService, + protected notificationService: NotificationsService, + protected translateService: TranslateService + ) { + super( + _window, + authRequestService, + epersonService, + router, + routeService, + storage, + store, + hardRedirectService, + notificationService, + translateService + ); + } + /** * Returns the authenticated user * @returns {User} @@ -60,4 +98,18 @@ export class ServerAuthService extends AuthService { map((rd: RemoteData) => Object.assign(new AuthStatus(), rd.payload)) ); } + + override redirectToLoginWhenTokenExpired() { + const redirectUrl = LOGIN_ROUTE + '?expired=true'; + if (this._window.nativeWindow.location) { + // Hard redirect to login page, so that all state is definitely lost + this._window.nativeWindow.location.href = redirectUrl; + } else if (this.response) { + if (!this.response._headerSent) { + this.response.redirect(302, redirectUrl); + } + } else { + this.router.navigateByUrl(redirectUrl); + } + } } From 961bb11b59e44b67e86bd74fe5c114163a7fbd59 Mon Sep 17 00:00:00 2001 From: Andreas Awouters Date: Thu, 6 Feb 2025 11:18:53 +0100 Subject: [PATCH 03/26] 125969: Fix auth service tests --- src/app/core/auth/auth.service.spec.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/app/core/auth/auth.service.spec.ts b/src/app/core/auth/auth.service.spec.ts index b38d17aecd..32ceee35d6 100644 --- a/src/app/core/auth/auth.service.spec.ts +++ b/src/app/core/auth/auth.service.spec.ts @@ -260,7 +260,7 @@ describe('AuthService test', () => { (state as any).core = Object.create({}); (state as any).core.auth = authenticatedState; }); - authService = new AuthService({}, window, undefined, authReqService, mockEpersonDataService, router, routeService, cookieService, store, hardRedirectService, notificationsService, translateService); + authService = new AuthService(window, authReqService, mockEpersonDataService, router, routeService, cookieService, store, hardRedirectService, notificationsService, translateService); })); it('should return true when user is logged in', () => { @@ -345,7 +345,7 @@ describe('AuthService test', () => { (state as any).core = Object.create({}); (state as any).core.auth = authenticatedState; }); - authService = new AuthService({}, window, undefined, authReqService, mockEpersonDataService, router, routeService, cookieService, store, hardRedirectService, notificationsService, translateService); + authService = new AuthService(window, authReqService, mockEpersonDataService, router, routeService, cookieService, store, hardRedirectService, notificationsService, translateService); storage = (authService as any).storage; routeServiceMock = TestBed.inject(RouteService); routerStub = TestBed.inject(Router); @@ -565,7 +565,7 @@ describe('AuthService test', () => { (state as any).core = Object.create({}); (state as any).core.auth = unAuthenticatedState; }); - authService = new AuthService({}, window, undefined, authReqService, mockEpersonDataService, router, routeService, cookieService, store, hardRedirectService, notificationsService, translateService); + authService = new AuthService(window, authReqService, mockEpersonDataService, router, routeService, cookieService, store, hardRedirectService, notificationsService, translateService); })); it('should return null for the shortlived token', () => { @@ -605,7 +605,7 @@ describe('AuthService test', () => { (state as any).core = Object.create({}); (state as any).core.auth = idleState; }); - authService = new AuthService({}, window, undefined, authReqService, mockEpersonDataService, router, routeService, cookieService, store, hardRedirectService, notificationsService, translateService); + authService = new AuthService(window, authReqService, mockEpersonDataService, router, routeService, cookieService, store, hardRedirectService, notificationsService, translateService); })); it('isUserIdle should return true when user is not idle', () => { From e9fa2812a08534c45f595e8fb1938deb16c52798 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Feb 2025 02:52:11 +0000 Subject: [PATCH 04/26] Bump compression from 1.7.5 to 1.8.0 Bumps [compression](https://github.com/expressjs/compression) from 1.7.5 to 1.8.0. - [Release notes](https://github.com/expressjs/compression/releases) - [Changelog](https://github.com/expressjs/compression/blob/master/HISTORY.md) - [Commits](https://github.com/expressjs/compression/compare/1.7.5...1.8.0) --- updated-dependencies: - dependency-name: compression dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 1ab4e54262..7420cb4d20 100644 --- a/package.json +++ b/package.json @@ -78,7 +78,7 @@ "cerialize": "0.1.18", "cli-progress": "^3.12.0", "colors": "^1.4.0", - "compression": "^1.7.5", + "compression": "^1.8.0", "cookie-parser": "1.4.7", "core-js": "^3.40.0", "date-fns": "^2.30.0", diff --git a/yarn.lock b/yarn.lock index 7983caea23..2f166423a5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4129,10 +4129,10 @@ compression-webpack-plugin@^9.2.0: schema-utils "^4.0.0" serialize-javascript "^6.0.0" -compression@^1.7.4, compression@^1.7.5: - version "1.7.5" - resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.5.tgz#fdd256c0a642e39e314c478f6c2cd654edd74c93" - integrity sha512-bQJ0YRck5ak3LgtnpKkiabX5pNF7tMUh1BSy2ZBOTh0Dim0BUu6aPPwByIns6/A5Prh8PufSPerMDUklpzes2Q== +compression@^1.7.4, compression@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.8.0.tgz#09420efc96e11a0f44f3a558de59e321364180f7" + integrity sha512-k6WLKfunuqCYD3t6AsuPGvQWaKwuLLh2/xHNcX4qE+vIfDNXpSqnrhwA7O53R7WVQUnt8dVAIW+YHr7xTgOgGA== dependencies: bytes "3.1.2" compressible "~2.0.18" From 008fe0151be64abe6b1ea56125dc3c47cea76cd1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Mar 2025 03:10:07 +0000 Subject: [PATCH 05/26] Bump @types/lodash from 4.17.15 to 4.17.16 Bumps [@types/lodash](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/lodash) from 4.17.15 to 4.17.16. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/lodash) --- updated-dependencies: - dependency-name: "@types/lodash" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 1ab4e54262..ce4e4ed513 100644 --- a/package.json +++ b/package.json @@ -146,7 +146,7 @@ "@types/grecaptcha": "^3.0.9", "@types/jasmine": "~3.6.0", "@types/js-cookie": "2.2.6", - "@types/lodash": "^4.17.15", + "@types/lodash": "^4.17.16", "@types/node": "^14.18.63", "@types/sanitize-html": "^2.13.0", "@typescript-eslint/eslint-plugin": "^5.62.0", diff --git a/yarn.lock b/yarn.lock index 7983caea23..2bfdcb5829 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2539,10 +2539,10 @@ resolved "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz" integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== -"@types/lodash@^4.17.15": - version "4.17.15" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.15.tgz#12d4af0ed17cc7600ce1f9980cec48fc17ad1e89" - integrity sha512-w/P33JFeySuhN6JLkysYUK2gEmy9kHHFN7E8ro0tkfmlDOgxBDzWEZ/J8cWA+fHqFevpswDTFZnDx+R9lbL6xw== +"@types/lodash@^4.17.16": + version "4.17.16" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.16.tgz#94ae78fab4a38d73086e962d0b65c30d816bfb0a" + integrity sha512-HX7Em5NYQAXKW+1T+FiuG27NGwzJfCX3s1GjOa7ujxZa52kjJLOr4FUxT+giF6Tgxv1e+/czV/iTtBw27WTU9g== "@types/mime@*": version "3.0.1" From ac5c5c8a1480f95074374a30105bc5f10c0659b5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Mar 2025 03:10:19 +0000 Subject: [PATCH 06/26] Bump core-js from 3.40.0 to 3.41.0 Bumps [core-js](https://github.com/zloirock/core-js/tree/HEAD/packages/core-js) from 3.40.0 to 3.41.0. - [Release notes](https://github.com/zloirock/core-js/releases) - [Changelog](https://github.com/zloirock/core-js/blob/master/CHANGELOG.md) - [Commits](https://github.com/zloirock/core-js/commits/v3.41.0/packages/core-js) --- updated-dependencies: - dependency-name: core-js dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 1ab4e54262..5b7f9ad8fc 100644 --- a/package.json +++ b/package.json @@ -80,7 +80,7 @@ "colors": "^1.4.0", "compression": "^1.7.5", "cookie-parser": "1.4.7", - "core-js": "^3.40.0", + "core-js": "^3.41.0", "date-fns": "^2.30.0", "date-fns-tz": "^1.3.7", "deepmerge": "^4.3.1", diff --git a/yarn.lock b/yarn.lock index 7983caea23..ac17112446 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4272,10 +4272,10 @@ core-js-compat@^3.25.1: dependencies: browserslist "^4.21.5" -core-js@^3.40.0: - version "3.40.0" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.40.0.tgz#2773f6b06877d8eda102fc42f828176437062476" - integrity sha512-7vsMc/Lty6AGnn7uFpYT56QesI5D2Y/UkgKounk87OP9Z2H9Z8kj6jzcSGAxFmUtDOS0ntK6lbQz+Nsa0Jj6mQ== +core-js@^3.41.0: + version "3.41.0" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.41.0.tgz#57714dafb8c751a6095d028a7428f1fb5834a776" + integrity sha512-SJ4/EHwS36QMJd6h/Rg+GyR4A5xE0FSI3eZ+iBVpfqf1x0eTSg1smWLHrA+2jQThZSh97fmSgFSU8B61nxosxA== core-util-is@1.0.2: version "1.0.2" From 6c11621d91e5ea4001c739bea086d7b67326f7c5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Mar 2025 02:47:30 +0000 Subject: [PATCH 07/26] Bump isbot from 5.1.22 to 5.1.25 Bumps [isbot](https://github.com/omrilotan/isbot) from 5.1.22 to 5.1.25. - [Changelog](https://github.com/omrilotan/isbot/blob/main/CHANGELOG.md) - [Commits](https://github.com/omrilotan/isbot/compare/v5.1.22...v5.1.25) --- updated-dependencies: - dependency-name: isbot dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 1ab4e54262..f62fb65acc 100644 --- a/package.json +++ b/package.json @@ -91,7 +91,7 @@ "filesize": "^6.1.0", "http-proxy-middleware": "^2.0.7", "http-terminator": "^3.2.0", - "isbot": "^5.1.22", + "isbot": "^5.1.25", "js-cookie": "2.2.1", "js-yaml": "^4.1.0", "json5": "^2.2.3", diff --git a/yarn.lock b/yarn.lock index 7983caea23..421804eadc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7080,10 +7080,10 @@ isbinaryfile@^4.0.8: resolved "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz" integrity sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw== -isbot@^5.1.22: - version "5.1.22" - resolved "https://registry.yarnpkg.com/isbot/-/isbot-5.1.22.tgz#18a4a58bbfff6974ff7868dafea59907deb7b68d" - integrity sha512-RqCFY3cJy3c2y1I+rMn81cfzAR4XJwfPBC+M8kffUjbPzxApzyyv7Tbm1C/gXXq2dSCuD238pKFEWlQMTWsTFw== +isbot@^5.1.25: + version "5.1.25" + resolved "https://registry.yarnpkg.com/isbot/-/isbot-5.1.25.tgz#3f08f13a773a9cd86f7e498094f36974de0c151d" + integrity sha512-mqU76fmT7cpGG0JX1EzhCZIC+xovpH6TD2SAK18alonk0RG/RgChpGduJTYzRaq9a0COoFA99M9JVtEUOcScIw== isexe@^2.0.0: version "2.0.0" From fa6b8cc21d27e070666ac764c03671753fb8f73f Mon Sep 17 00:00:00 2001 From: abhinav Date: Fri, 21 Mar 2025 13:34:04 +0100 Subject: [PATCH 08/26] 129641: Fix Export button is enabled wrongly This fixes the export button being enabled when the second step is not active in bulk access edit. The tests have been updated accordingly --- .../bulk-access/bulk-access.component.spec.ts | 45 ++++++++++++++----- .../bulk-access/bulk-access.component.ts | 4 +- .../bulk-access-settings.component.ts | 4 ++ .../access-control-array-form.component.ts | 4 ++ ...access-control-form-container.component.ts | 4 ++ 5 files changed, 48 insertions(+), 13 deletions(-) diff --git a/src/app/access-control/bulk-access/bulk-access.component.spec.ts b/src/app/access-control/bulk-access/bulk-access.component.spec.ts index e9b253147d..4a545dc3dd 100644 --- a/src/app/access-control/bulk-access/bulk-access.component.spec.ts +++ b/src/app/access-control/bulk-access/bulk-access.component.spec.ts @@ -1,5 +1,5 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { NO_ERRORS_SCHEMA, Component } from '@angular/core'; import { TranslateModule } from '@ngx-translate/core'; import { of } from 'rxjs'; @@ -57,10 +57,15 @@ describe('BulkAccessComponent', () => { 'file': { } }; - const mockSettings: any = jasmine.createSpyObj('AccessControlFormContainerComponent', { - getValue: jasmine.createSpy('getValue'), - reset: jasmine.createSpy('reset') - }); + @Component({ + selector: 'ds-bulk-access-settings', + template: '' + }) + class MockBulkAccessSettingsComponent { + isFormValid = jasmine.createSpy('isFormValid').and.returnValue(false); + getValue = jasmine.createSpy('getValue'); + reset = jasmine.createSpy('reset'); + } const selection: any[] = [{ indexableObject: { uuid: '1234' } }, { indexableObject: { uuid: '5678' } }]; const selectableListState: SelectableListState = { id: 'test', selection }; const expectedIdList = ['1234', '5678']; @@ -73,7 +78,10 @@ describe('BulkAccessComponent', () => { RouterTestingModule, TranslateModule.forRoot() ], - declarations: [ BulkAccessComponent ], + declarations: [ + BulkAccessComponent, + MockBulkAccessSettingsComponent, + ], providers: [ { provide: BulkAccessControlService, useValue: bulkAccessControlServiceMock }, { provide: NotificationsService, useValue: NotificationsServiceStub }, @@ -102,7 +110,6 @@ describe('BulkAccessComponent', () => { (component as any).selectableListService.getSelectableList.and.returnValue(of(selectableListStateEmpty)); fixture.detectChanges(); - component.settings = mockSettings; }); it('should create', () => { @@ -119,13 +126,12 @@ describe('BulkAccessComponent', () => { }); - describe('when there are elements selected', () => { + describe('when there are elements selected and step two form is invalid', () => { beforeEach(() => { (component as any).selectableListService.getSelectableList.and.returnValue(of(selectableListState)); fixture.detectChanges(); - component.settings = mockSettings; }); it('should create', () => { @@ -136,9 +142,9 @@ describe('BulkAccessComponent', () => { expect(component.objectsSelected$.value).toEqual(expectedIdList); }); - it('should enable the execute button when there are objects selected', () => { + it('should not enable the execute button when there are objects selected and step two form is invalid', () => { component.objectsSelected$.next(['1234']); - expect(component.canExport()).toBe(true); + expect(component.canExport()).toBe(false); }); it('should call the settings reset method when reset is called', () => { @@ -146,6 +152,23 @@ describe('BulkAccessComponent', () => { expect(component.settings.reset).toHaveBeenCalled(); }); + + }); + + describe('when there are elements selectedted and the step two form is valid', () => { + + beforeEach(() => { + + (component as any).selectableListService.getSelectableList.and.returnValue(of(selectableListState)); + fixture.detectChanges(); + (component as any).settings.isFormValid.and.returnValue(true); + }); + + it('should enable the execute button when there are objects selected and step two form is valid', () => { + component.objectsSelected$.next(['1234']); + expect(component.canExport()).toBe(true); + }); + it('should call the bulkAccessControlService executeScript method when submit is called', () => { (component.settings as any).getValue.and.returnValue(mockFormState); bulkAccessControlService.createPayloadFile.and.returnValue(mockFile); diff --git a/src/app/access-control/bulk-access/bulk-access.component.ts b/src/app/access-control/bulk-access/bulk-access.component.ts index 04724614cb..bdea3d5cbe 100644 --- a/src/app/access-control/bulk-access/bulk-access.component.ts +++ b/src/app/access-control/bulk-access/bulk-access.component.ts @@ -37,7 +37,7 @@ export class BulkAccessComponent implements OnInit { constructor( private bulkAccessControlService: BulkAccessControlService, - private selectableListService: SelectableListService + private selectableListService: SelectableListService, ) { } @@ -51,7 +51,7 @@ export class BulkAccessComponent implements OnInit { } canExport(): boolean { - return this.objectsSelected$.value?.length > 0; + return this.objectsSelected$.value?.length > 0 && this.settings?.isFormValid(); } /** diff --git a/src/app/access-control/bulk-access/settings/bulk-access-settings.component.ts b/src/app/access-control/bulk-access/settings/bulk-access-settings.component.ts index eecc016245..5d1070893c 100644 --- a/src/app/access-control/bulk-access/settings/bulk-access-settings.component.ts +++ b/src/app/access-control/bulk-access/settings/bulk-access-settings.component.ts @@ -31,4 +31,8 @@ export class BulkAccessSettingsComponent { this.controlForm.reset(); } + isFormValid() { + return this.controlForm.isValid(); + } + } diff --git a/src/app/shared/access-control-form-container/access-control-array-form/access-control-array-form.component.ts b/src/app/shared/access-control-form-container/access-control-array-form/access-control-array-form.component.ts index 227de596ff..f91bae7858 100644 --- a/src/app/shared/access-control-form-container/access-control-array-form/access-control-array-form.component.ts +++ b/src/app/shared/access-control-form-container/access-control-array-form/access-control-array-form.component.ts @@ -119,6 +119,10 @@ export class AccessControlArrayFormComponent implements OnInit { return item.id; } + isValid() { + return this.ngForm.valid; + } + } diff --git a/src/app/shared/access-control-form-container/access-control-form-container.component.ts b/src/app/shared/access-control-form-container/access-control-form-container.component.ts index cddd1b1a29..ad3a3c0052 100644 --- a/src/app/shared/access-control-form-container/access-control-form-container.component.ts +++ b/src/app/shared/access-control-form-container/access-control-form-container.component.ts @@ -156,5 +156,9 @@ export class AccessControlFormContainerComponent impleme this.selectableListService.deselectAll(ITEM_ACCESS_CONTROL_SELECT_BITSTREAMS_LIST_ID); } + isValid() { + return this.bitstreamAccessCmp.isValid() || this.itemAccessCmp.isValid(); + } + } From ecc03343b7fb6640b3f59e076d824edbf0f2d527 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Mar 2025 02:43:43 +0000 Subject: [PATCH 09/26] Bump @babel/runtime from 7.26.7 to 7.27.0 Bumps [@babel/runtime](https://github.com/babel/babel/tree/HEAD/packages/babel-runtime) from 7.26.7 to 7.27.0. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.27.0/packages/babel-runtime) --- updated-dependencies: - dependency-name: "@babel/runtime" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 1ab4e54262..b992942b07 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ "@angular/platform-browser-dynamic": "^15.2.10", "@angular/platform-server": "^15.2.10", "@angular/router": "^15.2.10", - "@babel/runtime": "7.26.7", + "@babel/runtime": "7.27.0", "@kolkov/ngx-gallery": "^2.0.1", "@ng-bootstrap/ng-bootstrap": "^11.0.0", "@ng-dynamic-forms/core": "^15.0.0", diff --git a/yarn.lock b/yarn.lock index 7983caea23..f0df680c15 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1352,10 +1352,10 @@ dependencies: regenerator-runtime "^0.13.11" -"@babel/runtime@7.26.7", "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.12.0", "@babel/runtime@^7.14.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.21.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": - version "7.26.7" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.26.7.tgz#f4e7fe527cd710f8dc0618610b61b4b060c3c341" - integrity sha512-AOPI3D+a8dXnja+iwsUqGRjr1BbZIe771sXdapOtYI531gSqpi92vXivKcq2asu/DFpdl1ceFAKZyRzK2PCVcQ== +"@babel/runtime@7.27.0", "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.12.0", "@babel/runtime@^7.14.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.21.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": + version "7.27.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.27.0.tgz#fbee7cf97c709518ecc1f590984481d5460d4762" + integrity sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw== dependencies: regenerator-runtime "^0.14.0" From 7dd6ab79ffcb26a15b825b5eda46ce1aebc93370 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Fern=C3=A1ndez=20Celorio?= Date: Mon, 31 Mar 2025 09:14:32 +0200 Subject: [PATCH 10/26] Store the state of the computed filters --- .../search-filters.component.html | 10 +- .../search-filters.component.ts | 131 +++++++++++++++++- 2 files changed, 131 insertions(+), 10 deletions(-) diff --git a/src/app/shared/search/search-filters/search-filters.component.html b/src/app/shared/search/search-filters/search-filters.component.html index e1e54c683d..bb020f85b1 100644 --- a/src/app/shared/search/search-filters/search-filters.component.html +++ b/src/app/shared/search/search-filters/search-filters.component.html @@ -1,13 +1,13 @@

{{"search.filters.head" | translate}}

-
- -
+
+ +
- + {{"search.filters.reset" | translate}} diff --git a/src/app/shared/search/search-filters/search-filters.component.ts b/src/app/shared/search/search-filters/search-filters.component.ts index 831c32d76c..b23a645205 100644 --- a/src/app/shared/search/search-filters/search-filters.component.ts +++ b/src/app/shared/search/search-filters/search-filters.component.ts @@ -2,7 +2,7 @@ import { Component, Inject, Input, OnDestroy, OnInit } from '@angular/core'; import { Router } from '@angular/router'; import { BehaviorSubject, Observable } from 'rxjs'; -import { map, tap } from 'rxjs/operators'; +import { map, filter } from 'rxjs/operators'; import { SearchService } from '../../../core/shared/search/search.service'; import { RemoteData } from '../../../core/data/remote-data'; @@ -62,9 +62,16 @@ export class SearchFiltersComponent implements OnInit, OnDestroy { searchLink: string; /** - * Filters for which visibility has been computed + * Keeps track of the filters computed for each configuration during the current rendering cycle + * This array stores objects with configuration identifier and number of computed filters */ - filtersWithComputedVisibility = 0; + private currentFiltersComputed = []; + + /** + * Stores the final count of computed filters for each configuration + * Used to determine when all filters for a configuration have been processed + */ + private finalFiltersComputed = []; subs = []; defaultFilterCount: number; @@ -90,7 +97,6 @@ export class SearchFiltersComponent implements OnInit, OnDestroy { ngOnInit(): void { this.router.events.subscribe(() => { this.clearParams = this.searchConfigService.getCurrentFrontendFilters().pipe( - tap(() => this.filtersWithComputedVisibility = 0), map((filters) => { Object.keys(filters).forEach((f) => filters[f] = null); return filters; @@ -127,7 +133,122 @@ export class SearchFiltersComponent implements OnInit, OnDestroy { countFiltersWithComputedVisibility(computed: boolean) { if (computed) { - this.filtersWithComputedVisibility += 1; + this.filters.pipe( + // Get filter data and check if we need to increment the counter + map(filtersData => { + if (filtersData && filtersData.hasSucceeded && filtersData.payload) { + const totalFilters = filtersData.payload.length; + const currentComputed = this.getCurrentFiltersComputed(this.currentConfiguration); + + // If we've already computed all filters for this configuration + if (currentComputed >= totalFilters) { + // Register in finalFiltersComputed if not already registered + if (!this.findConfigInFinalFilters(this.currentConfiguration)) { + this.updateFinalFiltersComputed(this.currentConfiguration, totalFilters); + } + return { shouldIncrement: false }; + } + + // We haven't reached the total yet, proceed with increment + return { + shouldIncrement: true, + totalFilters + }; + } + return { shouldIncrement: false }; + }), + // Only continue if we need to increment the counter + filter(result => result.shouldIncrement), + // Increment the counter for the current configuration + map(result => { + const filterConfig = this.findConfigInCurrentFilters(this.currentConfiguration); + + if (filterConfig) { + // Update existing counter + filterConfig.filtersComputed += 1; + } else { + // Create new counter entry + this.currentFiltersComputed.push({ + configuration: this.currentConfiguration, + filtersComputed: 1 + }); + } + + // Pass along the total and updated count + return { + totalFilters: result.totalFilters, + currentComputed: this.getCurrentFiltersComputed(this.currentConfiguration) + }; + }), + // Check if we've reached the total after incrementing + map(result => { + if (result.currentComputed === result.totalFilters) { + // If we've reached the total, update final filters count + this.updateFinalFiltersComputed(this.currentConfiguration, result.currentComputed); + } + return result; + }) + ).subscribe().unsubscribe(); // Execute the pipeline and immediately unsubscribe } } + + /** + * Finds a configuration entry in the currentFiltersComputed array + * @param configuration The configuration identifier to search for + * @returns The filter configuration object if found, otherwise undefined + */ + private findConfigInCurrentFilters(configuration: string) { + return this.currentFiltersComputed.find( + (configFilter) => configFilter.configuration === configuration + ); + } + + /** + * Finds a configuration entry in the finalFiltersComputed array + * @param configuration The configuration identifier to search for + * @returns The filter configuration object if found, otherwise undefined + */ + private findConfigInFinalFilters(configuration: string) { + return this.finalFiltersComputed.find( + (configFilter) => configFilter.configuration === configuration + ); + } + + /** + * Updates or adds a new entry in the finalFiltersComputed array + * @param configuration The configuration identifier to update + * @param count The number of computed filters to set for this configuration + */ + private updateFinalFiltersComputed(configuration: string, count: number) { + const filterConfig = this.findConfigInFinalFilters(configuration); + + if (filterConfig) { + filterConfig.filtersComputed = count; + } else { + this.finalFiltersComputed.push({ + configuration, + filtersComputed: count + }); + } + } + + /** + * Gets the current number of computed filters for a specific configuration + * @param configuration The configuration identifier to get the count for + * @returns The number of computed filters, or 0 if none found + */ + private getCurrentFiltersComputed(configuration: string) { + const configFilter = this.findConfigInCurrentFilters(configuration); + return configFilter?.filtersComputed || 0; + } + + /** + * Gets the final number of computed filters for a specific configuration + * @param configuration The configuration identifier to get the count for + * @returns The number of computed filters in the final state, or 0 if none found + */ + getFinalFiltersComputed(configuration: string): number { + const configFilter = this.findConfigInFinalFilters(configuration); + return configFilter?.filtersComputed || 0; + } } From 0d2e49b12c744b6fe6bf82e4a9e698c1a21d6b9f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Apr 2025 03:06:35 +0000 Subject: [PATCH 11/26] Bump sass from 1.84.0 to 1.85.1 in the sass group across 1 directory Bumps the sass group with 1 update in the / directory: [sass](https://github.com/sass/dart-sass). Updates `sass` from 1.84.0 to 1.85.1 - [Release notes](https://github.com/sass/dart-sass/releases) - [Changelog](https://github.com/sass/dart-sass/blob/main/CHANGELOG.md) - [Commits](https://github.com/sass/dart-sass/compare/1.84.0...1.85.1) --- updated-dependencies: - dependency-name: sass dependency-type: direct:development update-type: version-update:semver-minor dependency-group: sass ... Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 1ab4e54262..7edbf9ea19 100644 --- a/package.json +++ b/package.json @@ -187,7 +187,7 @@ "react-copy-to-clipboard": "^5.1.0", "react-dom": "^16.14.0", "rimraf": "^3.0.2", - "sass": "~1.84.0", + "sass": "~1.86.3", "sass-loader": "^12.6.0", "sass-resources-loader": "^2.2.5", "ts-node": "^8.10.2", diff --git a/yarn.lock b/yarn.lock index 7983caea23..e6abd594b7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10270,10 +10270,10 @@ sass@1.58.1: immutable "^4.0.0" source-map-js ">=0.6.2 <2.0.0" -sass@^1.25.0, sass@~1.84.0: - version "1.84.0" - resolved "https://registry.yarnpkg.com/sass/-/sass-1.84.0.tgz#da9154cbccb2d2eac7a9486091b6d9ba93ef5bad" - integrity sha512-XDAbhEPJRxi7H0SxrnOpiXFQoUJHwkR2u3Zc4el+fK/Tt5Hpzw5kkQ59qVDfvdaUq6gCrEZIbySFBM2T9DNKHg== +sass@^1.25.0, sass@~1.86.3: + version "1.86.3" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.86.3.tgz#0a0d9ea97cb6665e73f409639f8533ce057464c9" + integrity sha512-iGtg8kus4GrsGLRDLRBRHY9dNVA78ZaS7xr01cWnS7PEMQyFtTqBiyCrfpTYTZXRWM94akzckYjh8oADfFNTzw== dependencies: chokidar "^4.0.0" immutable "^5.0.2" From 33146603dffd00ff0690d078034e5e69950e1d74 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 9 Apr 2025 22:26:28 +0000 Subject: [PATCH 12/26] Bump eslint-plugin-jsonc from 2.19.1 to 2.20.0 in the eslint group Bumps the eslint group with 1 update: [eslint-plugin-jsonc](https://github.com/ota-meshi/eslint-plugin-jsonc). Updates `eslint-plugin-jsonc` from 2.19.1 to 2.20.0 - [Release notes](https://github.com/ota-meshi/eslint-plugin-jsonc/releases) - [Changelog](https://github.com/ota-meshi/eslint-plugin-jsonc/blob/master/CHANGELOG.md) - [Commits](https://github.com/ota-meshi/eslint-plugin-jsonc/compare/v2.19.1...v2.20.0) --- updated-dependencies: - dependency-name: eslint-plugin-jsonc dependency-version: 2.20.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: eslint ... Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 88 +++++++++++++++++++++++++++++++++++----------------- 2 files changed, 60 insertions(+), 30 deletions(-) diff --git a/package.json b/package.json index 30cbf522ad..50f27bf8c5 100644 --- a/package.json +++ b/package.json @@ -163,7 +163,7 @@ "eslint-plugin-deprecation": "^1.5.0", "eslint-plugin-import": "^2.31.0", "eslint-plugin-jsdoc": "^45.0.0", - "eslint-plugin-jsonc": "^2.19.1", + "eslint-plugin-jsonc": "^2.20.0", "eslint-plugin-lodash": "^7.4.0", "eslint-plugin-unused-imports": "^2.0.0", "express-static-gzip": "^2.2.0", diff --git a/yarn.lock b/yarn.lock index 73194d1c4f..caea3d149c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1712,12 +1712,12 @@ resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.17.8.tgz#200a0965cf654ac28b971358ecdca9cc5b44c335" integrity sha512-1iuezdyDNngPnz8rLRDO2C/ZZ/emJLb72OsZeqQ6gL6Avko/XCXZw+NuxBSNhBAP13Hie418V7VMt9et1FMvpg== -"@eslint-community/eslint-utils@^4.2.0": - version "4.4.0" - resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz" - integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== +"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.5.1": + version "4.5.1" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.5.1.tgz#b0fc7e06d0c94f801537fd4237edc2706d3b8e4c" + integrity sha512-soEIOALTfTK6EjmKMMoLugwaP0rzkad90iIWd1hMO9ARkSAyjfMfkRRhLvD5qH7vvM0Cg72pieUfR6yh6XxC4w== dependencies: - eslint-visitor-keys "^3.3.0" + eslint-visitor-keys "^3.4.3" "@eslint-community/regexpp@^4.4.0": version "4.5.0" @@ -2243,6 +2243,11 @@ "@parcel/watcher-win32-ia32" "2.4.1" "@parcel/watcher-win32-x64" "2.4.1" +"@pkgr/core@^0.2.0": + version "0.2.2" + resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.2.2.tgz#224e466468489466a3ca77832be80cdd0bb8e523" + integrity sha512-25L86MyPvnlQoX2MTIV2OiUcb6vJ6aRbFa9pbwByn95INKD5mFH2smgjDhq+fwJoqAgvgbdJLj6Tz7V9X5CFAQ== + "@react-dnd/asap@^4.0.0": version "4.0.1" resolved "https://registry.npmjs.org/@react-dnd/asap/-/asap-4.0.1.tgz" @@ -3037,6 +3042,11 @@ acorn@^8.1.0, acorn@^8.2.4, acorn@^8.4.1, acorn@^8.5.0, acorn@^8.7.1, acorn@^8.8 resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.13.0.tgz#2a30d670818ad16ddd6a35d3842dacec9e5d7ca3" integrity sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w== +acorn@^8.14.0: + version "8.14.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.14.1.tgz#721d5dc10f7d5b5609a891773d47731796935dfb" + integrity sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg== + adjust-sourcemap-loader@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz" @@ -5299,10 +5309,10 @@ escodegen@^2.0.0: optionalDependencies: source-map "~0.6.1" -eslint-compat-utils@^0.6.0: - version "0.6.4" - resolved "https://registry.yarnpkg.com/eslint-compat-utils/-/eslint-compat-utils-0.6.4.tgz#173d305132da755ac3612cccab03e1b2e14235ed" - integrity sha512-/u+GQt8NMfXO8w17QendT4gvO5acfxQsAKirAt0LVxDnr2N8YLCVbregaNc/Yhp7NM128DwCaRvr8PLDfeNkQw== +eslint-compat-utils@^0.6.4: + version "0.6.5" + resolved "https://registry.yarnpkg.com/eslint-compat-utils/-/eslint-compat-utils-0.6.5.tgz#6b06350a1c947c4514cfa64a170a6bfdbadc7ec2" + integrity sha512-vAUHYzue4YAa2hNACjB8HvUQj5yehAZgiClyFVVom9cP8z5NSFq3PwB/TtJslN2zAMgRX6FCFCjYBbQh71g5RQ== dependencies: semver "^7.5.4" @@ -5377,19 +5387,19 @@ eslint-plugin-jsdoc@^45.0.0: semver "^7.5.1" spdx-expression-parse "^3.0.1" -eslint-plugin-jsonc@^2.19.1: - version "2.19.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-jsonc/-/eslint-plugin-jsonc-2.19.1.tgz#aeedd7131d115b8c46f439a8855139837a0e2752" - integrity sha512-MmlAOaZK1+Lg7YoCZPGRjb88ZjT+ct/KTsvcsbZdBm+w8WMzGx+XEmexk0m40P1WV9G2rFV7X3klyRGRpFXEjA== +eslint-plugin-jsonc@^2.20.0: + version "2.20.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsonc/-/eslint-plugin-jsonc-2.20.0.tgz#7f3ae51abd38176487ba7324dee77578a92e15e0" + integrity sha512-FRgCn9Hzk5eKboCbVMrr9QrhM0eO4G+WKH8IFXoaeqhM/2kuWzbStJn4kkr0VWL8J5H8RYZF+Aoam1vlBaZVkw== dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - eslint-compat-utils "^0.6.0" + "@eslint-community/eslint-utils" "^4.5.1" + eslint-compat-utils "^0.6.4" eslint-json-compat-utils "^0.2.1" - espree "^9.6.1" + espree "^9.6.1 || ^10.3.0" graphemer "^1.4.0" - jsonc-eslint-parser "^2.0.4" + jsonc-eslint-parser "^2.4.0" natural-compare "^1.4.0" - synckit "^0.6.0" + synckit "^0.6.2 || ^0.7.3 || ^0.10.3" eslint-plugin-lodash@^7.4.0: version "7.4.0" @@ -5451,11 +5461,16 @@ eslint-visitor-keys@^3.0.0, eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4 resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz" integrity sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ== -eslint-visitor-keys@^3.4.1: +eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: version "3.4.3" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== +eslint-visitor-keys@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz#687bacb2af884fcdda8a6e7d65c606f46a14cd45" + integrity sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw== + eslint@^8.39.0: version "8.39.0" resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.39.0.tgz#7fd20a295ef92d43809e914b70c39fd5a23cf3f1" @@ -5507,7 +5522,7 @@ esm@^3.2.25: resolved "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz" integrity sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA== -espree@^9.0.0, espree@^9.5.1, espree@^9.6.1: +espree@^9.0.0, espree@^9.5.1: version "9.6.1" resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== @@ -5516,6 +5531,15 @@ espree@^9.0.0, espree@^9.5.1, espree@^9.6.1: acorn-jsx "^5.3.2" eslint-visitor-keys "^3.4.1" +"espree@^9.6.1 || ^10.3.0": + version "10.3.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-10.3.0.tgz#29267cf5b0cb98735b65e64ba07e0ed49d1eed8a" + integrity sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg== + dependencies: + acorn "^8.14.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^4.2.0" + esprima@^4.0.0, esprima@^4.0.1: version "4.0.1" resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz" @@ -7350,10 +7374,10 @@ json5@^2.1.2, json5@^2.2.1, json5@^2.2.2, json5@^2.2.3: resolved "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== -jsonc-eslint-parser@^2.0.4: - version "2.1.0" - resolved "https://registry.yarnpkg.com/jsonc-eslint-parser/-/jsonc-eslint-parser-2.1.0.tgz#4c126b530aa583d85308d0b3041ff81ce402bbb2" - integrity sha512-qCRJWlbP2v6HbmKW7R3lFbeiVWHo+oMJ0j+MizwvauqnCV/EvtAeEeuCgoc/ErtsuoKgYB8U4Ih8AxJbXoE6/g== +jsonc-eslint-parser@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/jsonc-eslint-parser/-/jsonc-eslint-parser-2.4.0.tgz#74ded53f9d716e8d0671bd167bf5391f452d5461" + integrity sha512-WYDyuc/uFcGp6YtM2H0uKmUwieOuzeE/5YocFJLnLfclZ4inf3mRn8ZVy1s7Hxji7Jxm6Ss8gqpexD/GlKoGgg== dependencies: acorn "^8.5.0" eslint-visitor-keys "^3.0.0" @@ -10997,12 +11021,13 @@ symbol-tree@^3.2.4: resolved "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== -synckit@^0.6.0: - version "0.6.2" - resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.6.2.tgz#e1540b97825f2855f7170b98276e8463167f33eb" - integrity sha512-Vhf+bUa//YSTYKseDiiEuQmhGCoIF3CVBhunm3r/DQnYiGT4JssmnKQc44BIyOZRK2pKjXXAgbhfmbeoC9CJpA== +"synckit@^0.6.2 || ^0.7.3 || ^0.10.3": + version "0.10.3" + resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.10.3.tgz#940aea2c7b6d141a4f74dbdebc81e0958c331a4b" + integrity sha512-R1urvuyiTaWfeCggqEvpDJwAlDVdsT9NM+IP//Tk2x7qHCkSvBk/fwFgw/TLAHzZlrAnnazMcRw0ZD8HlYFTEQ== dependencies: - tslib "^2.3.1" + "@pkgr/core" "^0.2.0" + tslib "^2.8.1" tapable@^2.1.1, tapable@^2.2.0: version "2.2.1" @@ -11260,6 +11285,11 @@ tslib@^1.8.1, tslib@^1.9.0: resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== +tslib@^2.8.1: + version "2.8.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" + integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== + tsutils@^3.21.0: version "3.21.0" resolved "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz" From b37a7a1456b0230639a67a26727e0e83f1740ab8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 9 Apr 2025 22:27:19 +0000 Subject: [PATCH 13/26] Bump isbot from 5.1.25 to 5.1.26 Bumps [isbot](https://github.com/omrilotan/isbot) from 5.1.25 to 5.1.26. - [Changelog](https://github.com/omrilotan/isbot/blob/main/CHANGELOG.md) - [Commits](https://github.com/omrilotan/isbot/compare/v5.1.25...v5.1.26) --- updated-dependencies: - dependency-name: isbot dependency-version: 5.1.26 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 30cbf522ad..c4fc2a4284 100644 --- a/package.json +++ b/package.json @@ -91,7 +91,7 @@ "filesize": "^6.1.0", "http-proxy-middleware": "^2.0.7", "http-terminator": "^3.2.0", - "isbot": "^5.1.25", + "isbot": "^5.1.26", "js-cookie": "2.2.1", "js-yaml": "^4.1.0", "json5": "^2.2.3", diff --git a/yarn.lock b/yarn.lock index 73194d1c4f..cee2d31bce 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7080,10 +7080,10 @@ isbinaryfile@^4.0.8: resolved "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz" integrity sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw== -isbot@^5.1.25: - version "5.1.25" - resolved "https://registry.yarnpkg.com/isbot/-/isbot-5.1.25.tgz#3f08f13a773a9cd86f7e498094f36974de0c151d" - integrity sha512-mqU76fmT7cpGG0JX1EzhCZIC+xovpH6TD2SAK18alonk0RG/RgChpGduJTYzRaq9a0COoFA99M9JVtEUOcScIw== +isbot@^5.1.26: + version "5.1.26" + resolved "https://registry.yarnpkg.com/isbot/-/isbot-5.1.26.tgz#38c336503b8a7071a15437b2d11b41e65b903bd2" + integrity sha512-3wqJEYSIm59dYQjEF7zJ7T42aqaqxbCyJQda5rKCudJykuAnISptCHR/GSGpOnw8UrvU+mGueNLRJS5HXnbsXQ== isexe@^2.0.0: version "2.0.0" From 4f42c1e95f9859f8997e2a290263822237b41f8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Fern=C3=A1ndez=20Celorio?= Date: Thu, 10 Apr 2025 17:34:36 +0200 Subject: [PATCH 14/26] Use take instead unsubscribe --- .../shared/search/search-filters/search-filters.component.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/shared/search/search-filters/search-filters.component.ts b/src/app/shared/search/search-filters/search-filters.component.ts index b23a645205..b5aa10778d 100644 --- a/src/app/shared/search/search-filters/search-filters.component.ts +++ b/src/app/shared/search/search-filters/search-filters.component.ts @@ -2,7 +2,7 @@ import { Component, Inject, Input, OnDestroy, OnInit } from '@angular/core'; import { Router } from '@angular/router'; import { BehaviorSubject, Observable } from 'rxjs'; -import { map, filter } from 'rxjs/operators'; +import { map, filter, take } from 'rxjs/operators'; import { SearchService } from '../../../core/shared/search/search.service'; import { RemoteData } from '../../../core/data/remote-data'; @@ -188,7 +188,7 @@ export class SearchFiltersComponent implements OnInit, OnDestroy { } return result; }) - ).subscribe().unsubscribe(); // Execute the pipeline and immediately unsubscribe + ).pipe(take(1)).subscribe(); // Execute the pipeline and immediately unsubscribe } } From 036fd1c87191b3116e10dc62a11488444b731269 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 10 Apr 2025 19:27:52 +0000 Subject: [PATCH 15/26] Bump the testing group with 2 updates Bumps the testing group with 2 updates: [axe-core](https://github.com/dequelabs/axe-core) and [ng-mocks](https://github.com/help-me-mom/ng-mocks). Updates `axe-core` from 4.10.2 to 4.10.3 - [Release notes](https://github.com/dequelabs/axe-core/releases) - [Changelog](https://github.com/dequelabs/axe-core/blob/v4.10.3/CHANGELOG.md) - [Commits](https://github.com/dequelabs/axe-core/compare/v4.10.2...v4.10.3) Updates `ng-mocks` from 14.13.2 to 14.13.3 - [Release notes](https://github.com/help-me-mom/ng-mocks/releases) - [Changelog](https://github.com/help-me-mom/ng-mocks/blob/master/CHANGELOG.md) - [Commits](https://github.com/help-me-mom/ng-mocks/compare/v14.13.2...v14.13.3) --- updated-dependencies: - dependency-name: axe-core dependency-type: direct:development update-type: version-update:semver-patch dependency-group: testing - dependency-name: ng-mocks dependency-type: direct:development update-type: version-update:semver-patch dependency-group: testing ... Signed-off-by: dependabot[bot] --- package.json | 4 ++-- yarn.lock | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 50f27bf8c5..dc23b0a273 100644 --- a/package.json +++ b/package.json @@ -151,7 +151,7 @@ "@types/sanitize-html": "^2.13.0", "@typescript-eslint/eslint-plugin": "^5.62.0", "@typescript-eslint/parser": "^5.62.0", - "axe-core": "^4.10.2", + "axe-core": "^4.10.3", "compression-webpack-plugin": "^9.2.0", "copy-webpack-plugin": "^6.4.1", "cross-env": "^7.0.3", @@ -175,7 +175,7 @@ "karma-jasmine": "~4.0.0", "karma-jasmine-html-reporter": "^1.5.0", "karma-mocha-reporter": "2.2.5", - "ng-mocks": "^14.13.2", + "ng-mocks": "^14.13.4", "ngx-mask": "^13.1.7", "nodemon": "^2.0.22", "postcss": "^8.5", diff --git a/yarn.lock b/yarn.lock index caea3d149c..fae90b27b9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3414,10 +3414,10 @@ aws4@^1.8.0: resolved "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz" integrity sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg== -axe-core@^4.10.2: - version "4.10.2" - resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.10.2.tgz#85228e3e1d8b8532a27659b332e39b7fa0e022df" - integrity sha512-RE3mdQ7P3FRSe7eqCWoeQ/Z9QXrtniSjp1wUjt5nRC3WIpz5rSCve6o3fsZ2aCpJtrZjSZgjwXAoTO5k4tEI0w== +axe-core@^4.10.3: + version "4.10.3" + resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.10.3.tgz#04145965ac7894faddbac30861e5d8f11bfd14fc" + integrity sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg== axios@0.21.4: version "0.21.4" @@ -8399,10 +8399,10 @@ neo-async@^2.6.2: resolved "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== -ng-mocks@^14.13.2: - version "14.13.2" - resolved "https://registry.yarnpkg.com/ng-mocks/-/ng-mocks-14.13.2.tgz#ddd675d675eb16dfa85834e28dd42343853a6622" - integrity sha512-ItAB72Pc0uznL1j4TPsFp1wehhitVp7DARkc67aafeIk1FDgwnAZvzJwntMnIp/IWMSbzrEQ6kl3cc5euX1NRA== +ng-mocks@^14.13.4: + version "14.13.4" + resolved "https://registry.yarnpkg.com/ng-mocks/-/ng-mocks-14.13.4.tgz#bb53f7b75e0937fcfc8a2177a234a0937143f326" + integrity sha512-OFpzcx9vzeMqpVaBaukH8gvHRhor8iAkc8pOWakSPwxD3DuoHyDrjb/odgjI3Jq+Iaerqb3js1I4Sluu+0rLSQ== ng2-file-upload@1.4.0: version "1.4.0" From 828648aa7e6c9e3a433b4376355c265b67a8d944 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 10 Apr 2025 21:56:43 +0000 Subject: [PATCH 16/26] Bump axios from 1.7.9 to 1.8.4 Bumps [axios](https://github.com/axios/axios) from 1.7.9 to 1.8.4. - [Release notes](https://github.com/axios/axios/releases) - [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md) - [Commits](https://github.com/axios/axios/compare/v1.7.9...v1.8.4) --- updated-dependencies: - dependency-name: axios dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index dc23b0a273..c095aff2c9 100644 --- a/package.json +++ b/package.json @@ -73,7 +73,7 @@ "@nicky-lenaers/ngx-scroll-to": "^14.0.0", "angular-idle-preload": "3.0.0", "angulartics2": "^12.2.1", - "axios": "^1.7.9", + "axios": "^1.8.4", "bootstrap": "^4.6.1", "cerialize": "0.1.18", "cli-progress": "^3.12.0", diff --git a/yarn.lock b/yarn.lock index fae90b27b9..2e18ecafd9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3426,10 +3426,10 @@ axios@0.21.4: dependencies: follow-redirects "^1.14.0" -axios@^1.7.9: - version "1.7.9" - resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.9.tgz#d7d071380c132a24accda1b2cfc1535b79ec650a" - integrity sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw== +axios@^1.8.4: + version "1.8.4" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.8.4.tgz#78990bb4bc63d2cae072952d374835950a82f447" + integrity sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw== dependencies: follow-redirects "^1.15.6" form-data "^4.0.0" From dc3e84274759bb29b5165dbad4eea5828d65705e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Fern=C3=A1ndez=20Celorio?= Date: Fri, 11 Apr 2025 11:39:41 +0200 Subject: [PATCH 17/26] No need to subscribe anymore to the router events --- .../search-filters/search-filters.component.ts | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/app/shared/search/search-filters/search-filters.component.ts b/src/app/shared/search/search-filters/search-filters.component.ts index b5aa10778d..189062fea3 100644 --- a/src/app/shared/search/search-filters/search-filters.component.ts +++ b/src/app/shared/search/search-filters/search-filters.component.ts @@ -95,15 +95,13 @@ export class SearchFiltersComponent implements OnInit, OnDestroy { } ngOnInit(): void { - this.router.events.subscribe(() => { - this.clearParams = this.searchConfigService.getCurrentFrontendFilters().pipe( - map((filters) => { - Object.keys(filters).forEach((f) => filters[f] = null); - return filters; - }) - ); - this.searchLink = this.getSearchLink(); - }); + this.clearParams = this.searchConfigService.getCurrentFrontendFilters().pipe( + map((filters) => { + Object.keys(filters).forEach((f) => filters[f] = null); + return filters; + }) + ); + this.searchLink = this.getSearchLink(); } /** From cc202b7adb3a632a3cbc63669c1d4501cce2512b Mon Sep 17 00:00:00 2001 From: Nona Luypaert Date: Wed, 9 Apr 2025 12:03:11 +0200 Subject: [PATCH 18/26] 130081: Fix pagination on 'Select bistreams' modal on 'Access Control' tab (cherry picked from commit c03bbb01a2d4ebdedacff3b046a7ce0522bf971f) --- ...rol-select-bitstreams-modal.component.html | 13 +++-- ...ntrol-select-bitstreams-modal.component.ts | 47 +++++++++---------- 2 files changed, 29 insertions(+), 31 deletions(-) diff --git a/src/app/shared/access-control-form-container/item-access-control-select-bitstreams-modal/item-access-control-select-bitstreams-modal.component.html b/src/app/shared/access-control-form-container/item-access-control-select-bitstreams-modal/item-access-control-select-bitstreams-modal.component.html index 8cf0ecea38..88706e2df3 100644 --- a/src/app/shared/access-control-form-container/item-access-control-select-bitstreams-modal/item-access-control-select-bitstreams-modal.component.html +++ b/src/app/shared/access-control-form-container/item-access-control-select-bitstreams-modal/item-access-control-select-bitstreams-modal.component.html @@ -8,20 +8,19 @@