From ae3f103d4b59e3fa9c1c54dbef0debd51cec9922 Mon Sep 17 00:00:00 2001 From: Brice Schaffner Date: Thu, 15 Feb 2024 06:36:53 +0100 Subject: [PATCH 01/38] PB-259: Improve topic changes performance and plConfig layers order When changing the topic we need to set clear the active layers and set a bunch of new activated layers. This was done with several dispatch which was quite inefficient. Now we use only one dispatch with the new array, this way for the default topic `ech` we gain about 500ms on development build. Also fixed a bug in the infamous plConfig of topics (used by schneesport topic) in which layers were added in reverse order. --- src/api/topics.api.js | 19 ++++++++----------- src/store/modules/layers.store.js | 18 +++++++++++++++++- .../plugins/topic-change-management.plugin.js | 13 ++----------- tests/cypress/tests-e2e/topics.cy.js | 3 ++- 4 files changed, 29 insertions(+), 24 deletions(-) diff --git a/src/api/topics.api.js b/src/api/topics.api.js index dcaf6b49e..95e23b50d 100644 --- a/src/api/topics.api.js +++ b/src/api/topics.api.js @@ -152,10 +152,7 @@ const loadTopicsFromBackend = (layersConfig) => { params.get('layers_timestamp') ), ] - if ( - Array.isArray(rawTopic.activatedLayers) && - rawTopic.activatedLayers.length > 0 - ) { + if (rawTopic.activatedLayers?.length > 0) { rawTopic.activatedLayers.forEach((layerId) => { let layer = layersConfig.find( (layer) => layer.getID() === layerId @@ -163,15 +160,15 @@ const loadTopicsFromBackend = (layersConfig) => { if (layer) { // deep copy so that we can reassign values later on // (layers come from the Vuex store so it can't be modified directly) - layer = Object.assign( - Object.create(Object.getPrototypeOf(layer)), - layer - ) + layer = layer.clone() // checking if the layer should be also visible layer.visible = - Array.isArray(rawTopic.selectedLayers) && - rawTopic.selectedLayers.indexOf(layerId) !== -1 - layersToActivate.push(layer) + rawTopic.selectedLayers?.indexOf(layerId) !== -1 ?? + false + // In the backend the layers are in the wrong order + // so we need to reverse the order here by simply adding + // the layer at the beginning of the array + layersToActivate.unshift(layer) } }) } diff --git a/src/store/modules/layers.store.js b/src/store/modules/layers.store.js index 3938c85a4..95e8011d1 100644 --- a/src/store/modules/layers.store.js +++ b/src/store/modules/layers.store.js @@ -244,7 +244,7 @@ const actions = { * * @param {String | AbstractLayer | ActiveLayerConfig} layerIdOrObject */ - async addLayer({ commit, getters }, layerIdOrObject) { + addLayer({ commit, getters }, layerIdOrObject) { // creating a clone of the config, so that we do not modify the initial config of the app // (it is possible to add one layer many times, so we want to always have the correct // default values when we add it, not the settings from the layer already added) @@ -273,6 +273,19 @@ const actions = { log.error('no layer found for payload:', layerIdOrObject) } }, + /** + * Sets the list of active layers. This replace the existing list. + * + * NOTE: the layers array is automatically deep cloned + * + * @param {[AbstractLayer]} layers List of active layers + */ + setLayers({ commit }, layers) { + commit( + 'setLayers', + layers.map((layer) => layer.clone()) + ) + }, removeLayer({ commit }, layerIdOrObject) { if (typeof layerIdOrObject === 'string') { commit('removeLayerWithId', layerIdOrObject) @@ -514,6 +527,9 @@ const mutations = { state.activeLayers = removeActiveLayerById(state, layer.getID()) state.activeLayers.push(layer) }, + setLayers(state, layers) { + state.activeLayers = layers + }, updateLayer(state, layer) { const layer2Update = getActiveLayerById(state, layer.getID()) if (layer2Update) { diff --git a/src/store/plugins/topic-change-management.plugin.js b/src/store/plugins/topic-change-management.plugin.js index af3a2b248..0e9d8dafe 100644 --- a/src/store/plugins/topic-change-management.plugin.js +++ b/src/store/plugins/topic-change-management.plugin.js @@ -38,20 +38,11 @@ const topicChangeManagementPlugin = (store) => { store.dispatch('setBackground', null) } } - // we only set/clear layers after the first setTopic has occurred (after app init) - if (!isFirstSetTopic) { - store.dispatch('clearLayers') - } + // at init, if there is no active layer yet, but the topic has some, we add them // after init we always add all layers from topic if (!isFirstSetTopic || state.layers.activeLayers.length === 0) { - // somehow topic layers are stored in reverse (top to bottom) so we swap the order before adding them - currentTopic.layersToActivate - .slice() - .reverse() - .forEach((layer) => { - store.dispatch('addLayer', layer) - }) + store.dispatch('setLayers', currentTopic.layersToActivate) } // loading topic tree loadTopicTreeForTopic( diff --git a/tests/cypress/tests-e2e/topics.cy.js b/tests/cypress/tests-e2e/topics.cy.js index 6aa4ffdc3..0766fb45b 100644 --- a/tests/cypress/tests-e2e/topics.cy.js +++ b/tests/cypress/tests-e2e/topics.cy.js @@ -8,6 +8,7 @@ describe('Topics', () => { // mimic the output of `/rest/services` endpoint let mockupTopics = {} const selectTopicWithId = (topicId) => { + cy.log(`Select topic ${topicId}`) cy.readStoreValue('state.ui').then((ui) => { // only click on the menu button if the menu is not opened yet if (!ui.showMenu) { @@ -122,7 +123,7 @@ describe('Topics', () => { const complexTopic = mockupTopics.topics[4] selectTopicWithId(complexTopic.id) // from the mocked up response above - const expectedActiveLayers = ['test.wms.layer', 'test.wmts.layer'] + const expectedActiveLayers = ['test.wmts.layer', 'test.wms.layer'] const expectedVisibleLayers = ['test.wmts.layer'] const expectedOpacity = { 'test.wmts.layer': 0.6, From 63b4a80aadc1c9f898369730e1ea24714c6eb9b0 Mon Sep 17 00:00:00 2001 From: Brice Schaffner Date: Thu, 15 Feb 2024 07:44:00 +0100 Subject: [PATCH 02/38] PB-259: Improve logging for debugging and production build --- src/store/plugins/app-readiness.plugin.js | 21 ++++++++++++++++++++- src/utils/logging.js | 7 +++++-- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/store/plugins/app-readiness.plugin.js b/src/store/plugins/app-readiness.plugin.js index 598f8434a..900669611 100644 --- a/src/store/plugins/app-readiness.plugin.js +++ b/src/store/plugins/app-readiness.plugin.js @@ -1,3 +1,6 @@ +import { ENVIRONMENT } from '@/config' +import log from '@/utils/logging' + /** * Plugin that will listen to most mutation as long as a certain state of readiness is not reached. * When the state has loaded enough data / is ready, this plugin will trigger the mutation that will @@ -12,7 +15,10 @@ * @param {Vuex.Store} store */ const appReadinessPlugin = (store) => { - store.subscribe((_, state) => { + const unsubscribe = store.subscribe((mutation, state) => { + // Log all mutations for debugging + log.debug(`[store mutation]: type=${mutation.type} payload=`, mutation.payload) + // if app is not ready yet, we go through the checklist if (!state.app.isReady) { if ( @@ -22,10 +28,23 @@ const appReadinessPlugin = (store) => { state.topics.config.length > 0 ) { store.dispatch('setAppIsReady') + + // In production build we are not interested anymore in the mutation logs + // therefore unsubscribe here + if (ENVIRONMENT === 'production') { + unsubscribe() + } } } // otherwise we ignore all mutations, our job is already done }) + + // only subscribe to action logs for non productive build + if (ENVIRONMENT !== 'production') { + store.subscribeAction((action, _state) => { + log.debug(`[store action]: type=${action.type} payload=`, action.payload) + }) + } } export default appReadinessPlugin diff --git a/src/utils/logging.js b/src/utils/logging.js index c1a5efa60..dcf12fabf 100644 --- a/src/utils/logging.js +++ b/src/utils/logging.js @@ -24,8 +24,11 @@ export const LogLevel = { * @param {...any} message */ const log = (level, ...message) => { - // In production we only log errors. - if (ENVIRONMENT === 'production' && level !== LogLevel.ERROR) { + // In production we don't log debug level + if ( + ENVIRONMENT === 'production' && + [LogLevel.ERROR, LogLevel.WARNING, LogLevel.INFO].includes(level) + ) { return } From 0d508a4c19f02be5cc594cc4b31b07e52ca3ea3f Mon Sep 17 00:00:00 2001 From: Brice Schaffner Date: Thu, 15 Feb 2024 07:55:55 +0100 Subject: [PATCH 03/38] PB-265: Fix some topics (BFS, IVS, KGS, ...) Topics on the backend that only specified the selectedLayers without activatedLayers were not added. --- src/api/topics.api.js | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/src/api/topics.api.js b/src/api/topics.api.js index 95e23b50d..35664a89d 100644 --- a/src/api/topics.api.js +++ b/src/api/topics.api.js @@ -152,26 +152,27 @@ const loadTopicsFromBackend = (layersConfig) => { params.get('layers_timestamp') ), ] - if (rawTopic.activatedLayers?.length > 0) { - rawTopic.activatedLayers.forEach((layerId) => { - let layer = layersConfig.find( - (layer) => layer.getID() === layerId - ) - if (layer) { - // deep copy so that we can reassign values later on - // (layers come from the Vuex store so it can't be modified directly) - layer = layer.clone() - // checking if the layer should be also visible - layer.visible = - rawTopic.selectedLayers?.indexOf(layerId) !== -1 ?? - false - // In the backend the layers are in the wrong order - // so we need to reverse the order here by simply adding - // the layer at the beginning of the array - layersToActivate.unshift(layer) - } - }) - } + const activatedLayers = [ + ...new Set([ + ...(rawTopic.activatedLayers ?? []), + ...(rawTopic.selectedLayers ?? []), + ]), + ] + activatedLayers.forEach((layerId) => { + let layer = layersConfig.find((layer) => layer.getID() === layerId) + if (layer) { + // deep copy so that we can reassign values later on + // (layers come from the Vuex store so it can't be modified directly) + layer = layer.clone() + // checking if the layer should be also visible + layer.visible = + rawTopic.selectedLayers?.indexOf(layerId) !== -1 ?? false + // In the backend the layers are in the wrong order + // so we need to reverse the order here by simply adding + // the layer at the beginning of the array + layersToActivate.unshift(layer) + } + }) topics.push( new Topic( topicId, From 44cf9b53b0fe7689ac0b15c4d17bffd4eca20b1b Mon Sep 17 00:00:00 2001 From: Brice Schaffner Date: Thu, 15 Feb 2024 08:45:19 +0100 Subject: [PATCH 04/38] PB-259: Fixed duplicate layers for meteoschweiz and snowsport topic Due to previous commit that set the topic layers in one dispatch, we must make sure that the layer list to set has no duplicate. --- src/api/topics.api.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/api/topics.api.js b/src/api/topics.api.js index 35664a89d..820f44304 100644 --- a/src/api/topics.api.js +++ b/src/api/topics.api.js @@ -158,6 +158,17 @@ const loadTopicsFromBackend = (layersConfig) => { ...(rawTopic.selectedLayers ?? []), ]), ] + // Filter out layers that have been already added by the infamous + // plConfig topic config that has priority, this avoid duplicate + // layers + .filter( + (layerId) => + !( + layersToActivate.findIndex( + (layer) => layer.getID() === layerId + ) !== -1 + ) + ) activatedLayers.forEach((layerId) => { let layer = layersConfig.find((layer) => layer.getID() === layerId) if (layer) { From 207ba82d68274b6e4a1d6b94e033164e239d0e4f Mon Sep 17 00:00:00 2001 From: Brice Schaffner Date: Thu, 15 Feb 2024 13:12:14 +0100 Subject: [PATCH 05/38] PB-285: Added `dispatcher` to all store actions related to the URL parsing This should also be done for all actions, but for the time being only added it to the url parameter related actions. This new generic parameter gives the possibility to do different actions in the store plugins depending on the source of the event. This avoid bulky/flaky tests using local closure flags. --- src/api/topics.api.js | 2 +- src/modules/drawing/DrawingModule.vue | 2 +- .../useKmlDataManagement.composable.js | 10 +- src/modules/i18n/components/LangButton.vue | 2 +- src/modules/map/components/CompareSlider.vue | 5 +- .../map/components/cesium/CesiumMap.vue | 8 +- .../backgroundSelector/BackgroundSelector.vue | 5 +- .../components/openlayers/OpenLayersMap.vue | 2 +- .../openlayers/utils/map-views.composable.js | 4 +- .../menu/components/LayerCatalogueItem.vue | 17 ++- .../activeLayers/MenuActiveLayersList.vue | 13 ++- .../MenuActiveLayersListItemTimeSelector.vue | 3 + .../advancedTools/ImportFile/utils.js | 4 +- .../advancedTools/MenuAdvancedToolsList.vue | 13 ++- .../menu/components/debug/DebugToolbar.vue | 9 +- .../components/debug/Toggle3DLayerButton.vue | 6 +- src/modules/menu/components/menu/MenuTray.vue | 2 +- .../toolboxRight/Toggle3dButton.vue | 2 +- .../components/topics/MenuTopicSection.vue | 2 +- .../storeSync/CameraParamConfig.class.js | 9 +- .../CompareSliderParamConfig.class.js | 18 ++- .../storeSync/CrossHairParamConfig.class.js | 24 +++- .../storeSync/LayerParamConfig.class.js | 34 +++++- .../storeSync/PositionParamConfig.class.js | 6 +- .../QueryToStoreOnlyParamConfig.class.js | 10 +- .../storeSync/SimpleUrlParamConfig.class.js | 10 +- src/router/storeSync/ZoomParamConfig.class.js | 9 +- .../storeSync/abstractParamConfig.class.js | 4 + src/router/storeSync/storeSync.config.js | 4 +- .../storeSync/storeSync.routerPlugin.js | 5 +- .../modules/__tests__/layers.store.spec.js | 67 ++++++----- .../modules/__tests__/zoom.store.spec.js | 27 +++-- src/store/modules/app.store.js | 8 +- src/store/modules/cesium.store.js | 18 +-- src/store/modules/geolocation.store.js | 3 + src/store/modules/i18n.store.js | 10 +- src/store/modules/layers.store.js | 109 +++++++++--------- src/store/modules/position.store.js | 63 +++++----- src/store/modules/search.store.js | 30 +++-- src/store/modules/topics.store.js | 45 ++++---- src/store/modules/ui.store.js | 34 +++--- .../plugins/2d-to-3d-management.plugin.js | 22 +++- src/store/plugins/app-readiness.plugin.js | 12 +- src/store/plugins/external-layers.plugin.js | 6 +- .../plugins/geolocation-management.plugin.js | 12 +- .../load-geojson-style-and-data.plugin.js | 6 +- src/store/plugins/load-gpx-data.plugin.js | 6 +- src/store/plugins/load-kml-data.plugin.js | 6 +- .../load-layersconfig-on-lang-change.js | 27 +++-- src/store/plugins/sync-camera-lonlatzoom.js | 18 +-- .../plugins/topic-change-management.plugin.js | 27 ++++- tests/cypress/tests-e2e/geodesicDrawing.cy.js | 2 +- tests/cypress/tests-e2e/mouseposition.cy.js | 2 +- 53 files changed, 510 insertions(+), 294 deletions(-) diff --git a/src/api/topics.api.js b/src/api/topics.api.js index 820f44304..bca69f44a 100644 --- a/src/api/topics.api.js +++ b/src/api/topics.api.js @@ -159,7 +159,7 @@ const loadTopicsFromBackend = (layersConfig) => { ]), ] // Filter out layers that have been already added by the infamous - // plConfig topic config that has priority, this avoid duplicate + // plConfig topic config that has priority, this avoid duplicate // layers .filter( (layerId) => diff --git a/src/modules/drawing/DrawingModule.vue b/src/modules/drawing/DrawingModule.vue index e0f9ac3ba..acd2b3a26 100644 --- a/src/modules/drawing/DrawingModule.vue +++ b/src/modules/drawing/DrawingModule.vue @@ -156,7 +156,7 @@ async function closeDrawing() { await saveDrawing(false) } - await store.dispatch('toggleDrawingOverlay') + await store.dispatch('toggleDrawingOverlay', { dispatcher: 'DrawingModule.vue' }) await store.dispatch('setShowLoadingBar', false) } diff --git a/src/modules/drawing/useKmlDataManagement.composable.js b/src/modules/drawing/useKmlDataManagement.composable.js index d1d6c7755..f31ad78ef 100644 --- a/src/modules/drawing/useKmlDataManagement.composable.js +++ b/src/modules/drawing/useKmlDataManagement.composable.js @@ -71,9 +71,15 @@ export default function useSaveKmlOnChange(drawingLayerDirectReference) { // Meaning we must remove the old one from the layers; it will otherwise be there twice // (once the pristine "old" KML, and once the new copy) if (activeKmlLayer.value) { - await store.dispatch('removeLayer', activeKmlLayer.value) + await store.dispatch('removeLayer', { + layer: activeKmlLayer.value, + dispatcher: 'useKmlDataManagement.composable/saveDrawing', + }) } - await store.dispatch('addLayer', kmlLayer) + await store.dispatch('addLayer', { + layer: kmlLayer, + dispatcher: 'useKmlDataManagement.composable/saveDrawing', + }) saveState.value = DrawingState.SAVED } else { // if a KMLLayer is already defined, we update it diff --git a/src/modules/i18n/components/LangButton.vue b/src/modules/i18n/components/LangButton.vue index f45920af2..72109de4f 100644 --- a/src/modules/i18n/components/LangButton.vue +++ b/src/modules/i18n/components/LangButton.vue @@ -41,7 +41,7 @@ export default { ...mapActions(['setLang']), changeLang() { log.debug('switching locale', this.lang) - this.setLang(this.lang) + this.setLang({ value: this.lang, dispatcher: 'LangButton.vue' }) }, }, } diff --git a/src/modules/map/components/CompareSlider.vue b/src/modules/map/components/CompareSlider.vue index af77fb8bb..18480c7e7 100644 --- a/src/modules/map/components/CompareSlider.vue +++ b/src/modules/map/components/CompareSlider.vue @@ -117,7 +117,10 @@ function releaseSlider() { window.removeEventListener('mouseup', releaseSlider) window.removeEventListener('touchend', releaseSlider) compareSliderOffset.value = 0 - store.dispatch('setCompareRatio', compareRatio.value) + store.dispatch('setCompareRatio', { + value: compareRatio.value, + dispatcher: 'CompareSlider.vue', + }) } diff --git a/src/modules/map/components/cesium/CesiumMap.vue b/src/modules/map/components/cesium/CesiumMap.vue index 73ac0a6a3..248334a53 100644 --- a/src/modules/map/components/cesium/CesiumMap.vue +++ b/src/modules/map/components/cesium/CesiumMap.vue @@ -281,7 +281,7 @@ export default { } }, unmounted() { - this.setCameraPosition({ position: null, source: 'CesiumMap unmount' }) + this.setCameraPosition({ position: null, dispatcher: 'CesiumMap.vue/unmount' }) this.viewer.destroy() delete this.viewer }, @@ -397,7 +397,7 @@ export default { // reduce screen space error to downgrade visual quality but speed up tests globe.maximumScreenSpaceError = 30 } - this.mapModuleReady() + this.mapModuleReady({ dispatcher: 'CesiumMap.vue' }) }, highlightSelectedFeatures() { const [firstFeature] = this.selectedFeatures @@ -472,7 +472,7 @@ export default { pitch: parseFloat(CesiumMath.toDegrees(camera.pitch).toFixed(0)), roll: parseFloat(CesiumMath.toDegrees(camera.roll).toFixed(0)), }, - source: 'CesiumMap camera move end', + dispatcher: 'CesiumMap.vue/onCameraMoveEnd', }) }, getCoordinateAtScreenCoordinate(x, y) { @@ -594,7 +594,7 @@ export default { const lon = CesiumMath.toDegrees(cameraTargetCartographic.longitude) this.setCenter({ center: proj4(WGS84.epsg, this.projection.epsg, [lon, lat]), - source: 'CesiumMap', + dispatcher: 'CesiumMap.vue', }) } }, diff --git a/src/modules/map/components/footer/backgroundSelector/BackgroundSelector.vue b/src/modules/map/components/footer/backgroundSelector/BackgroundSelector.vue index 08577e3c8..87b46d8b0 100644 --- a/src/modules/map/components/footer/backgroundSelector/BackgroundSelector.vue +++ b/src/modules/map/components/footer/backgroundSelector/BackgroundSelector.vue @@ -44,7 +44,10 @@ const sortedBackgroundLayersWithVoid = computed(() => ) function selectBackground(backgroundLayer) { - store.dispatch('setBackground', backgroundLayer) + store.dispatch('setBackground', { + value: backgroundLayer, + dispatcher: 'BackgroundSelector.vue', + }) } diff --git a/src/modules/map/components/openlayers/OpenLayersMap.vue b/src/modules/map/components/openlayers/OpenLayersMap.vue index bb857b736..6886b759f 100644 --- a/src/modules/map/components/openlayers/OpenLayersMap.vue +++ b/src/modules/map/components/openlayers/OpenLayersMap.vue @@ -53,7 +53,7 @@ if (IS_TESTING_WITH_CYPRESS) { map.once('rendercomplete', () => { // This is needed for cypress in order to start the tests only // when openlayer is rendered otherwise some tests will fail. - store.dispatch('mapModuleReady') + store.dispatch('mapModuleReady', { dispatcher: 'OpenLayersMap.vue' }) log.info('Openlayer map rendered') }) diff --git a/src/modules/map/components/openlayers/utils/map-views.composable.js b/src/modules/map/components/openlayers/utils/map-views.composable.js index b7e90aa34..cac5bf2fc 100644 --- a/src/modules/map/components/openlayers/utils/map-views.composable.js +++ b/src/modules/map/components/openlayers/utils/map-views.composable.js @@ -80,11 +80,11 @@ export default function useViewBasedOnProjection(map) { if (currentView) { const [x, y] = currentView.getCenter() if (x !== center.value[0] || y !== center.value[1]) { - store.dispatch('setCenter', { center: { x, y }, source: 'OpenLayers' }) + store.dispatch('setCenter', { center: { x, y }, dispatcher: 'OpenLayers.vue' }) } const currentZoom = round(currentView.getZoom(), 3) if (currentZoom && currentZoom !== zoom.value) { - store.dispatch('setZoom', { zoom: currentZoom, source: 'OpenLayers' }) + store.dispatch('setZoom', { zoom: currentZoom, dispatcher: 'OpenLayers.vue' }) } const currentRotation = currentView.getRotation() if (currentRotation !== rotation.value) { diff --git a/src/modules/menu/components/LayerCatalogueItem.vue b/src/modules/menu/components/LayerCatalogueItem.vue index 66029bb29..c23e3f0fa 100644 --- a/src/modules/menu/components/LayerCatalogueItem.vue +++ b/src/modules/menu/components/LayerCatalogueItem.vue @@ -21,6 +21,8 @@ import { LV95 } from '@/utils/coordinates/coordinateSystems' import { ActiveLayerConfig } from '@/utils/layerUtils' import log from '@/utils/logging' +const STORE_DISPATCHER_LAYER_CATALOGUE_ITEM = 'LayerCatalogueItem.vue' + const props = defineProps({ item: { type: AbstractLayer, @@ -118,11 +120,20 @@ function addRemoveLayer() { // if this is a group of a layer then simply add it to the map const matchingActiveLayer = store.getters.getActiveLayerById(item.value.getID()) if (matchingActiveLayer) { - store.dispatch('removeLayer', matchingActiveLayer) + store.dispatch('removeLayer', { + layer: matchingActiveLayer, + dispatcher: STORE_DISPATCHER_LAYER_CATALOGUE_ITEM, + }) } else if (item.value.isExternal) { - store.dispatch('addLayer', item.value) + store.dispatch('addLayer', { + layer: item.value, + dispatcher: STORE_DISPATCHER_LAYER_CATALOGUE_ITEM, + }) } else { - store.dispatch('addLayer', new ActiveLayerConfig(item.value.getID(), true)) + store.dispatch('addLayer', { + layerConfig: new ActiveLayerConfig(item.value.getID(), true), + dispatcher: STORE_DISPATCHER_LAYER_CATALOGUE_ITEM, + }) } } diff --git a/src/modules/menu/components/activeLayers/MenuActiveLayersList.vue b/src/modules/menu/components/activeLayers/MenuActiveLayersList.vue index cb0c9551b..3c987cdb3 100644 --- a/src/modules/menu/components/activeLayers/MenuActiveLayersList.vue +++ b/src/modules/menu/components/activeLayers/MenuActiveLayersList.vue @@ -39,6 +39,8 @@ import LayerLegendPopup from '@/modules/menu/components/LayerLegendPopup.vue' import MenuActiveLayersListItem from './MenuActiveLayersListItem.vue' +const STORE_DISPATCHER_MENU_ACTIVE_LAYERS_LIST = 'MenuActiveLayersList.vue' + /** * Component that maps the active layers from the state to the menu (and also forwards user * interactions to the state) @@ -82,7 +84,10 @@ export default { 'setOverlayShouldBeFront', ]), onRemoveLayer(layerId) { - this.removeLayer(layerId) + this.removeLayer({ + layerId: layerId, + dispatcher: STORE_DISPATCHER_MENU_ACTIVE_LAYERS_LIST, + }) }, onToggleLayerVisibility(layerId) { this.toggleLayerVisibility(layerId) @@ -96,7 +101,11 @@ export default { } }, onOpacityChange(layerId, opacity) { - this.setLayerOpacity({ layerId, opacity }) + this.setLayerOpacity({ + layerId, + opacity, + dispatcher: STORE_DISPATCHER_MENU_ACTIVE_LAYERS_LIST, + }) }, isFirstLayer(layerId) { return this.activeLayers[0].getID() === layerId diff --git a/src/modules/menu/components/activeLayers/MenuActiveLayersListItemTimeSelector.vue b/src/modules/menu/components/activeLayers/MenuActiveLayersListItemTimeSelector.vue index c0de82961..47f713522 100644 --- a/src/modules/menu/components/activeLayers/MenuActiveLayersListItemTimeSelector.vue +++ b/src/modules/menu/components/activeLayers/MenuActiveLayersListItemTimeSelector.vue @@ -50,6 +50,8 @@ import { YEAR_TO_DESCRIBE_ALL_OR_CURRENT_DATA, } from '@/api/layers/LayerTimeConfigEntry.class' +const STORE_DISPATCHER_MENU_ACTIVE_LAYERS_LIST_TIME = 'MenuActiveLayersListItemTimeSelector.vue' + export default { props: { layerId: { @@ -119,6 +121,7 @@ export default { this.setTimedLayerCurrentYear({ layerId: this.layerId, year, + dispatcher: STORE_DISPATCHER_MENU_ACTIVE_LAYERS_LIST_TIME, }) }, hidePopover() { diff --git a/src/modules/menu/components/advancedTools/ImportFile/utils.js b/src/modules/menu/components/advancedTools/ImportFile/utils.js index 9c2440f99..cafad047f 100644 --- a/src/modules/menu/components/advancedTools/ImportFile/utils.js +++ b/src/modules/menu/components/advancedTools/ImportFile/utils.js @@ -48,7 +48,7 @@ export function handleFileContent(store, content, source) { throw new OutOfBoundsError(`KML out of projection bounds: ${extent}`) } store.dispatch('zoomToExtent', projectedExtent) - store.dispatch('addLayer', layer) + store.dispatch('addLayer', { layer, dispatcher: 'ImportFile.vue/kml' }) } else if (isGpx(content)) { const gpxParser = new GPX() const metadata = gpxParser.readMetadata(content) @@ -62,7 +62,7 @@ export function handleFileContent(store, content, source) { throw new OutOfBoundsError(`GPX out of projection bounds: ${extent}`) } store.dispatch('zoomToExtent', projectedExtent) - store.dispatch('addLayer', layer) + store.dispatch('addLayer', { layer, dispacther: 'ImportFile.vue/gpx' }) } else { throw new Error(`Unsupported file ${source} content`) } diff --git a/src/modules/menu/components/advancedTools/MenuAdvancedToolsList.vue b/src/modules/menu/components/advancedTools/MenuAdvancedToolsList.vue index f8d0016fd..edb211da9 100644 --- a/src/modules/menu/components/advancedTools/MenuAdvancedToolsList.vue +++ b/src/modules/menu/components/advancedTools/MenuAdvancedToolsList.vue @@ -7,6 +7,9 @@ import ImportCatalogue from '@/modules/menu/components/advancedTools/ImportCatal import ImportFile from '@/modules/menu/components/advancedTools/ImportFile/ImportFile.vue' import MenuAdvancedToolsListItem from '@/modules/menu/components/advancedTools/MenuAdvancedToolsListItem.vue' import ModalWithBackdrop from '@/utils/components/ModalWithBackdrop.vue' + +const STORE_DISPATCHER_MENU_ADVANCED_TOOL = 'MenuAdvancedToolsList.vue' + const props = defineProps({ compact: { type: Boolean, @@ -29,9 +32,15 @@ function onToggleImportCatalogue() { function onToggleCompareSlider() { if (storeCompareRatio.value === null) { // this allows us to set a value to the compare ratio, in case there was none - store.dispatch('setCompareRatio', 0.5) + store.dispatch('setCompareRatio', { + value: 0.5, + dispatcher: STORE_DISPATCHER_MENU_ADVANCED_TOOL, + }) } - store.dispatch('setCompareSliderActive', !isCompareSliderActive.value) + store.dispatch('setCompareSliderActive', { + value: !isCompareSliderActive.value, + dispatcher: STORE_DISPATCHER_MENU_ADVANCED_TOOL, + }) } function onToggleImportFile() { if (!showImportFile.value && isPhoneMode.value) { diff --git a/src/modules/menu/components/debug/DebugToolbar.vue b/src/modules/menu/components/debug/DebugToolbar.vue index 66ede5a0f..28c8564db 100644 --- a/src/modules/menu/components/debug/DebugToolbar.vue +++ b/src/modules/menu/components/debug/DebugToolbar.vue @@ -6,6 +6,8 @@ import { useStore } from 'vuex' import Toggle3DLayerButton from '@/modules/menu/components/debug/Toggle3DLayerButton.vue' import { LV95, WEBMERCATOR } from '@/utils/coordinates/coordinateSystems' +const STORE_DISPATCHER_DEBUG_TB = 'DebugToolbar.vue' + const store = useStore() const showDebugTool = ref(false) @@ -21,9 +23,12 @@ const isMercatorTheCurrentProjection = computed( function toggleProjection() { if (isMercatorTheCurrentProjection.value) { - store.dispatch('setProjection', LV95) + store.dispatch('setProjection', { value: LV95, dispatcher: STORE_DISPATCHER_DEBUG_TB }) } else { - store.dispatch('setProjection', WEBMERCATOR) + store.dispatch('setProjection', { + value: WEBMERCATOR, + dispatcher: STORE_DISPATCHER_DEBUG_TB, + }) } } function toggleShowTileDebugInfo() { diff --git a/src/modules/menu/components/debug/Toggle3DLayerButton.vue b/src/modules/menu/components/debug/Toggle3DLayerButton.vue index ee04cc5dc..b8a6fb77d 100644 --- a/src/modules/menu/components/debug/Toggle3DLayerButton.vue +++ b/src/modules/menu/components/debug/Toggle3DLayerButton.vue @@ -7,8 +7,10 @@ const store = useStore() const showBuildings = computed(() => store.state.cesium.showBuildings) const showVegetation = computed(() => store.state.cesium.showVegetation) -const toggleShow3dVegetation = () => store.dispatch('toggleShow3dVegetation') -const toggleShow3dBuildings = () => store.dispatch('toggleShow3dBuildings') +const toggleShow3dVegetation = () => + store.dispatch('toggleShow3dVegetation', { dispatcher: 'Toggle3DLayerButton.vue' }) +const toggleShow3dBuildings = () => + store.dispatch('toggleShow3dBuildings', { dispatcher: 'Toggle3DLayerButton.vue' })