From 3cafe2cbe5c62905271528c2a3d84c097c83cf11 Mon Sep 17 00:00:00 2001 From: Pascal Barth Date: Fri, 1 Nov 2024 09:46:37 +0100 Subject: [PATCH 1/2] PB-1116 : move drawing name to store there was some bugs by keeping it only in the toolbox. For instance deleting the drawing and adding new features would not give a correct drawing name. --- src/api/layers/KMLLayer.class.js | 6 +++ src/modules/drawing/DrawingModule.vue | 7 +++ .../drawing/components/DrawingToolbox.vue | 48 +++++++++++-------- .../useKmlDataManagement.composable.js | 35 +++++++------- src/store/modules/drawing.store.js | 12 +++++ 5 files changed, 71 insertions(+), 37 deletions(-) diff --git a/src/api/layers/KMLLayer.class.js b/src/api/layers/KMLLayer.class.js index 66a836d9c..884f514eb 100644 --- a/src/api/layers/KMLLayer.class.js +++ b/src/api/layers/KMLLayer.class.js @@ -81,6 +81,12 @@ export default class KMLLayer extends AbstractLayer { this.kmlMetadata = kmlMetadata if (kmlData) { this.name = parseKmlName(kmlData) + if (!this.name || this.name === '') { + this.name = isLocalFile + ? kmlFileUrl + : // only keeping what is after the last slash + kmlFileUrl.split('/').pop() + } this.isLoading = false } else { this.isLoading = true diff --git a/src/modules/drawing/DrawingModule.vue b/src/modules/drawing/DrawingModule.vue index ef0c2871d..7a94ad7c5 100644 --- a/src/modules/drawing/DrawingModule.vue +++ b/src/modules/drawing/DrawingModule.vue @@ -2,6 +2,7 @@ import VectorLayer from 'ol/layer/Vector' import VectorSource from 'ol/source/Vector' import { computed, inject, onBeforeUnmount, onMounted, provide, ref, watch } from 'vue' +import { useI18n } from 'vue-i18n' import { useStore } from 'vuex' import { IS_TESTING_WITH_CYPRESS } from '@/config/staging.config' @@ -22,6 +23,7 @@ const olMap = inject('olMap') const drawingInteractions = ref(null) const isNewDrawing = ref(true) +const i18n = useI18n() const store = useStore() const availableIconSets = computed(() => store.state.drawing.iconSets) const projection = computed(() => store.state.position.projection) @@ -130,6 +132,11 @@ onMounted(() => { if (hasKml.value) { isNewDrawing.value = false addKmlToDrawing() + } else { + store.dispatch('setDrawingName', { + name: i18n.t('draw_layer_label'), + ...dispatcher, + }) } olMap.addLayer(drawingLayer) diff --git a/src/modules/drawing/components/DrawingToolbox.vue b/src/modules/drawing/components/DrawingToolbox.vue index ab8583ed2..7d6d57dc9 100644 --- a/src/modules/drawing/components/DrawingToolbox.vue +++ b/src/modules/drawing/components/DrawingToolbox.vue @@ -7,14 +7,14 @@ import { useStore } from 'vuex' import { EditableFeatureTypes } from '@/api/features/EditableFeature.class' import DrawingExporter from '@/modules/drawing/components/DrawingExporter.vue' +import DrawingHeader from '@/modules/drawing/components/DrawingHeader.vue' import DrawingToolboxButton from '@/modules/drawing/components/DrawingToolboxButton.vue' import SharePopup from '@/modules/drawing/components/SharePopup.vue' import { DrawingState } from '@/modules/drawing/lib/export-utils' import useSaveKmlOnChange from '@/modules/drawing/useKmlDataManagement.composable' import ModalWithBackdrop from '@/utils/components/ModalWithBackdrop.vue' -import { useTippyTooltip } from '@/utils/composables/useTippyTooltip.js' - -import DrawingHeader from './DrawingHeader.vue' +import { useTippyTooltip } from '@/utils/composables/useTippyTooltip' +import debounce from '@/utils/debounce' const dispatcher = { dispatcher: 'DrawingToolbox.vue' } @@ -39,7 +39,8 @@ const isDrawingLineOrMeasure = computed(() => ) ) const activeKmlLayer = computed(() => store.getters.activeKmlLayer) -const drawingName = ref(activeKmlLayer.value?.name || i18n.t('draw_layer_label')) +const drawingName = computed(() => store.state.drawing.name) +const editableDrawingName = ref(drawingName.value) const isDrawingStateError = computed(() => saveState.value < 0) /** Return a different translation key depending on the saving status */ const drawingStateMessage = computed(() => { @@ -64,7 +65,7 @@ function onCloseClearConfirmation(confirmed) { store.dispatch('clearDrawingFeatures', dispatcher) store.dispatch('clearAllSelectedFeatures', dispatcher) drawingLayer.getSource().clear() - debounceSaveDrawing({ drawingName: drawingName.value }) + debounceSaveDrawing() store.dispatch('setDrawingMode', { mode: null, ...dispatcher }) } } @@ -78,15 +79,11 @@ onMounted(() => { } }) -watch(drawingName, () => { - sanitizeDrawingName() - debounceSaveDrawing({ - // Lowering the risk of the user changing the name and leaving the drawing module without the name being saved. - // It is terrible design that this can occur, but moving the drawing name management other places raises the complexity tenfold - // so that is a trade-off we can live with. - debounceTime: 500, - drawingName: drawingName.value.trim(), - }) +watch(drawingName, (newName) => { + editableDrawingName.value = newName +}) +watch(editableDrawingName, () => { + debounceSaveDrawingName() }) watch(activeKmlLayer, () => { @@ -96,15 +93,10 @@ watch(activeKmlLayer, () => { } }) -function sanitizeDrawingName() { - drawingName.value = DOMPurify.sanitize(drawingName.value, { - USE_PROFILES: { xml: true }, - }) -} - function closeDrawing() { emits('closeDrawing') } + function selectDrawingMode(drawingMode) { store.dispatch('setDrawingMode', { mode: drawingMode, ...dispatcher }) } @@ -112,6 +104,20 @@ function selectDrawingMode(drawingMode) { function onDeleteLastPoint() { emits('removeLastPoint') } + +const debounceSaveDrawingName = debounce(async () => { + // sanitizing to avoid any XSS vector + editableDrawingName.value = DOMPurify.sanitize(editableDrawingName.value, { + USE_PROFILES: { xml: true }, + }).trim() + if (editableDrawingName.value !== drawingName.value) { + await store.dispatch('setDrawingName', { + name: editableDrawingName.value, + ...dispatcher, + }) + debounceSaveDrawing() + } +}, 200)