From a1a705321a32d66b9b9a29b6c2c617370f9cefd1 Mon Sep 17 00:00:00 2001 From: till_schuetze Date: Tue, 27 Aug 2024 16:15:21 +0200 Subject: [PATCH 01/43] keep all temporary url params if there was an error with the search --- src/app/shared/errors/search.errors.ts | 3 ++- src/app/state/app/actions/url.actions.ts | 3 ++- src/app/state/app/effects/url.effects.ts | 24 +++++++++++++++++++---- src/app/state/app/reducers/url.reducer.ts | 7 ++++++- src/app/state/app/states/url.state.ts | 1 + 5 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src/app/shared/errors/search.errors.ts b/src/app/shared/errors/search.errors.ts index ced33a824..d631771d5 100644 --- a/src/app/shared/errors/search.errors.ts +++ b/src/app/shared/errors/search.errors.ts @@ -6,7 +6,8 @@ export class SearchResultsCouldNotBeLoaded extends RecoverableError { } export class InvalidSearchParameters extends RecoverableError { - public override message = 'Um über die URL zu suchen, müssen die Parameter "searchTerm" und "searchIndex" definiert sein.'; + public override message = + 'Um über die URL zu suchen, müssen die Parameter "searchTerm" und "searchIndex" definiert sein. Bitte passen Sie die URL entsprechend an.'; public override name = 'InvalidSearchParameters'; } diff --git a/src/app/state/app/actions/url.actions.ts b/src/app/state/app/actions/url.actions.ts index 3f280565e..87fa3d00a 100644 --- a/src/app/state/app/actions/url.actions.ts +++ b/src/app/state/app/actions/url.actions.ts @@ -1,4 +1,4 @@ -import {createActionGroup, props} from '@ngrx/store'; +import {createActionGroup, emptyProps, props} from '@ngrx/store'; import {MainPage} from '../../../shared/enums/main-page.enum'; import {Params} from '@angular/router'; @@ -8,5 +8,6 @@ export const UrlActions = createActionGroup({ 'Set Page': props<{mainPage: MainPage | undefined; isHeadlessPage: boolean; isSimplifiedPage: boolean}>(), 'Set App Params': props<{params: Params}>(), 'Set Map Page Params': props<{params: Params}>(), + 'Keep Temporary Url Parameters': emptyProps(), }, }); diff --git a/src/app/state/app/effects/url.effects.ts b/src/app/state/app/effects/url.effects.ts index 470e81f6d..41fcf4200 100644 --- a/src/app/state/app/effects/url.effects.ts +++ b/src/app/state/app/effects/url.effects.ts @@ -11,7 +11,7 @@ import {distinctUntilChanged, filter, switchMap} from 'rxjs'; import {MapConfigActions} from '../../map/actions/map-config.actions'; import {MapConstants} from '../../../shared/constants/map.constants'; import {selectMapConfigParams} from '../../map/selectors/map-config-params.selector'; -import {selectMainPage} from '../reducers/url.reducer'; +import {selectKeepTemporaryUrlParams, selectMainPage} from '../reducers/url.reducer'; import {MainPage} from '../../../shared/enums/main-page.enum'; import {Store} from '@ngrx/store'; import {BasemapConfigService} from '../../../map/services/basemap-config.service'; @@ -112,11 +112,18 @@ export class UrlEffects { () => { return this.actions$.pipe( ofType(UrlActions.setMapPageParams), - concatLatestFrom(() => [this.store.select(selectQueryParams), this.store.select(selectMainPage)]), + concatLatestFrom(() => [ + this.store.select(selectQueryParams), + this.store.select(selectMainPage), + this.store.select(selectKeepTemporaryUrlParams), + ]), filter(([, , mainPage]) => mainPage === MainPage.Maps), - map(([{params}, currentParams, _]) => { + map(([{params}, currentParams, _, keepTemporaryUrlParams]) => { let adjustedAndCurrentParams: {params: Params; currentParams: Params} = {params, currentParams}; - if (Object.keys(currentParams).some((paramKey) => MapConstants.TEMPORARY_URL_PARAMS.includes(paramKey))) { + if ( + Object.keys(currentParams).some((paramKey) => MapConstants.TEMPORARY_URL_PARAMS.includes(paramKey)) && + !keepTemporaryUrlParams + ) { // remove temporary parameters const paramsToRemove = MapConstants.TEMPORARY_URL_PARAMS.reduce((prev, curr) => ({...prev, [curr]: null}), {}); const adjustedParams: Params = { @@ -141,6 +148,15 @@ export class UrlEffects { {dispatch: false}, ); + public keepTemporaryUrlParameters$ = createEffect(() => { + return this.actions$.pipe( + ofType(SearchActions.setSearchApiError, SearchActions.handleEmptyResultsFromUrlSearch, SearchActions.handleInvalidParameters), + map(() => { + return UrlActions.keepTemporaryUrlParameters(); + }), + ); + }); + constructor( private readonly actions$: Actions, private readonly router: Router, diff --git a/src/app/state/app/reducers/url.reducer.ts b/src/app/state/app/reducers/url.reducer.ts index 8c429aec5..b3ecdb07c 100644 --- a/src/app/state/app/reducers/url.reducer.ts +++ b/src/app/state/app/reducers/url.reducer.ts @@ -9,6 +9,7 @@ export const initialState: UrlState = { previousPage: undefined, isHeadlessPage: false, isSimplifiedPage: false, + keepTemporaryUrlParams: false, }; export const urlFeature = createFeature({ @@ -18,7 +19,11 @@ export const urlFeature = createFeature({ on(UrlActions.setPage, (state, {mainPage, isHeadlessPage, isSimplifiedPage}): UrlState => { return {...state, previousPage: state.mainPage, mainPage, isHeadlessPage, isSimplifiedPage}; }), + on(UrlActions.keepTemporaryUrlParameters, (state): UrlState => { + return {...state, keepTemporaryUrlParams: true}; + }), ), }); -export const {name, reducer, selectUrlState, selectMainPage, selectIsHeadlessPage, selectIsSimplifiedPage} = urlFeature; +export const {name, reducer, selectUrlState, selectMainPage, selectIsHeadlessPage, selectIsSimplifiedPage, selectKeepTemporaryUrlParams} = + urlFeature; diff --git a/src/app/state/app/states/url.state.ts b/src/app/state/app/states/url.state.ts index 958966355..28ea2ae1e 100644 --- a/src/app/state/app/states/url.state.ts +++ b/src/app/state/app/states/url.state.ts @@ -11,4 +11,5 @@ export interface UrlState { * Flag which can be used to toggle simplified layouts, e.g. no ZH Lion in the header. */ isSimplifiedPage: boolean; + keepTemporaryUrlParams: boolean; } From a0107953ce3ad6c7b2d82a3e5ab434676962d0ed Mon Sep 17 00:00:00 2001 From: Sebastian Wendland Date: Fri, 30 Aug 2024 12:39:38 +0200 Subject: [PATCH 02/43] GB3-1623: Updated the `grav-cms-generated.interfaces` which introduced `altText` for images. Modified `discover-maps.component` and `frequently-used-items.component` accordingly so that they will show this alt text properly. --- .../discover-maps-item.interface.ts | 1 + .../frequently-used-item.interface.ts | 1 + .../models/grav-cms-generated.interfaces.ts | 25 +++++++++++-------- .../apis/grav-cms/grav-cms.service.ts | 2 ++ .../discover-maps.component.html | 7 +++--- .../discover-maps.component.scss | 6 ++--- .../frequently-used-items.component.html | 2 +- .../frequently-used-items.component.scss | 1 + 8 files changed, 27 insertions(+), 18 deletions(-) diff --git a/src/app/shared/interfaces/discover-maps-item.interface.ts b/src/app/shared/interfaces/discover-maps-item.interface.ts index 6f003711c..dc9abbcae 100644 --- a/src/app/shared/interfaces/discover-maps-item.interface.ts +++ b/src/app/shared/interfaces/discover-maps-item.interface.ts @@ -14,4 +14,5 @@ interface DiscoverMapsItemImage { type: string; size: number; path: string; + altText?: string; } diff --git a/src/app/shared/interfaces/frequently-used-item.interface.ts b/src/app/shared/interfaces/frequently-used-item.interface.ts index 3a9f96bde..b7e4e99ad 100644 --- a/src/app/shared/interfaces/frequently-used-item.interface.ts +++ b/src/app/shared/interfaces/frequently-used-item.interface.ts @@ -13,4 +13,5 @@ interface FrequentlyUsedItemImage { type: string; size: number; path: string; + altText?: string; } diff --git a/src/app/shared/models/grav-cms-generated.interfaces.ts b/src/app/shared/models/grav-cms-generated.interfaces.ts index 584344917..1d11b83eb 100644 --- a/src/app/shared/models/grav-cms-generated.interfaces.ts +++ b/src/app/shared/models/grav-cms-generated.interfaces.ts @@ -1,5 +1,8 @@ /** * Generated using https://transform.tools/json-to-typescript and the output from the endpoint. + * There are some slight manual adjustments: + * - The root object is renamed to include the endpoint name to avoid conflicts with other interface names + * - The optional `image` in `FrequentlyUsed` is changed from `image?: Image` to `image: Image | null` to avoid errors */ /* eslint-disable */ /* tslint:disable */ @@ -9,20 +12,21 @@ export interface DiscoverMapsRoot { } export interface Map { - title: string; description: string; - id: string; + flex_id: string; from_date: string; - to_date: string; + id: string; image: Image; - flex_id: string; + image_alt?: string; + title: string; + to_date: string; } export interface Image { name: string; - type: string; - size: number; path: string; + size: number; + type: string; } export interface PageInfosRoot { @@ -51,10 +55,11 @@ export interface FrequentlyUsedRoot { } export interface FrequentlyUsed { - title: string; - description: string; - url?: string; - image: Image | null; created: string; + description: string; flex_id: string; + image: Image | null; + title: string; + image_alt?: string; + url?: string; } diff --git a/src/app/shared/services/apis/grav-cms/grav-cms.service.ts b/src/app/shared/services/apis/grav-cms/grav-cms.service.ts index 31f52ed8f..fe22a6822 100644 --- a/src/app/shared/services/apis/grav-cms/grav-cms.service.ts +++ b/src/app/shared/services/apis/grav-cms/grav-cms.service.ts @@ -52,6 +52,7 @@ export class GravCmsService extends BaseApiService { type: discoverMapData.image.type, size: discoverMapData.image.size, path: discoverMapData.image.path, + altText: discoverMapData.image_alt, }, }; }); @@ -86,6 +87,7 @@ export class GravCmsService extends BaseApiService { type: frequentlyUsedData.image.type, size: frequentlyUsedData.image.size, path: frequentlyUsedData.image.path, + altText: frequentlyUsedData.image_alt, } : undefined, created: dayjs.unix(+frequentlyUsedData.created).toDate(), diff --git a/src/app/start-page/components/discover-maps/discover-maps.component.html b/src/app/start-page/components/discover-maps/discover-maps.component.html index ddb66247c..295dbe40b 100644 --- a/src/app/start-page/components/discover-maps/discover-maps.component.html +++ b/src/app/start-page/components/discover-maps/discover-maps.component.html @@ -8,10 +8,11 @@
  • - + />

    {{ discoverMapsEntry.title }}

    {{ discoverMapsEntry.description }}

    diff --git a/src/app/start-page/components/discover-maps/discover-maps.component.scss b/src/app/start-page/components/discover-maps/discover-maps.component.scss index ca0028843..fedd82368 100644 --- a/src/app/start-page/components/discover-maps/discover-maps.component.scss +++ b/src/app/start-page/components/discover-maps/discover-maps.component.scss @@ -37,10 +37,8 @@ $number-of-entries: 2; display: block; width: 100%; height: 327px; - background-size: cover; - background-repeat: no-repeat; - background-position: center center; - // The url is added dynamically via ngStyle + object-fit: cover; + object-position: center; } .discover-maps__list__item__wrapper__content__container { diff --git a/src/app/start-page/components/frequently-used-items/frequently-used-items.component.html b/src/app/start-page/components/frequently-used-items/frequently-used-items.component.html index 7e4b65b19..57e6851b5 100644 --- a/src/app/start-page/components/frequently-used-items/frequently-used-items.component.html +++ b/src/app/start-page/components/frequently-used-items/frequently-used-items.component.html @@ -16,7 +16,7 @@
    diff --git a/src/app/start-page/components/frequently-used-items/frequently-used-items.component.scss b/src/app/start-page/components/frequently-used-items/frequently-used-items.component.scss index 8130c4dab..e95afde21 100644 --- a/src/app/start-page/components/frequently-used-items/frequently-used-items.component.scss +++ b/src/app/start-page/components/frequently-used-items/frequently-used-items.component.scss @@ -32,6 +32,7 @@ width: 100%; height: 100%; object-fit: cover; + object-position: center; } } From d6855ebd8d35cdb95508595b575d781f83f77af6 Mon Sep 17 00:00:00 2001 From: Sebastian Wendland Date: Fri, 30 Aug 2024 13:03:39 +0200 Subject: [PATCH 03/43] GB3-1623: Fixed and extended the unit tests. --- .../discover-maps-item.interface.ts | 2 +- .../frequently-used-item.interface.ts | 2 +- .../apis/grav-cms/grav-cms.service.spec.ts | 25 +++++++++++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/app/shared/interfaces/discover-maps-item.interface.ts b/src/app/shared/interfaces/discover-maps-item.interface.ts index dc9abbcae..82f04c634 100644 --- a/src/app/shared/interfaces/discover-maps-item.interface.ts +++ b/src/app/shared/interfaces/discover-maps-item.interface.ts @@ -14,5 +14,5 @@ interface DiscoverMapsItemImage { type: string; size: number; path: string; - altText?: string; + altText: string | undefined; } diff --git a/src/app/shared/interfaces/frequently-used-item.interface.ts b/src/app/shared/interfaces/frequently-used-item.interface.ts index b7e4e99ad..5fe0147af 100644 --- a/src/app/shared/interfaces/frequently-used-item.interface.ts +++ b/src/app/shared/interfaces/frequently-used-item.interface.ts @@ -13,5 +13,5 @@ interface FrequentlyUsedItemImage { type: string; size: number; path: string; - altText?: string; + altText: string | undefined; } diff --git a/src/app/shared/services/apis/grav-cms/grav-cms.service.spec.ts b/src/app/shared/services/apis/grav-cms/grav-cms.service.spec.ts index 789aa7593..52da2e359 100644 --- a/src/app/shared/services/apis/grav-cms/grav-cms.service.spec.ts +++ b/src/app/shared/services/apis/grav-cms/grav-cms.service.spec.ts @@ -60,6 +60,7 @@ describe('GravCmsService', () => { size: 542427, path: 'assets/uploads/discovermaps/c8xtlxyksm9w5tj.png', }, + image_alt: 'Bildbeschriftung für Landschaftstypologie', flex_id: 'da0a66b63d2b036dd6d0ad6b470d1a2c', }, ], @@ -82,6 +83,7 @@ describe('GravCmsService', () => { type: 'image/png', size: 662482, path: 'assets/uploads/discovermaps/ruvsmjzmt6ienof.png', + altText: undefined, }, }, { @@ -98,6 +100,7 @@ describe('GravCmsService', () => { type: 'image/png', size: 542427, path: 'assets/uploads/discovermaps/c8xtlxyksm9w5tj.png', + altText: 'Bildbeschriftung für Landschaftstypologie', }, }, ]; @@ -171,6 +174,7 @@ describe('GravCmsService', () => { size: 2361401, path: 'assets/uploads/frequentlyused/mdph1k0nyqstliu.png', }, + image_alt: 'Bildbeschriftung für Orthofotos', flex_id: 'b07395a55bd971a90884aff2e8bb7abf', }, { @@ -187,6 +191,16 @@ describe('GravCmsService', () => { }, flex_id: 'dc10938d401e622da75cbcfdcebf64d5', }, + { + title: 'Azeroth', + description: + 'Eine gefährliche, schöne, magische und inspirierende Welt. Eine Welt voller Entdeckungen, Innovationen und Wunder. Eine Welt, für die es sich zu kämpfen lohnt. Eine Welt, die es wert ist, beschützt zu werden.', + url: '/maps?initialMapIds=F0r7H3H0rD3', + created: '1424201337', + image: null, + image_alt: 'Bildbeschriftung für Azeroth', + flex_id: '00000000-0000-4000-y000-000000000000', + }, ], }; const httpClient = TestBed.inject(HttpClient); @@ -204,6 +218,7 @@ describe('GravCmsService', () => { type: 'image/png', size: 2361401, path: 'assets/uploads/frequentlyused/mdph1k0nyqstliu.png', + altText: 'Bildbeschriftung für Orthofotos', }, created: new Date(Date.UTC(2023, 8, 18, 9, 24, 31)), }, @@ -219,9 +234,19 @@ describe('GravCmsService', () => { type: 'image/png', size: 506099, path: 'assets/uploads/frequentlyused/czef0j9wrdgbyni.png', + altText: undefined, }, created: new Date(Date.UTC(2023, 8, 18, 9, 23, 2)), }, + { + id: '00000000-0000-4000-y000-000000000000', + title: 'Azeroth', + description: + 'Eine gefährliche, schöne, magische und inspirierende Welt. Eine Welt voller Entdeckungen, Innovationen und Wunder. Eine Welt, für die es sich zu kämpfen lohnt. Eine Welt, die es wert ist, beschützt zu werden.', + url: '/maps?initialMapIds=F0r7H3H0rD3', + image: undefined, + created: new Date(Date.UTC(2015, 1, 17, 19, 28, 57)), + }, ]; service.loadFrequentlyUsedData().subscribe((actual) => { From 6b171f7a3e3e3b33b997817111c39ee848c427b8 Mon Sep 17 00:00:00 2001 From: till_schuetze Date: Mon, 2 Sep 2024 17:09:21 +0200 Subject: [PATCH 04/43] Bugfix: Wrong update of dpi settings upon format change --- .../print-dialog/print-dialog.component.ts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/app/map/components/map-tools/print-dialog/print-dialog.component.ts b/src/app/map/components/map-tools/print-dialog/print-dialog.component.ts index 30559a2be..9dfdc7b1d 100644 --- a/src/app/map/components/map-tools/print-dialog/print-dialog.component.ts +++ b/src/app/map/components/map-tools/print-dialog/print-dialog.component.ts @@ -382,7 +382,12 @@ export class PrintDialogComponent implements OnInit, OnDestroy { } else { this.formGroup.controls.dpi.enable(); } - this.formGroup.controls.dpi.setValue(this.availableDpiSettings[0]); + const isSelectedDpiSettingAllowed = this.availableDpiSettings.some( + (availableDpiSetting) => availableDpiSetting === this.formGroup.controls.dpi.value, + ); + if (!isSelectedDpiSettingAllowed) { + this.formGroup.controls.dpi.setValue(this.availableDpiSettings[0]); + } } private updateFileTypeValueOnValueChange() { @@ -391,6 +396,11 @@ export class PrintDialogComponent implements OnInit, OnDestroy { } else { this.formGroup.controls.fileFormat.enable(); } - this.formGroup.controls.fileFormat.setValue(this.availableFileFormats[0]); + const isSelectedFileFormatAllowed = this.availableFileFormats.some( + (availableFileFormat) => availableFileFormat === this.formGroup.controls.fileFormat.value, + ); + if (!isSelectedFileFormatAllowed) { + this.formGroup.controls.fileFormat.setValue(this.availableFileFormats[0]); + } } } From f03e530163388563ce4e99e671d50f62188ae14b Mon Sep 17 00:00:00 2001 From: till_schuetze Date: Mon, 2 Sep 2024 17:51:57 +0200 Subject: [PATCH 05/43] Update tests --- src/app/state/app/effects/search.effect.spec.ts | 2 ++ src/app/state/app/effects/url.effects.spec.ts | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/app/state/app/effects/search.effect.spec.ts b/src/app/state/app/effects/search.effect.spec.ts index 2c671e089..348ec0fb0 100644 --- a/src/app/state/app/effects/search.effect.spec.ts +++ b/src/app/state/app/effects/search.effect.spec.ts @@ -105,6 +105,7 @@ describe('SearchEffects', () => { isHeadlessPage: false, isSimplifiedPage: false, previousPage: MainPage.Data, + keepTemporaryUrlParams: false, }); const mapDrawingService = TestBed.inject(MapDrawingService); @@ -123,6 +124,7 @@ describe('SearchEffects', () => { isHeadlessPage: false, isSimplifiedPage: false, previousPage: MainPage.Data, + keepTemporaryUrlParams: false, }); let newAction; diff --git a/src/app/state/app/effects/url.effects.spec.ts b/src/app/state/app/effects/url.effects.spec.ts index 64e306a2d..402d5ef30 100644 --- a/src/app/state/app/effects/url.effects.spec.ts +++ b/src/app/state/app/effects/url.effects.spec.ts @@ -12,7 +12,7 @@ import {BasemapConfigService} from '../../../map/services/basemap-config.service import {selectQueryParams} from '../selectors/router.selector'; import {selectMapConfigParams} from '../../map/selectors/map-config-params.selector'; import {MapConfigActions} from '../../map/actions/map-config.actions'; -import {selectMainPage} from '../reducers/url.reducer'; +import {selectKeepTemporaryUrlParams, selectMainPage} from '../reducers/url.reducer'; import {RouteParamConstants} from '../../../shared/constants/route-param.constants'; import {SearchActions} from '../actions/search.actions'; import {InitialMapExtentService} from '../../../map/services/initial-map-extent.service'; @@ -223,6 +223,7 @@ describe('UrlEffects', () => { const params = {x: 123, y: 456, scale: 789, basemap: 'Dust II'}; const existingParams = {x: 1, y: 2, scale: 3, basemap: '4'}; store.overrideSelector(selectQueryParams, existingParams); + store.overrideSelector(selectKeepTemporaryUrlParams, false); const expectedParams = params; @@ -240,6 +241,7 @@ describe('UrlEffects', () => { const params = {x: 123, y: 456, scale: 789, basemap: 'Dust II'}; const existingParams = {...params, initialMapIds: 'one,two', searchTerm: 'search', searchIndex: 'index'}; store.overrideSelector(selectQueryParams, existingParams); + store.overrideSelector(selectKeepTemporaryUrlParams, false); const expectedParams = {...params, initialMapIds: null, searchTerm: null, searchIndex: null}; @@ -257,6 +259,7 @@ describe('UrlEffects', () => { const params = {x: 123, y: 456, scale: 789, basemap: 'Dust II'}; const existingParams = params; store.overrideSelector(selectQueryParams, existingParams); + store.overrideSelector(selectKeepTemporaryUrlParams, false); actions$ = of(UrlActions.setMapPageParams({params})); effects.setMapPageParameters$.subscribe(); From c7bd6f018ffeae4a659f9988284f6809b9d4ccde Mon Sep 17 00:00:00 2001 From: till_schuetze Date: Tue, 3 Sep 2024 14:15:28 +0200 Subject: [PATCH 06/43] Close the selection list when map is selected and focus the button to allow opening it again right away --- .../basemap-selection-list.component.ts | 5 ++++- .../basemap-selector/basemap-selector.component.html | 3 ++- .../basemap-selector/basemap-selector.component.ts | 6 ++++++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/app/map/components/map-controls/basemap-selector/basemap-selection-list/basemap-selection-list.component.ts b/src/app/map/components/map-controls/basemap-selector/basemap-selection-list/basemap-selection-list.component.ts index 458a910de..06d9471fa 100644 --- a/src/app/map/components/map-controls/basemap-selector/basemap-selection-list/basemap-selection-list.component.ts +++ b/src/app/map/components/map-controls/basemap-selector/basemap-selection-list/basemap-selection-list.component.ts @@ -1,4 +1,4 @@ -import {Component, OnDestroy, OnInit} from '@angular/core'; +import {Component, EventEmitter, OnDestroy, OnInit, Output} from '@angular/core'; import {Store} from '@ngrx/store'; import {Subscription, tap} from 'rxjs'; import {ScreenMode} from 'src/app/shared/types/screen-size.type'; @@ -14,6 +14,8 @@ import {BasemapConfigService} from '../../../../services/basemap-config.service' styleUrls: ['./basemap-selection-list.component.scss'], }) export class BasemapSelectionListComponent implements OnInit, OnDestroy { + @Output() public basemapChangedEvent = new EventEmitter(); + public activeBasemap?: Basemap; public availableBasemaps: Basemap[] = []; public screenMode: ScreenMode = 'regular'; @@ -39,6 +41,7 @@ export class BasemapSelectionListComponent implements OnInit, OnDestroy { public switchBasemap(toId: string) { this.store.dispatch(MapConfigActions.setBasemap({activeBasemapId: toId})); + this.basemapChangedEvent.emit(); } private initSubscriptions() { diff --git a/src/app/map/components/map-controls/basemap-selector/basemap-selector.component.html b/src/app/map/components/map-controls/basemap-selector/basemap-selector.component.html index a79c45a70..0dc536ae7 100644 --- a/src/app/map/components/map-controls/basemap-selector/basemap-selector.component.html +++ b/src/app/map/components/map-controls/basemap-selector/basemap-selector.component.html @@ -1,9 +1,10 @@
    - +
    diff --git a/src/app/map/components/map-controls/basemap-selector/basemap-selector.component.ts b/src/app/map/components/map-controls/basemap-selector/basemap-selector.component.ts index fc4177009..f8ce49206 100644 --- a/src/app/map/components/map-controls/basemap-selector/basemap-selector.component.ts +++ b/src/app/map/components/map-controls/basemap-selector/basemap-selector.component.ts @@ -13,6 +13,7 @@ import {BasemapConfigService} from '../../../services/basemap-config.service'; }) export class BasemapSelectorComponent implements OnInit, OnDestroy, AfterViewInit { @ViewChild('basemapSelector', {read: ElementRef, static: false}) private basemapSelectorRef!: ElementRef; + @ViewChild('basemapSelectorButton', {read: ElementRef}) private basemapSelectorButtonRef!: ElementRef; public activeBasemap?: Basemap; public isSelectionOpen: boolean = false; @@ -50,6 +51,11 @@ export class BasemapSelectorComponent implements OnInit, OnDestroy, AfterViewIni ); } + public toggleAndFocusBasemapSelectorButton() { + this.toggleSelection(); + this.basemapSelectorButtonRef.nativeElement.focus(); + } + public toggleSelection() { this.isSelectionOpen = !this.isSelectionOpen; } From 51e8b7199d4f90567ebf7dd64518f63670547d90 Mon Sep 17 00:00:00 2001 From: till_schuetze Date: Tue, 3 Sep 2024 15:43:37 +0200 Subject: [PATCH 07/43] Add custom page title to each page --- src/app/app-routing.module.ts | 43 +++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index e0ea49564..5a70b106e 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -5,29 +5,52 @@ import {NotFoundErrorPageComponent} from './error-handling/components/not-found- import {FatalErrorPageComponent} from './error-handling/components/fatal-error-page/fatal-error-page.component'; import {fatalErrorMapGuard} from './embedded-page/guards/fatal-error-page.guard'; +const siteOperator = 'Geoportal Kanton Zürich'; const routes: Routes = [ { path: '', children: [ - {path: MainPage.Auth, loadChildren: () => import('./auth/auth.module').then((m) => m.AuthModule)}, - {path: MainPage.Maps, loadChildren: () => import('./map/map.module').then((m) => m.MapModule)}, - {path: MainPage.Data, loadChildren: () => import('./data-catalogue/data-catalogue.module').then((m) => m.DataCatalogueModule)}, - {path: MainPage.Support, loadChildren: () => import('./support-page/support-page.module').then((m) => m.SupportPageModule)}, - {path: MainPage.Privacy, loadChildren: () => import('./privacy/privacy.module').then((m) => m.PrivacyModule)}, - {path: MainPage.TermsOfUse, loadChildren: () => import('./terms-of-use/terms-of-use.module').then((m) => m.TermsOfUseModule)}, - {path: MainPage.Start, loadChildren: () => import('./start-page/start-page.module').then((m) => m.StartPageModule)}, + {path: MainPage.Auth, loadChildren: () => import('./auth/auth.module').then((m) => m.AuthModule), title: `Login ${siteOperator}`}, + {path: MainPage.Maps, loadChildren: () => import('./map/map.module').then((m) => m.MapModule), title: `GIS-Browser ${siteOperator}`}, + { + path: MainPage.Data, + loadChildren: () => import('./data-catalogue/data-catalogue.module').then((m) => m.DataCatalogueModule), + title: `Geodatenkatalog ${siteOperator}`, + }, + { + path: MainPage.Support, + loadChildren: () => import('./support-page/support-page.module').then((m) => m.SupportPageModule), + title: `Hilfe & Support ${siteOperator}`, + }, + { + path: MainPage.Privacy, + loadChildren: () => import('./privacy/privacy.module').then((m) => m.PrivacyModule), + title: `Datenschutz ${siteOperator}`, + }, + { + path: MainPage.TermsOfUse, + loadChildren: () => import('./terms-of-use/terms-of-use.module').then((m) => m.TermsOfUseModule), + title: `Nutzungshinweise ${siteOperator}`, + }, + { + path: MainPage.Start, + loadChildren: () => import('./start-page/start-page.module').then((m) => m.StartPageModule), + title: `${siteOperator}`, + }, { path: MainPage.ShareLink, loadChildren: () => import('./share-link/share-link.module').then((m) => m.ShareLinkModule), + title: `Link teilen ${siteOperator}`, }, { path: MainPage.Embedded, loadChildren: () => import('./embedded-page/embedded-map-page.module').then((m) => m.EmbeddedMapPageModule), + title: `GIS-Browser ${siteOperator}`, }, - {path: MainPage.Error, component: FatalErrorPageComponent, canDeactivate: [fatalErrorMapGuard]}, - {path: MainPage.NotFound, component: NotFoundErrorPageComponent}, - {path: '**', component: NotFoundErrorPageComponent}, + {path: MainPage.Error, component: FatalErrorPageComponent, canDeactivate: [fatalErrorMapGuard], title: `Fehler ${siteOperator}`}, + {path: MainPage.NotFound, component: NotFoundErrorPageComponent, title: `Seite nicht gefunden ${siteOperator}`}, + {path: '**', component: NotFoundErrorPageComponent, title: `Seite nicht gefunden ${siteOperator}`}, ], }, ]; From 48bde88f6e66fc1d390017abc1149e3e9951bd75 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Wed, 4 Sep 2024 00:09:52 +0000 Subject: [PATCH 08/43] Update dependency puppeteer to v23.2.2 --- package-lock.json | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/package-lock.json b/package-lock.json index a4880f511..2f149d7fe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7474,9 +7474,9 @@ } }, "node_modules/chromium-bidi": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.6.4.tgz", - "integrity": "sha512-8zoq6ogmhQQkAKZVKO2ObFTl4uOkqoX1PlKQX3hZQ5E9cbUotcAb7h4pTNVAGGv8Z36PF3CtdOriEp/Rz82JqQ==", + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.6.5.tgz", + "integrity": "sha512-RuLrmzYrxSb0s9SgpB+QN5jJucPduZQ/9SIe76MDxYJuecPW5mxMdacJ1f4EtgiV+R0p3sCkznTMvH0MPGFqjA==", "dev": true, "dependencies": { "mitt": "3.0.1", @@ -14063,17 +14063,17 @@ } }, "node_modules/puppeteer": { - "version": "23.2.1", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-23.2.1.tgz", - "integrity": "sha512-IvJOBP2APjcIR2k0xKYYpAs/hAa39e6sn7y+qMlSWJDRraEc4JLfgCKlkXopzD5jrSc1iTANHWw7Rrj/w7bgpw==", + "version": "23.2.2", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-23.2.2.tgz", + "integrity": "sha512-3RX5vEhlOE/9M7ZXxoJVvI7pbOF3fzFK4etwbdii7w+r58q+krK5l2FXWlA1ETnNs7ilM/KLFc0n6K8VUi99dA==", "dev": true, "hasInstallScript": true, "dependencies": { "@puppeteer/browsers": "2.3.1", - "chromium-bidi": "0.6.4", + "chromium-bidi": "0.6.5", "cosmiconfig": "^9.0.0", "devtools-protocol": "0.0.1330662", - "puppeteer-core": "23.2.1", + "puppeteer-core": "23.2.2", "typed-query-selector": "^2.12.0" }, "bin": { @@ -14084,13 +14084,13 @@ } }, "node_modules/puppeteer-core": { - "version": "23.2.1", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-23.2.1.tgz", - "integrity": "sha512-AIFWfQ4Sq+En+OgqIUy8VJmD8yJHMDyt+qEmEVKW07zu5DKDNqysO7fzBZp0W85ShJTUlUf+RleKl4XLwFpUPA==", + "version": "23.2.2", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-23.2.2.tgz", + "integrity": "sha512-MK2Kbdmro+nX9/pfGKm8TiU5G3CuS6BbcNfkcz42GWnHp7KYsJHrP6lPDepiyvwjti5Bt/4a8U3w+DoFpIcBHQ==", "dev": true, "dependencies": { "@puppeteer/browsers": "2.3.1", - "chromium-bidi": "0.6.4", + "chromium-bidi": "0.6.5", "debug": "^4.3.6", "devtools-protocol": "0.0.1330662", "typed-query-selector": "^2.12.0", From a6368447ddca51035f6541fd05a86404ac3d72cf Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Wed, 4 Sep 2024 00:09:58 +0000 Subject: [PATCH 09/43] Update dependency typescript to ~5.5.0 --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index a4880f511..08945b1d8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -76,7 +76,7 @@ "lint-staged": "^15.0.0", "prettier": "^3.3.3", "puppeteer": "^23.0.0", - "typescript": "~5.4.5" + "typescript": "~5.5.0" }, "engines": { "node": "20.x" @@ -16067,9 +16067,9 @@ "dev": true }, "node_modules/typescript": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", - "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" diff --git a/package.json b/package.json index 4eb0f8cfc..082b4a555 100644 --- a/package.json +++ b/package.json @@ -93,6 +93,6 @@ "lint-staged": "^15.0.0", "prettier": "^3.3.3", "puppeteer": "^23.0.0", - "typescript": "~5.4.5" + "typescript": "~5.5.0" } } From f28b643cc471361f5ef8f55d24eac3cbf679aa4e Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Thu, 5 Sep 2024 00:08:57 +0000 Subject: [PATCH 10/43] Update angular to v18.2.3 --- package-lock.json | 204 +++++++++++++++++++++++----------------------- 1 file changed, 102 insertions(+), 102 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9700ca477..704fc0a5f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -103,11 +103,11 @@ } }, "node_modules/@angular-devkit/architect": { - "version": "0.1802.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1802.2.tgz", - "integrity": "sha512-LPRl9jhcf0NgshaL6RoUy1uL/cAyNt7oxctoZ9EHUu8eh5E9W/jZGhVowjOLpirwqYhmEzKJJIeS49Ssqs3RQg==", + "version": "0.1802.3", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1802.3.tgz", + "integrity": "sha512-WQ2AmkUKy1bqrDlNfozW8+VT2Tv/Fdmu4GIXps3ytZANyAKiIvTzmmql2cRCXXraa9FNMjLWNvz+qolDxWVdYQ==", "dependencies": { - "@angular-devkit/core": "18.2.2", + "@angular-devkit/core": "18.2.3", "rxjs": "7.8.1" }, "engines": { @@ -117,15 +117,15 @@ } }, "node_modules/@angular-devkit/build-angular": { - "version": "18.2.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-18.2.2.tgz", - "integrity": "sha512-7HEnTN2T1jnjuItXKcApOsoYGgfou4+POju3ZbwIQukDZ3B2COskvQkVTxqPNrQ0ZjT2mxZYoVlmGW9M+7N25g==", + "version": "18.2.3", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-18.2.3.tgz", + "integrity": "sha512-uUQba0SIskKORHcPayt7LpqPRKD//48EW92SgGHEArn2KklM+FSYBOA9OtrJeZ/UAcoJpdLDtvyY4+S7oFzomg==", "dependencies": { "@ampproject/remapping": "2.3.0", - "@angular-devkit/architect": "0.1802.2", - "@angular-devkit/build-webpack": "0.1802.2", - "@angular-devkit/core": "18.2.2", - "@angular/build": "18.2.2", + "@angular-devkit/architect": "0.1802.3", + "@angular-devkit/build-webpack": "0.1802.3", + "@angular-devkit/core": "18.2.3", + "@angular/build": "18.2.3", "@babel/core": "7.25.2", "@babel/generator": "7.25.0", "@babel/helper-annotate-as-pure": "7.24.7", @@ -136,7 +136,7 @@ "@babel/preset-env": "7.25.3", "@babel/runtime": "7.25.0", "@discoveryjs/json-ext": "0.6.1", - "@ngtools/webpack": "18.2.2", + "@ngtools/webpack": "18.2.3", "@vitejs/plugin-basic-ssl": "1.1.0", "ansi-colors": "4.1.3", "autoprefixer": "10.4.20", @@ -179,7 +179,7 @@ "vite": "5.4.0", "watchpack": "2.4.1", "webpack": "5.94.0", - "webpack-dev-middleware": "7.3.0", + "webpack-dev-middleware": "7.4.2", "webpack-dev-server": "5.0.4", "webpack-merge": "6.0.1", "webpack-subresource-integrity": "5.1.0" @@ -669,11 +669,11 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/@angular-devkit/build-webpack": { - "version": "0.1802.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1802.2.tgz", - "integrity": "sha512-Pj+YmKh0nJOKl6QAsqYh3SqfuVJrFqjyp5WrG9BgfsMD9GCMD+5teMHNYJlp+vG/C8e7VdZp4rqOon8K9Xn4Mw==", + "version": "0.1802.3", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1802.3.tgz", + "integrity": "sha512-/Nixv9uAg6v/OPoZa0PB0zi+iezzBkgLrnrJnestny5B536l9WRtsw97RjeQDu+x2BClQsxNe8NL2A7EvjVD6w==", "dependencies": { - "@angular-devkit/architect": "0.1802.2", + "@angular-devkit/architect": "0.1802.3", "rxjs": "7.8.1" }, "engines": { @@ -687,9 +687,9 @@ } }, "node_modules/@angular-devkit/core": { - "version": "18.2.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-18.2.2.tgz", - "integrity": "sha512-Zz0tGptI/QQnUBDdp+1G5wGwQWMjpfe2oO+UohkrDVgFS71yVj4VDnOy51kMTxBvzw+36evTgthPpmzqPIfxBw==", + "version": "18.2.3", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-18.2.3.tgz", + "integrity": "sha512-vbFs+ofNK9OWeMIcFarFjegXVklhtSdLTEFKZ9trDVr8alTJdjI9AiYa6OOUTDAyq0hqYxV26xlCisWAPe7s5w==", "dependencies": { "ajv": "8.17.1", "ajv-formats": "3.0.1", @@ -729,11 +729,11 @@ } }, "node_modules/@angular-devkit/schematics": { - "version": "18.2.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-18.2.2.tgz", - "integrity": "sha512-PU6+3nX+gQ3gofR7BGwXuvNUNeeV2raURaZjlPfGpBqjyTBxukMV71QsTTWptAZT4WibCWkTFp6X1gvsOGbjMg==", + "version": "18.2.3", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-18.2.3.tgz", + "integrity": "sha512-N3tRAzBW2yWQhebvc1Ha18XTMSXOQTfr8HNjx7Fasx0Fg1tNyGR612MJNZw6je/PqyItKeUHOhztvFMfCQjRyg==", "dependencies": { - "@angular-devkit/core": "18.2.2", + "@angular-devkit/core": "18.2.3", "jsonc-parser": "3.3.1", "magic-string": "0.30.11", "ora": "5.4.1", @@ -838,9 +838,9 @@ } }, "node_modules/@angular/animations": { - "version": "18.2.2", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-18.2.2.tgz", - "integrity": "sha512-jh/dGrY77HGm54HdTiQsxmvoRfFeJgHeWAK2+nWCPoc4b7OHcWxy/04cYffs0/27ThmABmppP7ERAyZ0f60uow==", + "version": "18.2.3", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-18.2.3.tgz", + "integrity": "sha512-rIATopHr83lYR0X05buHeHssq9CGw0I0YPIQcpUTGnlqIpJcQVCf7jCFn4KGZrE9V55hFY3MD4S28njlwCToQQ==", "dependencies": { "tslib": "^2.3.0" }, @@ -848,16 +848,16 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/core": "18.2.2" + "@angular/core": "18.2.3" } }, "node_modules/@angular/build": { - "version": "18.2.2", - "resolved": "https://registry.npmjs.org/@angular/build/-/build-18.2.2.tgz", - "integrity": "sha512-okaDdTMXnDhvnnnih6rPQnexL6htfEAPr19bB1Ci9d31gEjVuKZCjlcw2sPZ6BUyilwC9nZlCI5vbH1Ljf6mzA==", + "version": "18.2.3", + "resolved": "https://registry.npmjs.org/@angular/build/-/build-18.2.3.tgz", + "integrity": "sha512-USrD2Zvcb1te2dnqhH7JZ5XeJDg/t7fjUHR4f93vvMrnrncwCjLoHbHpz01HCHfcIVRgsYUdAmAi1iG7vpak7w==", "dependencies": { "@ampproject/remapping": "2.3.0", - "@angular-devkit/architect": "0.1802.2", + "@angular-devkit/architect": "0.1802.3", "@babel/core": "7.25.2", "@babel/helper-annotate-as-pure": "7.24.7", "@babel/helper-split-export-declaration": "7.24.7", @@ -1323,9 +1323,9 @@ } }, "node_modules/@angular/cdk": { - "version": "18.2.2", - "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-18.2.2.tgz", - "integrity": "sha512-+u7ZcMA24WO03vDzlBJJWq+okZLFDeW9JrtHzrdiT09FDt4sdUp+7PddXaZcRHIXjJL+CaCLQ6slaqPNEufqgg==", + "version": "18.2.3", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-18.2.3.tgz", + "integrity": "sha512-lUcpYTxPZuntJ1FK7V2ugapCGMIhT6TUDjIGgXfS9AxGSSKgwr8HNs6Ze9pcjYC44UhP40sYAZuiaFwmE60A2A==", "dependencies": { "tslib": "^2.3.0" }, @@ -1339,16 +1339,16 @@ } }, "node_modules/@angular/cli": { - "version": "18.2.2", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-18.2.2.tgz", - "integrity": "sha512-HVVaMxnbID0q+V3KE+JqzGbPHcBUFo1RKhBZ/jxY7USZNzgtyYbRc0IYqPWNdr99UT5QefTJrjVazJo1nqQZvQ==", + "version": "18.2.3", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-18.2.3.tgz", + "integrity": "sha512-40258vuliH6+p8QSByZe5EcIXSj0iR3PNF6yuusClR/ByToHOnmuPw7WC+AYr0ooozmqlim/EjQe4/037OUB3w==", "dependencies": { - "@angular-devkit/architect": "0.1802.2", - "@angular-devkit/core": "18.2.2", - "@angular-devkit/schematics": "18.2.2", + "@angular-devkit/architect": "0.1802.3", + "@angular-devkit/core": "18.2.3", + "@angular-devkit/schematics": "18.2.3", "@inquirer/prompts": "5.3.8", "@listr2/prompt-adapter-inquirer": "2.0.15", - "@schematics/angular": "18.2.2", + "@schematics/angular": "18.2.3", "@yarnpkg/lockfile": "1.1.0", "ini": "4.1.3", "jsonc-parser": "3.3.1", @@ -1371,9 +1371,9 @@ } }, "node_modules/@angular/common": { - "version": "18.2.2", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-18.2.2.tgz", - "integrity": "sha512-AQe4xnnNNch/sXRnV82C8FmhijxPATKfPGojC2qbAG2o6VkWKgt5Lbj0O8WxvSIOS5Syedv+O2kLY/JMGWHNtw==", + "version": "18.2.3", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-18.2.3.tgz", + "integrity": "sha512-NFL4yXXImSCH7i1xnHykUjHa9vl9827fGiwSV2mnf7LjSUsyDzFD8/54dNuYN9OY8AUD+PnK0YdNro6cczVyIA==", "dependencies": { "tslib": "^2.3.0" }, @@ -1381,14 +1381,14 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/core": "18.2.2", + "@angular/core": "18.2.3", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/compiler": { - "version": "18.2.2", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-18.2.2.tgz", - "integrity": "sha512-gmVNCXZiv/CIk2eKRLnH19N9VsPuE2s3Oxm0MNi003zk1cLy7D4YEm4fSrjKXtPY8MMpRXiu5f63W94hLwWEVw==", + "version": "18.2.3", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-18.2.3.tgz", + "integrity": "sha512-Il3ljs0j1GaYoqYFdShjUP1ryck5xTOaA8uQuRgqwU0FOwEDfugSAM3Qf7nJx/sgxTM0Lm/Nrdv2u6i1gZWeuQ==", "dependencies": { "tslib": "^2.3.0" }, @@ -1396,7 +1396,7 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/core": "18.2.2" + "@angular/core": "18.2.3" }, "peerDependenciesMeta": { "@angular/core": { @@ -1405,9 +1405,9 @@ } }, "node_modules/@angular/compiler-cli": { - "version": "18.2.2", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-18.2.2.tgz", - "integrity": "sha512-fF7lDrTA12YGqVjF4LyMi4hm58cv9G6CWmzSlvun0nMYCwrbRNnakZsj19dOfiIqqu4MwHaF4w3PTmUSxkMuiw==", + "version": "18.2.3", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-18.2.3.tgz", + "integrity": "sha512-BcmqYKnkcJTkGjuPztClZNQve7tdI290J5F3iZBx6c7/vaw8EU8EGZtpWYZpgiVn5S6jhcKyc1dLF9ggO9vftg==", "dependencies": { "@babel/core": "7.25.2", "@jridgewell/sourcemap-codec": "^1.4.14", @@ -1427,14 +1427,14 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/compiler": "18.2.2", + "@angular/compiler": "18.2.3", "typescript": ">=5.4 <5.6" } }, "node_modules/@angular/core": { - "version": "18.2.2", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-18.2.2.tgz", - "integrity": "sha512-Rx6XajL0Ydj9hXUSPDvL2Q/kMzWtbiE3VxZFJnkE+fLQiWvr0GncB+NTb/nQ6QlPQ0ly60DvuI3KLcGDuFtGVA==", + "version": "18.2.3", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-18.2.3.tgz", + "integrity": "sha512-VGhMJxj7d0rYpqVfQrcGRB7EE/BCziotft/I/YPl6bOMPSAvMukG7DXQuJdYpNrr62ks78mlzHlZX/cdmB9Prw==", "dependencies": { "tslib": "^2.3.0" }, @@ -1447,9 +1447,9 @@ } }, "node_modules/@angular/forms": { - "version": "18.2.2", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-18.2.2.tgz", - "integrity": "sha512-K8cv0w6o7+ocQfUrdSA3XaKrYfa1+2TlmtyxPHjEd2mCu2R+Yqo5RqJ3P8keFewJ1+bSLhz6xnn6mumwl0RnUQ==", + "version": "18.2.3", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-18.2.3.tgz", + "integrity": "sha512-+OBaAH0e8hue9eyLnbgpxg1/X9fps6bwXECfJ0nL5BDPU5itZ428YJbEnj5bTx0hEbqfTRiV4LgexdI+D9eOpw==", "dependencies": { "tslib": "^2.3.0" }, @@ -1457,16 +1457,16 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/common": "18.2.2", - "@angular/core": "18.2.2", - "@angular/platform-browser": "18.2.2", + "@angular/common": "18.2.3", + "@angular/core": "18.2.3", + "@angular/platform-browser": "18.2.3", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/localize": { - "version": "18.2.2", - "resolved": "https://registry.npmjs.org/@angular/localize/-/localize-18.2.2.tgz", - "integrity": "sha512-grWQ3CVbizOWCthGpyIlNNnZCpF/xpWYa6tIsPzKOXLCyqFQ7vOEtSludNN1nsUmMlZQt76+wA17Fx0qcNx0EA==", + "version": "18.2.3", + "resolved": "https://registry.npmjs.org/@angular/localize/-/localize-18.2.3.tgz", + "integrity": "sha512-ZTliuRfH/hGwQTmFb1FwKOyMUks2ATuFVFzKnxbsxoo+XgTg+e12FcUfPEfdtPAteZ9gSuc/9hP8sM0RzW0LPg==", "dependencies": { "@babel/core": "7.25.2", "@types/babel__core": "7.20.5", @@ -1482,20 +1482,20 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/compiler": "18.2.2", - "@angular/compiler-cli": "18.2.2" + "@angular/compiler": "18.2.3", + "@angular/compiler-cli": "18.2.3" } }, "node_modules/@angular/material": { - "version": "18.2.2", - "resolved": "https://registry.npmjs.org/@angular/material/-/material-18.2.2.tgz", - "integrity": "sha512-c+EQo1GEvM2w3qasgV/BGxB0bpJeSGs2WcMVTXCYVMcqEk8nwpALwfZiCAYl8JoKoiC5k993zz19xP2Eu14qkQ==", + "version": "18.2.3", + "resolved": "https://registry.npmjs.org/@angular/material/-/material-18.2.3.tgz", + "integrity": "sha512-JFfvXaMHMhskncaxxus4sDvie9VYdMkfYgfinkLXpZlPFyn1IzjDw0c1BcrcsuD7UxQVZ/v5tucCgq1FQfGRpA==", "dependencies": { "tslib": "^2.3.0" }, "peerDependencies": { "@angular/animations": "^18.0.0 || ^19.0.0", - "@angular/cdk": "18.2.2", + "@angular/cdk": "18.2.3", "@angular/common": "^18.0.0 || ^19.0.0", "@angular/core": "^18.0.0 || ^19.0.0", "@angular/forms": "^18.0.0 || ^19.0.0", @@ -1504,9 +1504,9 @@ } }, "node_modules/@angular/platform-browser": { - "version": "18.2.2", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-18.2.2.tgz", - "integrity": "sha512-Bfvl8elCFxyJ9vlwamr4X5sVMcp/tSwBal2coyl0WR+/PH2PAAtf+/WMYxIN90yZmPiJx6RZWUSJRlHOFiFp3A==", + "version": "18.2.3", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-18.2.3.tgz", + "integrity": "sha512-M2ob4zN7tAcL2mx7U6KnZNqNFPFl9MlPBE0FrjQjIzAjU0wSYPIJXmaPu9aMUp9niyo+He5iX98I+URi2Yc99g==", "dependencies": { "tslib": "^2.3.0" }, @@ -1514,9 +1514,9 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/animations": "18.2.2", - "@angular/common": "18.2.2", - "@angular/core": "18.2.2" + "@angular/animations": "18.2.3", + "@angular/common": "18.2.3", + "@angular/core": "18.2.3" }, "peerDependenciesMeta": { "@angular/animations": { @@ -1525,9 +1525,9 @@ } }, "node_modules/@angular/platform-browser-dynamic": { - "version": "18.2.2", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-18.2.2.tgz", - "integrity": "sha512-UM/+1nY4iIj1v4lxAmV3XRHPAh/4qfNKScCLq8tJGot64rPCbtCl0Rl8rFFGqxAFvTErVDaJycUgWNZSfVl/hw==", + "version": "18.2.3", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-18.2.3.tgz", + "integrity": "sha512-nWi9ZxN4KpbJkttIckFO1PCoW0+gb/18xFO+JWyLBAtcbsudj/Mv0P/fdOaSfQdLkPhZfORr3ZcfiTkhmuGyEg==", "dependencies": { "tslib": "^2.3.0" }, @@ -1535,16 +1535,16 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/common": "18.2.2", - "@angular/compiler": "18.2.2", - "@angular/core": "18.2.2", - "@angular/platform-browser": "18.2.2" + "@angular/common": "18.2.3", + "@angular/compiler": "18.2.3", + "@angular/core": "18.2.3", + "@angular/platform-browser": "18.2.3" } }, "node_modules/@angular/router": { - "version": "18.2.2", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-18.2.2.tgz", - "integrity": "sha512-tBHwuNtZNjzYAoVdveTI1ke/ZnQjKhc7gqDk9HCH2JUpdQhGbTvCKwDM51ktJpPMPcZlA263lQyy7VIyvdtK0A==", + "version": "18.2.3", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-18.2.3.tgz", + "integrity": "sha512-fvD9eSDIiIbeYoUokoWkXzu7/ZaxlzKPUHFqX1JuKuH5ciQDeT/d7lp4mj31Bxammhohzi3+z12THJYsCkj/iQ==", "dependencies": { "tslib": "^2.3.0" }, @@ -1552,9 +1552,9 @@ "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/common": "18.2.2", - "@angular/core": "18.2.2", - "@angular/platform-browser": "18.2.2", + "@angular/common": "18.2.3", + "@angular/core": "18.2.3", + "@angular/platform-browser": "18.2.3", "rxjs": "^6.5.3 || ^7.4.0" } }, @@ -4528,9 +4528,9 @@ } }, "node_modules/@ngtools/webpack": { - "version": "18.2.2", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-18.2.2.tgz", - "integrity": "sha512-YhADmc+lVjLt3kze07A+yLry2yzcghdclu+7D3EDfa6fG2Pk33HK3MY2I0Z0BO+Ivoq7cV7yxm+naR+Od0Y5ng==", + "version": "18.2.3", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-18.2.3.tgz", + "integrity": "sha512-DDuBHcu23qckt43SexBJaPEIeMc/HKaFOidILZM9D4gU4C9VroMActdR218dvQ802QfL0S46t5Ykz8ENprIfjA==", "engines": { "node": "^18.19.1 || ^20.11.1 || >=22.0.0", "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", @@ -5076,12 +5076,12 @@ ] }, "node_modules/@schematics/angular": { - "version": "18.2.2", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-18.2.2.tgz", - "integrity": "sha512-0uPA1kQ38RnbNrzMlveX/QAqQIDu2INl5IYd3EUbJZRfYSp1VVyOSyuIBJ+1iUl5Y5VUa2uylaVZXhFdKWprXw==", + "version": "18.2.3", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-18.2.3.tgz", + "integrity": "sha512-whSON70z9HYb4WboVXmPFE/RLKJJQLWNzNcUyi8OSDZkQbJnYgPp0///n738m26Y/XeJDv11q1gESy+Zl2AdUw==", "dependencies": { - "@angular-devkit/core": "18.2.2", - "@angular-devkit/schematics": "18.2.2", + "@angular-devkit/core": "18.2.3", + "@angular-devkit/schematics": "18.2.3", "jsonc-parser": "3.3.1" }, "engines": { @@ -16442,9 +16442,9 @@ } }, "node_modules/webpack-dev-middleware": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.3.0.tgz", - "integrity": "sha512-xD2qnNew+F6KwOGZR7kWdbIou/ud7cVqLEXeK1q0nHcNsX/u7ul/fSdlOTX4ntSL5FNFy7ZJJXbf0piF591JYw==", + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.4.2.tgz", + "integrity": "sha512-xOO8n6eggxnwYpy1NlzUKpvrjfJTvae5/D6WOK0S2LSo7vjmo5gCM1DbLUmFqrMTJP+W/0YZNctm7jasWvLuBA==", "dependencies": { "colorette": "^2.0.10", "memfs": "^4.6.0", From 7a21aefcf73d9c191d3475370c2815c2fda9e3b1 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Thu, 5 Sep 2024 00:09:10 +0000 Subject: [PATCH 11/43] Update dependency puppeteer to v23.3.0 --- package-lock.json | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9700ca477..cc67aa8c0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4862,9 +4862,9 @@ } }, "node_modules/@puppeteer/browsers": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.3.1.tgz", - "integrity": "sha512-uK7o3hHkK+naEobMSJ+2ySYyXtQkBxIH8Gn4MK9ciePjNV+Pf+PgY/W7iPzn2MTjl3stcYB5AlcTmPYw7AXDwA==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.4.0.tgz", + "integrity": "sha512-x8J1csfIygOwf6D6qUAZ0ASk3z63zPb7wkNeHRerCMh82qWKUrOgkuP005AJC8lDL6/evtXETGEJVcwykKT4/g==", "dev": true, "dependencies": { "debug": "^4.3.6", @@ -14063,17 +14063,17 @@ } }, "node_modules/puppeteer": { - "version": "23.2.2", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-23.2.2.tgz", - "integrity": "sha512-3RX5vEhlOE/9M7ZXxoJVvI7pbOF3fzFK4etwbdii7w+r58q+krK5l2FXWlA1ETnNs7ilM/KLFc0n6K8VUi99dA==", + "version": "23.3.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-23.3.0.tgz", + "integrity": "sha512-e2jY8cdWSUGsrLxqGm3hIbJq/UIk1uOY8XY7SM51leXkH7shrIyE91lK90Q9byX6tte+cyL3HKqlWBEd6TjWTA==", "dev": true, "hasInstallScript": true, "dependencies": { - "@puppeteer/browsers": "2.3.1", + "@puppeteer/browsers": "2.4.0", "chromium-bidi": "0.6.5", "cosmiconfig": "^9.0.0", "devtools-protocol": "0.0.1330662", - "puppeteer-core": "23.2.2", + "puppeteer-core": "23.3.0", "typed-query-selector": "^2.12.0" }, "bin": { @@ -14084,12 +14084,12 @@ } }, "node_modules/puppeteer-core": { - "version": "23.2.2", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-23.2.2.tgz", - "integrity": "sha512-MK2Kbdmro+nX9/pfGKm8TiU5G3CuS6BbcNfkcz42GWnHp7KYsJHrP6lPDepiyvwjti5Bt/4a8U3w+DoFpIcBHQ==", + "version": "23.3.0", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-23.3.0.tgz", + "integrity": "sha512-sB2SsVMFs4gKad5OCdv6w5vocvtEUrRl0zQqSyRPbo/cj1Ktbarmhxy02Zyb9R9HrssBcJDZbkrvBnbaesPyYg==", "dev": true, "dependencies": { - "@puppeteer/browsers": "2.3.1", + "@puppeteer/browsers": "2.4.0", "chromium-bidi": "0.6.5", "debug": "^4.3.6", "devtools-protocol": "0.0.1330662", From 7f0261b5167e24356fc4da1b83820b00a678180b Mon Sep 17 00:00:00 2001 From: till_schuetze Date: Thu, 5 Sep 2024 08:51:33 +0200 Subject: [PATCH 12/43] Pr fixes --- .../basemap-selection-list.component.ts | 2 +- .../basemap-selector/basemap-selector.component.html | 5 ++++- .../basemap-selector/basemap-selector.component.ts | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/app/map/components/map-controls/basemap-selector/basemap-selection-list/basemap-selection-list.component.ts b/src/app/map/components/map-controls/basemap-selector/basemap-selection-list/basemap-selection-list.component.ts index 06d9471fa..bf233e86d 100644 --- a/src/app/map/components/map-controls/basemap-selector/basemap-selection-list/basemap-selection-list.component.ts +++ b/src/app/map/components/map-controls/basemap-selector/basemap-selection-list/basemap-selection-list.component.ts @@ -14,7 +14,7 @@ import {BasemapConfigService} from '../../../../services/basemap-config.service' styleUrls: ['./basemap-selection-list.component.scss'], }) export class BasemapSelectionListComponent implements OnInit, OnDestroy { - @Output() public basemapChangedEvent = new EventEmitter(); + @Output() public readonly basemapChangedEvent = new EventEmitter(); public activeBasemap?: Basemap; public availableBasemaps: Basemap[] = []; diff --git a/src/app/map/components/map-controls/basemap-selector/basemap-selector.component.html b/src/app/map/components/map-controls/basemap-selector/basemap-selector.component.html index 0dc536ae7..79f79324b 100644 --- a/src/app/map/components/map-controls/basemap-selector/basemap-selector.component.html +++ b/src/app/map/components/map-controls/basemap-selector/basemap-selector.component.html @@ -6,5 +6,8 @@ class="basemap-selector__active" [ngStyle]="{'background-image': 'url(' + (activeBasemap?.id | basemapImageLink) + ')'}" > - +
    diff --git a/src/app/map/components/map-controls/basemap-selector/basemap-selector.component.ts b/src/app/map/components/map-controls/basemap-selector/basemap-selector.component.ts index f8ce49206..2cc4c26c8 100644 --- a/src/app/map/components/map-controls/basemap-selector/basemap-selector.component.ts +++ b/src/app/map/components/map-controls/basemap-selector/basemap-selector.component.ts @@ -51,7 +51,7 @@ export class BasemapSelectorComponent implements OnInit, OnDestroy, AfterViewIni ); } - public toggleAndFocusBasemapSelectorButton() { + public toggleSelectionAndFocusBasemapSelectorButton() { this.toggleSelection(); this.basemapSelectorButtonRef.nativeElement.focus(); } From 1a4d2c0968b1e3cf55231bf133353f314fad70ef Mon Sep 17 00:00:00 2001 From: till_schuetze Date: Thu, 5 Sep 2024 09:16:19 +0200 Subject: [PATCH 13/43] Pr fixes --- src/app/state/app/effects/url.effects.spec.ts | 17 +++++++++++++++++ src/app/state/app/effects/url.effects.ts | 4 ++-- src/app/state/app/reducers/url.reducer.spec.ts | 12 +++++++++++- 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/app/state/app/effects/url.effects.spec.ts b/src/app/state/app/effects/url.effects.spec.ts index 402d5ef30..b560095ed 100644 --- a/src/app/state/app/effects/url.effects.spec.ts +++ b/src/app/state/app/effects/url.effects.spec.ts @@ -268,4 +268,21 @@ describe('UrlEffects', () => { expect(routerSpy).not.toHaveBeenCalled(); })); }); + describe('keepTemporaryUrlParameters$', () => { + const actions = [ + {name: 'SearchActions.setSearchApiError', action: SearchActions.setSearchApiError}, + {name: 'SearchActions.handleEmptyResultsFromUrlSearch', action: SearchActions.handleEmptyResultsFromUrlSearch}, + {name: 'SearchActions.handleInvalidParameters', action: SearchActions.handleInvalidParameters}, + ]; + actions.forEach(({name, action}) => { + it(`dispatches UrlActions.keepTemporaryUrlParameters when ${name} is triggered`, () => { + const expectedAction = UrlActions.keepTemporaryUrlParameters(); + + actions$ = of(action); + effects.keepTemporaryUrlParameters$.subscribe((result) => { + expect(result).toEqual(expectedAction); + }); + }); + }); + }); }); diff --git a/src/app/state/app/effects/url.effects.ts b/src/app/state/app/effects/url.effects.ts index 41fcf4200..096857d23 100644 --- a/src/app/state/app/effects/url.effects.ts +++ b/src/app/state/app/effects/url.effects.ts @@ -121,8 +121,8 @@ export class UrlEffects { map(([{params}, currentParams, _, keepTemporaryUrlParams]) => { let adjustedAndCurrentParams: {params: Params; currentParams: Params} = {params, currentParams}; if ( - Object.keys(currentParams).some((paramKey) => MapConstants.TEMPORARY_URL_PARAMS.includes(paramKey)) && - !keepTemporaryUrlParams + !keepTemporaryUrlParams && + Object.keys(currentParams).some((paramKey) => MapConstants.TEMPORARY_URL_PARAMS.includes(paramKey)) ) { // remove temporary parameters const paramsToRemove = MapConstants.TEMPORARY_URL_PARAMS.reduce((prev, curr) => ({...prev, [curr]: null}), {}); diff --git a/src/app/state/app/reducers/url.reducer.spec.ts b/src/app/state/app/reducers/url.reducer.spec.ts index 05820420d..8ffe578db 100644 --- a/src/app/state/app/reducers/url.reducer.spec.ts +++ b/src/app/state/app/reducers/url.reducer.spec.ts @@ -13,7 +13,7 @@ describe('UrlReducer', () => { }); }); - describe('setUrl', () => { + describe('setPage', () => { it('correctly sets the values from the action and previus state', () => { const props = {mainPage: MainPage.Data, isSimplifiedPage: true, isHeadlessPage: true}; const action = UrlActions.setPage(props); @@ -27,4 +27,14 @@ describe('UrlReducer', () => { expect(result.previousPage).toBe(mockState.mainPage); }); }); + describe('keepTemporaryUrlParameters', () => { + it('correctly sets the value for keepTemporaryUrlParams ', () => { + const action = UrlActions.keepTemporaryUrlParameters(); + const mockState: UrlState = {...initialState, keepTemporaryUrlParams: false}; + + const result = reducer(mockState, action); + + expect(result.keepTemporaryUrlParams).toBe(true); + }); + }); }); From 41c65b929e26eace40f017a4412da9f40c4beccc Mon Sep 17 00:00:00 2001 From: Lukas Merz Date: Thu, 5 Sep 2024 14:06:00 +0200 Subject: [PATCH 14/43] GB3-1647: Add CNAME file to deployment step --- .github/workflows/node-deploy.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/node-deploy.yml b/.github/workflows/node-deploy.yml index 13fb87154..8627c4dfe 100644 --- a/.github/workflows/node-deploy.yml +++ b/.github/workflows/node-deploy.yml @@ -29,6 +29,9 @@ jobs: npm ci npm run build-dev-ebp + - name: Create CNAME file for custom domain + run: echo 'dev.geo.zh.ch' > ./dist/browser/CNAME + - name: Upload artifact uses: actions/upload-pages-artifact@v3 with: From 9c062fd7addac6935bdb03b6fe4f23f56959fc93 Mon Sep 17 00:00:00 2001 From: till_schuetze Date: Thu, 5 Sep 2024 15:00:05 +0200 Subject: [PATCH 15/43] Add skip links to all pages except map page --- src/app/app.component.html | 18 ++++++++++++++---- src/app/app.component.ts | 12 ++++++++++++ .../skip-link/skip-link.component.html | 5 +++++ .../skip-link/skip-link.component.scss | 18 ++++++++++++++++++ .../skip-link/skip-link.component.ts | 17 +++++++++++++++++ .../shared/constants/skip-link.constants.ts | 15 +++++++++++++++ src/app/shared/shared.module.ts | 3 +++ src/app/shared/types/skip-link.type.ts | 4 ++++ 8 files changed, 88 insertions(+), 4 deletions(-) create mode 100644 src/app/shared/components/skip-link/skip-link.component.html create mode 100644 src/app/shared/components/skip-link/skip-link.component.scss create mode 100644 src/app/shared/components/skip-link/skip-link.component.ts create mode 100644 src/app/shared/constants/skip-link.constants.ts create mode 100644 src/app/shared/types/skip-link.type.ts diff --git a/src/app/app.component.html b/src/app/app.component.html index 3b42d1aae..eec4344fb 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -1,10 +1,20 @@
    - - + + +
    - - + +
    diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 746031b6a..034003836 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -18,6 +18,8 @@ import {selectUrlState} from './state/app/reducers/url.reducer'; import {selectMapUiState} from './state/map/reducers/map-ui.reducer'; import {MapUiState} from './state/map/states/map-ui.state'; import {selectDevMode} from './state/app/reducers/app.reducer'; +import {SkipLink} from './shared/types/skip-link.type'; +import {SkipLinkConstants} from './shared/constants/skip-link.constants'; @Component({ selector: 'app-root', @@ -31,6 +33,8 @@ export class AppComponent implements OnInit, OnDestroy { public isSimplifiedPage: boolean = false; public scrollbarWidth?: number; public isDevModeActive: boolean = false; + public readonly skipLinks: SkipLink[] = SkipLinkConstants.skipLinks; + public readonly skipLinksMobile: SkipLink[] = SkipLinkConstants.skipLinksMobile; private snackBarRef?: MatSnackBarRef; private readonly urlState$ = this.store.select(selectUrlState); @@ -59,6 +63,14 @@ export class AppComponent implements OnInit, OnDestroy { this.subscriptions.unsubscribe(); } + public skipTo(elementId: string): void { + const element = document.getElementById(elementId); + if (element) { + element.setAttribute('tabindex', '-1'); + element.focus(); + } + } + @HostListener('document:click', ['$event']) private onDocumentClick(event: PointerEvent) { this.documentService.documentClicked$.next(event); diff --git a/src/app/shared/components/skip-link/skip-link.component.html b/src/app/shared/components/skip-link/skip-link.component.html new file mode 100644 index 000000000..f1eb61e6f --- /dev/null +++ b/src/app/shared/components/skip-link/skip-link.component.html @@ -0,0 +1,5 @@ +@for (skipLink of skipLinks; track skipLink.id) { + +} diff --git a/src/app/shared/components/skip-link/skip-link.component.scss b/src/app/shared/components/skip-link/skip-link.component.scss new file mode 100644 index 000000000..416378149 --- /dev/null +++ b/src/app/shared/components/skip-link/skip-link.component.scss @@ -0,0 +1,18 @@ +@use 'variables/ktzh-design-variables' as ktzh-variables; + +.skip-link { + position: absolute; + left: max(24px, calc((100% - #{ktzh-variables.$zh-layout-max-content-width}) / 2)); + top: -100px; + padding: 24px 12px; + background-color: white; + font-weight: bold; + font-size: 16px; + pointer-events: none; +} + +.skip-link:focus { + top: 0; + z-index: 1000; + pointer-events: all; +} diff --git a/src/app/shared/components/skip-link/skip-link.component.ts b/src/app/shared/components/skip-link/skip-link.component.ts new file mode 100644 index 000000000..a282c0116 --- /dev/null +++ b/src/app/shared/components/skip-link/skip-link.component.ts @@ -0,0 +1,17 @@ +import {Component, EventEmitter, Input, Output} from '@angular/core'; +import {SkipLink} from '../../types/skip-link.type'; + +@Component({ + selector: 'skip-link', + templateUrl: './skip-link.component.html', + styleUrl: './skip-link.component.scss', +}) +export class SkipLinkComponent { + @Input() public skipLinks: SkipLink[] = []; + + @Output() public skipToLocationEvent = new EventEmitter(); + + public skipToLocation(id: string): void { + this.skipToLocationEvent.emit(id); + } +} diff --git a/src/app/shared/constants/skip-link.constants.ts b/src/app/shared/constants/skip-link.constants.ts new file mode 100644 index 000000000..c160ce540 --- /dev/null +++ b/src/app/shared/constants/skip-link.constants.ts @@ -0,0 +1,15 @@ +import {SkipLink} from '../types/skip-link.type'; + +export class SkipLinkConstants { + public static readonly skipLinks: SkipLink[] = [ + {id: 'navigation', label: 'Navigation'}, + {id: 'main-content', label: 'Inhalt'}, + {id: 'footer', label: 'Fussbereich'}, + ]; + + public static readonly skipLinksMobile: SkipLink[] = [ + {id: 'navigation-mobile', label: 'Navigation'}, + {id: 'main-content', label: 'Inhalt'}, + {id: 'footer', label: 'Fussbereich'}, + ]; +} diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index 156a50a5e..d0038746d 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -36,6 +36,7 @@ import {LayerTooltipPipe} from './pipes/layer-tooltip.pipe'; import {Gb2ExitButtonComponent} from './components/external-link-button/gb2-exit-button.component'; import {TypedTourAnchorDirective} from './directives/typed-tour-anchor.directive'; import {ClickOnSpaceBarDirective} from './directives/click-on-spacebar.directive'; +import {SkipLinkComponent} from './components/skip-link/skip-link.component'; @NgModule({ declarations: [ @@ -71,6 +72,7 @@ import {ClickOnSpaceBarDirective} from './directives/click-on-spacebar.directive ShowTooltipIfTruncatedDirective, Gb2ExitButtonComponent, TypedTourAnchorDirective, + SkipLinkComponent, ], imports: [MaterialModule, RouterModule, CommonModule, ResizableModule, ClickOnSpaceBarDirective, NgOptimizedImage], exports: [ @@ -105,6 +107,7 @@ import {ClickOnSpaceBarDirective} from './directives/click-on-spacebar.directive ShowTooltipIfTruncatedDirective, Gb2ExitButtonComponent, TypedTourAnchorDirective, + SkipLinkComponent, ], }) export class SharedModule {} diff --git a/src/app/shared/types/skip-link.type.ts b/src/app/shared/types/skip-link.type.ts new file mode 100644 index 000000000..6d5c59209 --- /dev/null +++ b/src/app/shared/types/skip-link.type.ts @@ -0,0 +1,4 @@ +export type SkipLink = { + id: string; + label: string; +}; From 9d60d4281c98bbd1c5a074aa2ca63535c76badc5 Mon Sep 17 00:00:00 2001 From: till_schuetze Date: Thu, 5 Sep 2024 15:20:06 +0200 Subject: [PATCH 16/43] make skip link standalone --- src/app/app.module.ts | 2 ++ src/app/shared/components/skip-link/skip-link.component.ts | 2 ++ src/app/shared/shared.module.ts | 3 --- src/app/start-page/start-page.component.html | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 5b0b45f4c..171655b29 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -31,6 +31,7 @@ import {effectErrorHandler} from './state/app/effects/effects-error-handler.effe import {EsriMapLoaderService} from './map/services/esri-services/esri-map-loader.service'; import {MapLoaderService} from './map/interfaces/map-loader.service'; import {DevModeBannerComponent} from './shared/components/dev-mode-banner/dev-mode-banner.component'; +import {SkipLinkComponent} from './shared/components/skip-link/skip-link.component'; // necessary for the locale 'de-CH' to work // see https://stackoverflow.com/questions/46419026/missing-locale-data-for-the-locale-xxx-with-angular @@ -55,6 +56,7 @@ export const GRAV_CMS_SERVICE = new InjectionToken('GravCmsServi ErrorHandlingModule, StoreRouterConnectingModule.forRoot(), DevModeBannerComponent, + SkipLinkComponent, ], providers: [ {provide: ErrorHandler, deps: [Router, ErrorHandlerService, EmbeddedErrorHandlerService], useFactory: errorHandlerServiceFactory}, diff --git a/src/app/shared/components/skip-link/skip-link.component.ts b/src/app/shared/components/skip-link/skip-link.component.ts index a282c0116..d9d9d2a48 100644 --- a/src/app/shared/components/skip-link/skip-link.component.ts +++ b/src/app/shared/components/skip-link/skip-link.component.ts @@ -5,6 +5,8 @@ import {SkipLink} from '../../types/skip-link.type'; selector: 'skip-link', templateUrl: './skip-link.component.html', styleUrl: './skip-link.component.scss', + standalone: true, + imports: [], }) export class SkipLinkComponent { @Input() public skipLinks: SkipLink[] = []; diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index d0038746d..156a50a5e 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -36,7 +36,6 @@ import {LayerTooltipPipe} from './pipes/layer-tooltip.pipe'; import {Gb2ExitButtonComponent} from './components/external-link-button/gb2-exit-button.component'; import {TypedTourAnchorDirective} from './directives/typed-tour-anchor.directive'; import {ClickOnSpaceBarDirective} from './directives/click-on-spacebar.directive'; -import {SkipLinkComponent} from './components/skip-link/skip-link.component'; @NgModule({ declarations: [ @@ -72,7 +71,6 @@ import {SkipLinkComponent} from './components/skip-link/skip-link.component'; ShowTooltipIfTruncatedDirective, Gb2ExitButtonComponent, TypedTourAnchorDirective, - SkipLinkComponent, ], imports: [MaterialModule, RouterModule, CommonModule, ResizableModule, ClickOnSpaceBarDirective, NgOptimizedImage], exports: [ @@ -107,7 +105,6 @@ import {SkipLinkComponent} from './components/skip-link/skip-link.component'; ShowTooltipIfTruncatedDirective, Gb2ExitButtonComponent, TypedTourAnchorDirective, - SkipLinkComponent, ], }) export class SharedModule {} diff --git a/src/app/start-page/start-page.component.html b/src/app/start-page/start-page.component.html index 2ebc2b70f..49937e956 100644 --- a/src/app/start-page/start-page.component.html +++ b/src/app/start-page/start-page.component.html @@ -4,7 +4,7 @@ From 57b54c4d8b41d6d2783994d018543e4e09d7cb3c Mon Sep 17 00:00:00 2001 From: till_schuetze Date: Thu, 5 Sep 2024 15:27:56 +0200 Subject: [PATCH 17/43] use new control flow in app.component.html --- src/app/app.component.html | 33 +++++++++++--------- src/app/start-page/start-page.component.html | 2 +- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/app/app.component.html b/src/app/app.component.html index eec4344fb..16248b268 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -1,20 +1,23 @@
    - - - - + @if (!isHeadlessPage && !isSimplifiedPage) { + + } + @if (screenMode === 'mobile' && !isHeadlessPage && !mapUiState?.hideUiElements) { + + } + @if (!isHeadlessPage && screenMode !== 'mobile') { + + } + @if (isDevModeActive) { + + }
    - + @if (!isHeadlessPage && !isSimplifiedPage) { + + }
    - + @if (scrollbarWidth === undefined) { + + }
    diff --git a/src/app/start-page/start-page.component.html b/src/app/start-page/start-page.component.html index 49937e956..2ebc2b70f 100644 --- a/src/app/start-page/start-page.component.html +++ b/src/app/start-page/start-page.component.html @@ -4,7 +4,7 @@
    From 4247c1484f55b91fde09f01311509506a67f82a6 Mon Sep 17 00:00:00 2001 From: till_schuetze Date: Thu, 5 Sep 2024 16:03:37 +0200 Subject: [PATCH 18/43] add aria labels to the navigation --- src/app/shared/components/navbar/navbar.component.html | 3 ++- .../support-page-navigation.component.html | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/app/shared/components/navbar/navbar.component.html b/src/app/shared/components/navbar/navbar.component.html index ff47d164d..6bdcbbe5f 100644 --- a/src/app/shared/components/navbar/navbar.component.html +++ b/src/app/shared/components/navbar/navbar.component.html @@ -1,4 +1,4 @@ - + +