From 928d7a45a372003547b86be1ff3725288da43ad4 Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Tue, 27 Jun 2023 15:26:49 +0200 Subject: [PATCH 01/45] 103176: Fix vcr not being defined yet in OnInit hook --- src/app/shared/theme-support/themed.component.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/app/shared/theme-support/themed.component.ts b/src/app/shared/theme-support/themed.component.ts index 2ff0713f460..920fbba6e56 100644 --- a/src/app/shared/theme-support/themed.component.ts +++ b/src/app/shared/theme-support/themed.component.ts @@ -1,10 +1,10 @@ import { + AfterViewInit, Component, ViewChild, ViewContainerRef, ComponentRef, SimpleChanges, - OnInit, OnDestroy, ComponentFactoryResolver, ChangeDetectorRef, @@ -21,7 +21,7 @@ import { GenericConstructor } from '../../core/shared/generic-constructor'; styleUrls: ['./themed.component.scss'], templateUrl: './themed.component.html', }) -export abstract class ThemedComponent implements OnInit, OnDestroy, OnChanges { +export abstract class ThemedComponent implements AfterViewInit, OnDestroy, OnChanges { @ViewChild('vcr', { read: ViewContainerRef }) vcr: ViewContainerRef; protected compRef: ComponentRef; @@ -49,7 +49,7 @@ export abstract class ThemedComponent implements OnInit, OnDestroy, OnChanges } } - ngOnInit(): void { + ngAfterViewInit(): void { this.destroyComponentInstance(); this.themeSub = this.themeService.getThemeName$().subscribe(() => { this.renderComponentInstance(); From ae6b183faec9cda0d2932143a52e14ef94bd945c Mon Sep 17 00:00:00 2001 From: Art Lowel Date: Wed, 14 Jun 2023 18:51:42 +0200 Subject: [PATCH 02/45] 103236: fix issue where setStaleByHrefSubtring wouldn't emit after all requests were stale --- src/app/core/data/request.service.ts | 36 +++++++++++++++++++++------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/src/app/core/data/request.service.ts b/src/app/core/data/request.service.ts index 2d5acb2cb3d..3b7ee80ffb0 100644 --- a/src/app/core/data/request.service.ts +++ b/src/app/core/data/request.service.ts @@ -2,8 +2,8 @@ import { Injectable } from '@angular/core'; import { HttpHeaders } from '@angular/common/http'; import { createSelector, MemoizedSelector, select, Store } from '@ngrx/store'; -import { Observable } from 'rxjs'; -import { filter, map, take, tap } from 'rxjs/operators'; +import { Observable, from as observableFrom } from 'rxjs'; +import { filter, find, map, mergeMap, switchMap, take, tap, toArray } from 'rxjs/operators'; import { cloneDeep } from 'lodash'; import { hasValue, isEmpty, isNotEmpty, hasNoValue } from '../../shared/empty.util'; import { ObjectCacheEntry } from '../cache/object-cache.reducer'; @@ -292,22 +292,42 @@ export class RequestService { * Set all requests that match (part of) the href to stale * * @param href A substring of the request(s) href - * @return Returns an observable emitting whether or not the cache is removed + * @return Returns an observable emitting when those requests are all stale */ setStaleByHrefSubstring(href: string): Observable { - this.store.pipe( + const requestUUIDs$ = this.store.pipe( select(uuidsFromHrefSubstringSelector(requestIndexSelector, href)), take(1) - ).subscribe((uuids: string[]) => { + ); + requestUUIDs$.subscribe((uuids: string[]) => { for (const uuid of uuids) { this.store.dispatch(new RequestStaleAction(uuid)); } }); this.requestsOnTheirWayToTheStore = this.requestsOnTheirWayToTheStore.filter((reqHref: string) => reqHref.indexOf(href) < 0); - return this.store.pipe( - select(uuidsFromHrefSubstringSelector(requestIndexSelector, href)), - map((uuids) => isEmpty(uuids)) + // emit true after all requests are stale + return requestUUIDs$.pipe( + switchMap((uuids: string[]) => { + if (isEmpty(uuids)) { + // if there were no matching requests, emit true immediately + return [true]; + } else { + // otherwise emit all request uuids in order + return observableFrom(uuids).pipe( + // retrieve the RequestEntry for each uuid + mergeMap((uuid: string) => this.getByUUID(uuid)), + // check whether it is undefined or stale + map((request: RequestEntry) => hasNoValue(request) || isStale(request.state)), + // if it is, complete + find((stale: boolean) => stale === true), + // after all observables above are completed, emit them as a single array + toArray(), + // when the array comes in, emit true + map(() => true) + ); + } + }) ); } From 02a20c8862ca4d93919ca07e900d70a722ebbb5d Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Fri, 30 Jun 2023 16:56:37 +0200 Subject: [PATCH 03/45] 103236: Added tests for setStaleByHrefSubstring --- src/app/core/data/request.service.spec.ts | 46 ++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/src/app/core/data/request.service.spec.ts b/src/app/core/data/request.service.spec.ts index fe35d840d7d..4493c61a69c 100644 --- a/src/app/core/data/request.service.spec.ts +++ b/src/app/core/data/request.service.spec.ts @@ -1,6 +1,6 @@ import { Store, StoreModule } from '@ngrx/store'; import { cold, getTestScheduler } from 'jasmine-marbles'; -import { EMPTY, of as observableOf } from 'rxjs'; +import { EMPTY, Observable, of as observableOf } from 'rxjs'; import { TestScheduler } from 'rxjs/testing'; import { getMockObjectCacheService } from '../../shared/mocks/object-cache.service.mock'; @@ -625,4 +625,48 @@ describe('RequestService', () => { expect(done$).toBeObservable(cold('-----(t|)', { t: true })); })); }); + + describe('setStaleByHrefSubstring', () => { + let dispatchSpy: jasmine.Spy; + let getByUUIDSpy: jasmine.Spy; + + beforeEach(() => { + dispatchSpy = spyOn(store, 'dispatch'); + getByUUIDSpy = spyOn(service, 'getByUUID').and.callThrough(); + }); + + describe('with an empty/no matching requests in the state', () => { + it('should return true', () => { + const done$: Observable = service.setStaleByHrefSubstring('https://rest.api/endpoint/selfLink'); + expect(done$).toBeObservable(cold('(a|)', { a: true })); + }); + }); + + describe('with a matching request in the state', () => { + beforeEach(() => { + const state = Object.assign({}, initialState, { + core: Object.assign({}, initialState.core, { + 'index': { + 'get-request/href-to-uuid': { + 'https://rest.api/endpoint/selfLink': '5f2a0d2a-effa-4d54-bd54-5663b960f9eb' + } + } + }) + }); + mockStore.setState(state); + }); + + it('should return an Observable that emits true as soon as the request is stale', () => { + dispatchSpy.and.callFake(() => { /* empty */ }); // don't actually set as stale + getByUUIDSpy.and.returnValue(cold('a-b--c--d-', { // but fake the state in the cache + a: { state: RequestEntryState.ResponsePending }, + b: { state: RequestEntryState.Success }, + c: { state: RequestEntryState.SuccessStale }, + d: { state: RequestEntryState.Error }, + })); + const done$: Observable = service.setStaleByHrefSubstring('https://rest.api/endpoint/selfLink'); + expect(done$).toBeObservable(cold('-----(a|)', { a: true })); + }); + }); + }); }); From b5a70e8f95d1046bed0e33d5b0bdc8109d645676 Mon Sep 17 00:00:00 2001 From: Nona Luypaert Date: Sat, 8 Jul 2023 00:20:30 +0200 Subject: [PATCH 04/45] Fix VocabularyTreeview not updating + i18n for nsi --- .../vocabulary-treeview/vocabulary-treeview.component.ts | 9 +++++++-- src/assets/i18n/en.json5 | 6 ++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/app/shared/form/vocabulary-treeview/vocabulary-treeview.component.ts b/src/app/shared/form/vocabulary-treeview/vocabulary-treeview.component.ts index 017416e8c25..13d4495e614 100644 --- a/src/app/shared/form/vocabulary-treeview/vocabulary-treeview.component.ts +++ b/src/app/shared/form/vocabulary-treeview/vocabulary-treeview.component.ts @@ -1,5 +1,5 @@ import { FlatTreeControl } from '@angular/cdk/tree'; -import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core'; +import { Component, EventEmitter, Input, OnDestroy, OnInit, Output, OnChanges, SimpleChanges } from '@angular/core'; import { map } from 'rxjs/operators'; import { Observable, Subscription } from 'rxjs'; @@ -28,7 +28,7 @@ import { getFirstSucceededRemoteDataPayload } from '../../../core/shared/operato templateUrl: './vocabulary-treeview.component.html', styleUrls: ['./vocabulary-treeview.component.scss'] }) -export class VocabularyTreeviewComponent implements OnDestroy, OnInit { +export class VocabularyTreeviewComponent implements OnDestroy, OnInit, OnChanges { /** * The {@link VocabularyOptions} object @@ -322,4 +322,9 @@ export class VocabularyTreeviewComponent implements OnDestroy, OnInit { private getEntryId(entry: VocabularyEntry): string { return entry.authority || entry.otherInformation.id || undefined; } + + ngOnChanges(changes: SimpleChanges): void { + this.reset(); + this.vocabularyTreeviewService.initialize(this.vocabularyOptions, new PageInfo(), this.selectedItems, null); + } } diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 6c91bae4c16..ee594a9cb29 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -782,6 +782,8 @@ "browse.comcol.by.srsc": "By Subject Category", + "browse.comcol.by.nsi": "By Norwegian Science Index", + "browse.comcol.by.title": "By Title", "browse.comcol.head": "Browse", @@ -804,6 +806,8 @@ "browse.metadata.srsc.breadcrumbs": "Browse by Subject Category", + "browse.metadata.nsi.breadcrumbs": "Browse by Norwegian Science Index", + "browse.metadata.title.breadcrumbs": "Browse by Title", "pagination.next.button": "Next", @@ -2826,6 +2830,8 @@ "menu.section.browse_global_by_srsc": "By Subject Category", + "menu.section.browse_global_by_nsi": "By Norwegian Science Index", + "menu.section.browse_global_by_title": "By Title", "menu.section.browse_global_communities_and_collections": "Communities & Collections", From cac1407f08290adbc1a827fb1769011d3ecba803 Mon Sep 17 00:00:00 2001 From: Kristof De Langhe Date: Wed, 12 Jul 2023 15:11:38 +0200 Subject: [PATCH 05/45] 104189: Allow CSV export on related entity search --- .../related-entities-search.component.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/app/item-page/simple/related-entities/related-entities-search/related-entities-search.component.html b/src/app/item-page/simple/related-entities/related-entities-search/related-entities-search.component.html index 2a08efeb2ca..36340bebfa0 100644 --- a/src/app/item-page/simple/related-entities/related-entities-search/related-entities-search.component.html +++ b/src/app/item-page/simple/related-entities/related-entities-search/related-entities-search.component.html @@ -2,5 +2,6 @@ [fixedFilterQuery]="fixedFilter" [configuration]="configuration" [searchEnabled]="searchEnabled" - [sideBarWidth]="sideBarWidth"> + [sideBarWidth]="sideBarWidth" + [showCsvExport]="true"> From 45ad5f73168ccdf3d4f7ab617d44a0e28c94545a Mon Sep 17 00:00:00 2001 From: Kristof De Langhe Date: Wed, 12 Jul 2023 16:32:56 +0200 Subject: [PATCH 06/45] 104189: CSV export add fixedFilter --- .../search-export-csv.component.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/app/shared/search/search-export-csv/search-export-csv.component.ts b/src/app/shared/search/search-export-csv/search-export-csv.component.ts index 6ad105342f6..1997a663a13 100644 --- a/src/app/shared/search/search-export-csv/search-export-csv.component.ts +++ b/src/app/shared/search/search-export-csv/search-export-csv.component.ts @@ -94,6 +94,19 @@ export class SearchExportCsvComponent implements OnInit { } }); } + if (isNotEmpty(this.searchConfig.fixedFilter)) { + const fixedFilter = this.searchConfig.fixedFilter.substring(2); + const keyAndValue = fixedFilter.split('='); + if (keyAndValue.length > 1) { + const key = keyAndValue[0]; + const valueAndOperator = keyAndValue[1].split(','); + if (valueAndOperator.length > 1) { + const value = valueAndOperator[0]; + const operator = valueAndOperator[1]; + parameters.push({name: '-f', value: `${key},${operator}=${value}`}); + } + } + } } this.scriptDataService.invoke('metadata-export-search', parameters, []).pipe( From 648925f3e1c0a51fc3eb61b7257e7a44ea57fee6 Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Wed, 19 Jul 2023 14:01:41 +0200 Subject: [PATCH 07/45] 104312: DsDynamicLookupRelationExternalSourceTabComponent should have the form value already filled in the search input --- .../dynamic-lookup-relation-modal.component.html | 1 + ...ookup-relation-external-source-tab.component.ts | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/dynamic-lookup-relation-modal.component.html b/src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/dynamic-lookup-relation-modal.component.html index f95cd98c656..4c635b931f0 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/dynamic-lookup-relation-modal.component.html +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/dynamic-lookup-relation-modal.component.html @@ -42,6 +42,7 @@ diff --git a/src/app/shared/metadata-field-wrapper/metadata-field-wrapper.component.html b/src/app/shared/metadata-field-wrapper/metadata-field-wrapper.component.html index d69f87883bb..7748e385ca4 100644 --- a/src/app/shared/metadata-field-wrapper/metadata-field-wrapper.component.html +++ b/src/app/shared/metadata-field-wrapper/metadata-field-wrapper.component.html @@ -1,5 +1,5 @@
-
{{ label }}
+

{{ label }}

diff --git a/src/app/shared/metadata-field-wrapper/metadata-field-wrapper.component.scss b/src/app/shared/metadata-field-wrapper/metadata-field-wrapper.component.scss index 75dfd09d0d9..bf17d63d6c6 100644 --- a/src/app/shared/metadata-field-wrapper/metadata-field-wrapper.component.scss +++ b/src/app/shared/metadata-field-wrapper/metadata-field-wrapper.component.scss @@ -2,4 +2,7 @@ .simple-view-element { margin-bottom: 15px; } + .simple-view-element-header { + font-size: 1.25rem; + } } From 91d8b7e4f7187b68f70c1cf2906f4e6e8d8af2b9 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Tue, 29 Aug 2023 14:58:49 -0500 Subject: [PATCH 41/45] Update ng2-nouislider and nouislider to latest versions --- package.json | 4 ++-- src/styles/_vendor.scss | 2 +- yarn.lock | 18 ++++++++++-------- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index 707e9f0edf2..31d1b7cf28e 100644 --- a/package.json +++ b/package.json @@ -116,12 +116,12 @@ "morgan": "^1.10.0", "ng-mocks": "^14.10.0", "ng2-file-upload": "1.4.0", - "ng2-nouislider": "^1.8.3", + "ng2-nouislider": "^2.0.0", "ngx-infinite-scroll": "^15.0.0", "ngx-pagination": "6.0.3", "ngx-sortablejs": "^11.1.0", "ngx-ui-switch": "^14.0.3", - "nouislider": "^14.6.3", + "nouislider": "^15.7.1", "pem": "1.14.7", "prop-types": "^15.8.1", "react-copy-to-clipboard": "^5.1.0", diff --git a/src/styles/_vendor.scss b/src/styles/_vendor.scss index 9d9842b9b30..b2b94c28269 100644 --- a/src/styles/_vendor.scss +++ b/src/styles/_vendor.scss @@ -1,5 +1,5 @@ // node_modules imports meant for all the themes @import '~node_modules/bootstrap/scss/bootstrap.scss'; -@import '~node_modules/nouislider/distribute/nouislider.min'; +@import '~node_modules/nouislider/dist/nouislider.min'; @import '~node_modules/ngx-ui-switch/ui-switch.component.scss'; diff --git a/yarn.lock b/yarn.lock index 58ddfaca4b7..44625c4bd01 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8197,10 +8197,12 @@ ng2-file-upload@1.4.0: dependencies: tslib "^1.9.0" -ng2-nouislider@^1.8.3: - version "1.8.3" - resolved "https://registry.npmjs.org/ng2-nouislider/-/ng2-nouislider-1.8.3.tgz" - integrity sha512-Vl8tHCcJ/ioJLAs2t6FBC35sZq1P/O5ZdqdFwYxOCOMVbILGWNg+2gWZIjFstvv9pqb/mVvVUYe6qGG/mA/RBQ== +ng2-nouislider@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ng2-nouislider/-/ng2-nouislider-2.0.0.tgz#a62fd6cf3f1561be19a2691c2f68d21a46dc6006" + integrity sha512-NGbF/0w0+bZqclpSPFOlWIeVJaVwRRYFJzD1x8PClbw9GIeo7fCHoBzZ81y7K7FTJg6to+cgjSTFETPZG/Dizg== + dependencies: + tslib "^2.3.0" ngx-infinite-scroll@^15.0.0: version "15.0.0" @@ -8343,10 +8345,10 @@ normalize-url@^4.5.0: resolved "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz" integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA== -nouislider@^14.6.3: - version "14.7.0" - resolved "https://registry.npmjs.org/nouislider/-/nouislider-14.7.0.tgz" - integrity sha512-4RtQ1+LHJKesDCNJrXkQcwXAWCrC2aggdLYMstS/G5fEWL+fXZbUA9pwVNHFghMGuFGRATlDLNInRaPeRKzpFQ== +nouislider@^15.7.1: + version "15.7.1" + resolved "https://registry.yarnpkg.com/nouislider/-/nouislider-15.7.1.tgz#77d55e47d9b4cd771728515713df43b489db9705" + integrity sha512-5N7C1ru/i8y3dg9+Z6ilj6+m1EfabvOoaRa7ztpxBSKKRZso4vA52DGSbBJjw5XLtFr/LZ9SgGAXqyVtlVHO5w== npm-bundled@^3.0.0: version "3.0.0" From 2a881791ba76091d2f85d0b068f926043ef33bc9 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Tue, 29 Aug 2023 15:01:21 -0500 Subject: [PATCH 42/45] Fix accessibility of date sliders by adding aria-labels --- cypress/e2e/my-dspace.cy.ts | 6 +--- cypress/e2e/search-page.cy.ts | 6 +--- .../search-range-filter.component.html | 10 +++---- .../search-range-filter.component.ts | 29 +++++++++++++++++++ 4 files changed, 36 insertions(+), 15 deletions(-) diff --git a/cypress/e2e/my-dspace.cy.ts b/cypress/e2e/my-dspace.cy.ts index 79786c298a3..af4aab41f36 100644 --- a/cypress/e2e/my-dspace.cy.ts +++ b/cypress/e2e/my-dspace.cy.ts @@ -22,15 +22,11 @@ describe('My DSpace page', () => { testA11y( { include: ['ds-my-dspace-page'], - exclude: [ - ['nouislider'] // Date filter slider is missing ARIA labels. Will be fixed by #1175 - ], }, { rules: { - // Search filters fail these two "moderate" impact rules + // Search filters fail this "moderate" impact rules 'heading-order': { enabled: false }, - 'landmark-unique': { enabled: false } } } as Options ); diff --git a/cypress/e2e/search-page.cy.ts b/cypress/e2e/search-page.cy.ts index 24519cc236a..0d4f70ef037 100644 --- a/cypress/e2e/search-page.cy.ts +++ b/cypress/e2e/search-page.cy.ts @@ -30,15 +30,11 @@ describe('Search Page', () => { testA11y( { include: ['ds-search-page'], - exclude: [ - ['nouislider'] // Date filter slider is missing ARIA labels. Will be fixed by #1175 - ], }, { rules: { - // Search filters fail these two "moderate" impact rules + // Search filters fail this "moderate" impact rule 'heading-order': { enabled: false }, - 'landmark-unique': { enabled: false } } } as Options ); diff --git a/src/app/shared/search/search-filters/search-filter/search-range-filter/search-range-filter.component.html b/src/app/shared/search/search-filters/search-filter/search-range-filter/search-range-filter.component.html index 7834c4c5571..251e5ac420b 100644 --- a/src/app/shared/search/search-filters/search-filter/search-range-filter/search-range-filter.component.html +++ b/src/app/shared/search/search-filters/search-filter/search-range-filter/search-range-filter.component.html @@ -9,8 +9,8 @@
@@ -21,8 +21,8 @@ @@ -33,7 +33,7 @@ - diff --git a/src/app/shared/search/search-filters/search-filter/search-range-filter/search-range-filter.component.ts b/src/app/shared/search/search-filters/search-filter/search-range-filter/search-range-filter.component.ts index 938f67412e4..ed20e63c52f 100644 --- a/src/app/shared/search/search-filters/search-filter/search-range-filter/search-range-filter.component.ts +++ b/src/app/shared/search/search-filters/search-filter/search-range-filter/search-range-filter.component.ts @@ -2,6 +2,7 @@ import { BehaviorSubject, combineLatest as observableCombineLatest, Subscription import { map, startWith } from 'rxjs/operators'; import { isPlatformBrowser } from '@angular/common'; import { Component, Inject, OnDestroy, OnInit, PLATFORM_ID } from '@angular/core'; +import { TranslateService } from '@ngx-translate/core'; import { RemoteDataBuildService } from '../../../../../core/cache/builders/remote-data-build.service'; import { FilterType } from '../../../models/filter-type.model'; import { renderFacetFor } from '../search-filter-type-decorator'; @@ -53,11 +54,27 @@ export class SearchRangeFilterComponent extends SearchFacetFilterComponent imple */ min = 1950; + /** + * i18n Label to use for minimum field + */ + minLabel: string; + /** * Fallback maximum for the range */ max = new Date().getUTCFullYear(); + /** + * i18n Label to use for maximum field + */ + maxLabel: string; + + /** + * Base configuration for nouislider + * https://refreshless.com/nouislider/slider-options/ + */ + config = {}; + /** * The current range of the filter */ @@ -78,6 +95,7 @@ export class SearchRangeFilterComponent extends SearchFacetFilterComponent imple protected filterService: SearchFilterService, protected router: Router, protected rdbs: RemoteDataBuildService, + private translateService: TranslateService, @Inject(SEARCH_CONFIG_SERVICE) public searchConfigService: SearchConfigurationService, @Inject(IN_PLACE_SEARCH) public inPlaceSearch: boolean, @Inject(FILTER_CONFIG) public filterConfig: SearchFilterConfig, @@ -96,6 +114,8 @@ export class SearchRangeFilterComponent extends SearchFacetFilterComponent imple super.ngOnInit(); this.min = yearFromString(this.filterConfig.minValue) || this.min; this.max = yearFromString(this.filterConfig.maxValue) || this.max; + this.minLabel = this.translateService.instant('search.filters.filter.' + this.filterConfig.name + '.min.placeholder'); + this.maxLabel = this.translateService.instant('search.filters.filter.' + this.filterConfig.name + '.max.placeholder'); const iniMin = this.route.getQueryParameterValue(this.filterConfig.paramName + RANGE_FILTER_MIN_SUFFIX).pipe(startWith(undefined)); const iniMax = this.route.getQueryParameterValue(this.filterConfig.paramName + RANGE_FILTER_MAX_SUFFIX).pipe(startWith(undefined)); this.sub = observableCombineLatest(iniMin, iniMax).pipe( @@ -105,6 +125,15 @@ export class SearchRangeFilterComponent extends SearchFacetFilterComponent imple return [minimum, maximum]; }) ).subscribe((minmax) => this.range = minmax); + + // Default/base config for nouislider + this.config = { + // Ensure draggable handles have labels + handleAttributes: [ + { 'aria-label': this.minLabel }, + { 'aria-label': this.maxLabel }, + ], + }; } /** From 70a7bbe3cbdd24abaf7f6f791ef60e88a3ae8922 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Tue, 29 Aug 2023 15:01:51 -0500 Subject: [PATCH 43/45] Minor fixes to cypress tests --- cypress/e2e/community-list.cy.ts | 1 - cypress/e2e/pagenotfound.cy.ts | 5 +++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/cypress/e2e/community-list.cy.ts b/cypress/e2e/community-list.cy.ts index d91260eca1f..c371f6ceae7 100644 --- a/cypress/e2e/community-list.cy.ts +++ b/cypress/e2e/community-list.cy.ts @@ -1,4 +1,3 @@ -import { Options } from 'cypress-axe'; import { testA11y } from 'cypress/support/utils'; describe('Community List Page', () => { diff --git a/cypress/e2e/pagenotfound.cy.ts b/cypress/e2e/pagenotfound.cy.ts index 43e3c3af242..d02aa8541c3 100644 --- a/cypress/e2e/pagenotfound.cy.ts +++ b/cypress/e2e/pagenotfound.cy.ts @@ -1,8 +1,13 @@ +import { testA11y } from 'cypress/support/utils'; + describe('PageNotFound', () => { it('should contain element ds-pagenotfound when navigating to page that doesnt exist', () => { // request an invalid page (UUIDs at root path aren't valid) cy.visit('/e9019a69-d4f1-4773-b6a3-bd362caa46f2', { failOnStatusCode: false }); cy.get('ds-pagenotfound').should('be.visible'); + + // Analyze for accessibility issues + testA11y('ds-pagenotfound'); }); it('should not contain element ds-pagenotfound when navigating to existing page', () => { From 276d80895e38225fcbde38cab01d79cd31a34e9b Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Tue, 29 Aug 2023 15:10:12 -0500 Subject: [PATCH 44/45] Fix heading order accessibility issue in search filters/facets --- cypress/e2e/my-dspace.cy.ts | 12 +----------- cypress/e2e/search-page.cy.ts | 12 +----------- .../search-filter/search-filter.component.html | 4 ++-- .../shared/sidebar/sidebar-dropdown.component.html | 2 +- src/themes/dspace/styles/_global-styles.scss | 2 +- 5 files changed, 6 insertions(+), 26 deletions(-) diff --git a/cypress/e2e/my-dspace.cy.ts b/cypress/e2e/my-dspace.cy.ts index af4aab41f36..13f4a1b5471 100644 --- a/cypress/e2e/my-dspace.cy.ts +++ b/cypress/e2e/my-dspace.cy.ts @@ -19,17 +19,7 @@ describe('My DSpace page', () => { cy.get('.filter-toggle').click({ multiple: true }); // Analyze for accessibility issues - testA11y( - { - include: ['ds-my-dspace-page'], - }, - { - rules: { - // Search filters fail this "moderate" impact rules - 'heading-order': { enabled: false }, - } - } as Options - ); + testA11y('ds-my-dspace-page'); }); it('should have a working detailed view that passes accessibility tests', () => { diff --git a/cypress/e2e/search-page.cy.ts b/cypress/e2e/search-page.cy.ts index 0d4f70ef037..755f8eaac6c 100644 --- a/cypress/e2e/search-page.cy.ts +++ b/cypress/e2e/search-page.cy.ts @@ -27,17 +27,7 @@ describe('Search Page', () => { cy.get('[data-test="filter-toggle"]').click({ multiple: true }); // Analyze for accessibility issues - testA11y( - { - include: ['ds-search-page'], - }, - { - rules: { - // Search filters fail this "moderate" impact rule - 'heading-order': { enabled: false }, - } - } as Options - ); + testA11y('ds-search-page'); }); it('should have a working grid view that passes accessibility tests', () => { diff --git a/src/app/shared/search/search-filters/search-filter/search-filter.component.html b/src/app/shared/search/search-filters/search-filter/search-filter.component.html index a6fb0021b7f..421d1ede2c0 100644 --- a/src/app/shared/search/search-filters/search-filter/search-filter.component.html +++ b/src/app/shared/search/search-filters/search-filter/search-filter.component.html @@ -6,9 +6,9 @@ [attr.aria-label]="(((collapsed$ | async) ? 'search.filters.filter.expand' : 'search.filters.filter.collapse') | translate) + ' ' + (('search.filters.filter.' + filter.name + '.head') | translate | lowercase)" [attr.data-test]="'filter-toggle' | dsBrowserOnly" > -
+

{{'search.filters.filter.' + filter.name + '.head'| translate}} -

+ diff --git a/src/app/shared/sidebar/sidebar-dropdown.component.html b/src/app/shared/sidebar/sidebar-dropdown.component.html index 0c2a1c05d25..2eadac09f75 100644 --- a/src/app/shared/sidebar/sidebar-dropdown.component.html +++ b/src/app/shared/sidebar/sidebar-dropdown.component.html @@ -1,5 +1,5 @@
-
+

diff --git a/src/themes/dspace/styles/_global-styles.scss b/src/themes/dspace/styles/_global-styles.scss index e41dae0e3f2..5bd4c19bc04 100644 --- a/src/themes/dspace/styles/_global-styles.scss +++ b/src/themes/dspace/styles/_global-styles.scss @@ -17,7 +17,7 @@ background-color: var(--bs-primary); } - h5 { + h4 { font-size: 1.1rem } } From a6c1120700398fb0cf99ffd6e1a7ff52e5858a40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Carvalho?= Date: Wed, 30 Aug 2023 15:52:34 +0100 Subject: [PATCH 45/45] Minor pt-PT translation fixes --- src/assets/i18n/pt-PT.json5 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/assets/i18n/pt-PT.json5 b/src/assets/i18n/pt-PT.json5 index 5aa4817e881..faa027705e0 100644 --- a/src/assets/i18n/pt-PT.json5 +++ b/src/assets/i18n/pt-PT.json5 @@ -2259,7 +2259,7 @@ "confirmation-modal.delete-eperson.header": "Apagar Utilizador \"{{ dsoName }}\"", // "confirmation-modal.delete-eperson.info": "Are you sure you want to delete EPerson \"{{ dsoName }}\"", - "confirmation-modal.delete-eperson.info": "Pretende apagar o utilizar \"{{ dsoName }}\"", + "confirmation-modal.delete-eperson.info": "Pretende apagar o utilizador \"{{ dsoName }}\"", // "confirmation-modal.delete-eperson.cancel": "Cancel", "confirmation-modal.delete-eperson.cancel": "Cancelar", @@ -2666,7 +2666,7 @@ "health-page.property.status": "Código Estado", // "health-page.section.db.title": "Database", - "health-page.section.db.title": "Base Dados", + "health-page.section.db.title": "Base de Dados", // "health-page.section.geoIp.title": "GeoIp", "health-page.section.geoIp.title": "GeoIp",