Skip to content

Commit d72f8c7

Browse files
authored
Merge pull request #710 from geoadmin/develop
New Release v1.11.0 - #minor
2 parents 6f244c4 + d40bafd commit d72f8c7

File tree

70 files changed

+1106
-659
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+1106
-659
lines changed

src/api/icon.api.js

+20-21
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ export class DrawingIcon {
174174
* @returns {Promise<DrawingIconSet[]>}
175175
*/
176176
export async function loadAllIconSetsFromBackend() {
177+
const setPromises = []
177178
const sets = []
178179
try {
179180
const rawSets = (await axios.get(`${API_SERVICES_BASE_URL}icons/sets`)).data.items
@@ -185,10 +186,10 @@ export async function loadAllIconSetsFromBackend() {
185186
rawSet.template_url
186187
)
187188
// retrieving all icons for this icon set
188-
await loadIconsForIconSet(iconSet)
189-
189+
setPromises.push(loadIconsForIconSet(iconSet))
190190
sets.push(iconSet)
191191
}
192+
await Promise.all(setPromises)
192193
} catch (error) {
193194
log.error(`Failed to retrieve icons sets: ${error}`)
194195
}
@@ -201,23 +202,21 @@ export async function loadAllIconSetsFromBackend() {
201202
* @param {DrawingIconSet} iconSet
202203
* @returns {Promise} Promise resolving when all icons have been attached to the icon set
203204
*/
204-
function loadIconsForIconSet(iconSet) {
205-
return axios
206-
.get(iconSet.iconsURL)
207-
.then((rawIcons) => {
208-
iconSet.icons = rawIcons.data.items.map(
209-
(rawIcon) =>
210-
new DrawingIcon(
211-
rawIcon.name,
212-
rawIcon.url,
213-
rawIcon.template_url,
214-
iconSet.name,
215-
rawIcon.anchor
216-
)
217-
)
218-
})
219-
.catch((error) => {
220-
log.error('Error getting icons for icon set', iconSet)
221-
return Promise.reject(error)
222-
})
205+
async function loadIconsForIconSet(iconSet) {
206+
try {
207+
const rawIcons = await axios.get(iconSet.iconsURL)
208+
209+
iconSet.icons = rawIcons.data.items.map(
210+
(rawIcon) =>
211+
new DrawingIcon(
212+
rawIcon.name,
213+
rawIcon.url,
214+
rawIcon.template_url,
215+
iconSet.name,
216+
rawIcon.anchor
217+
)
218+
)
219+
} catch (error) {
220+
log.error('Error getting icons for icon set', iconSet)
221+
}
223222
}

src/modules/drawing/DrawingModule.vue

+11-2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import DrawingToolbox from '@/modules/drawing/components/DrawingToolbox.vue'
1010
import DrawingTooltip from '@/modules/drawing/components/DrawingTooltip.vue'
1111
import { DrawingState } from '@/modules/drawing/lib/export-utils'
1212
import useKmlDataManagement from '@/modules/drawing/useKmlDataManagement.composable'
13+
import { FeatureInfoPositions } from '@/store/modules/ui.store'
1314
import { getIcon, parseIconUrl } from '@/utils/kmlUtils'
1415
import log from '@/utils/logging'
1516
@@ -26,7 +27,7 @@ const projection = computed(() => store.state.position.projection)
2627
const activeKmlLayer = computed(() => store.getters.activeKmlLayer)
2728
const featureIds = computed(() => store.state.drawing.featureIds)
2829
const isDrawingEmpty = computed(() => store.getters.isDrawingEmpty)
29-
30+
const noFeatureInfo = computed(() => store.getters.noFeatureInfo)
3031
const drawingLayer = new VectorLayer({
3132
source: createSourceForProjection(),
3233
zIndex: 9999,
@@ -86,8 +87,16 @@ watch(availableIconSets, () => {
8687
})
8788
8889
onMounted(() => {
89-
// if icons have not yet been loaded, we do so
90+
if (noFeatureInfo.value) {
91+
// Left clicking while in drawing mode has its own logic not covered in click-on-map-management.plugin.js
92+
// We force the featureInfo to be visible in drawing mode
93+
store.dispatch('setFeatureInfoPosition', {
94+
featureInfo: FeatureInfoPositions.DEFAULT,
95+
...dispatcher,
96+
})
97+
}
9098
if (availableIconSets.value.length === 0) {
99+
// if icons have not yet been loaded, we do so
91100
store.dispatch('loadAvailableIconSets', dispatcher)
92101
}
93102

src/modules/drawing/useKmlDataManagement.composable.js

+9-3
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,10 @@ export default function useSaveKmlOnChange(drawingLayerDirectReference) {
5151

5252
async function saveDrawing(retryOnError = true) {
5353
try {
54-
log.debug(`Save drawing retryOnError ${retryOnError}`)
55-
clearTimeout(differSaveDrawingTimeout)
54+
log.debug(
55+
`Save drawing retryOnError ${retryOnError}, differSaveDrawing=${differSaveDrawingTimeout}`
56+
)
57+
clearPendingSaveDrawing()
5658
saveState.value = DrawingState.SAVING
5759
const kmlData = generateKmlString(
5860
projection.value,
@@ -109,7 +111,10 @@ export default function useSaveKmlOnChange(drawingLayerDirectReference) {
109111
}
110112

111113
async function debounceSaveDrawing({ debounceTime = 2000, retryOnError = true } = {}) {
112-
clearTimeout(differSaveDrawingTimeout)
114+
log.debug(
115+
`Debouncing save drawing debounceTime=${debounceTime} differSaveDrawingTimeout=${differSaveDrawingTimeout}`
116+
)
117+
clearPendingSaveDrawing()
113118
willModify()
114119
if (debounceTime > 0) {
115120
await new Promise((resolve) => {
@@ -132,6 +137,7 @@ export default function useSaveKmlOnChange(drawingLayerDirectReference) {
132137

133138
function clearPendingSaveDrawing() {
134139
clearTimeout(differSaveDrawingTimeout)
140+
differSaveDrawingTimeout = null
135141
}
136142

137143
/**

src/modules/infobox/InfoboxModule.vue

+29-36
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { computed, nextTick, ref, watch } from 'vue'
44
import { useStore } from 'vuex'
55
66
import { EditableFeatureTypes } from '@/api/features/EditableFeature.class'
7+
import { FeatureInfoPositions } from '@/store/modules/ui.store'
78
import promptUserToPrintHtmlContent from '@/utils/print'
89
910
import FeatureCombo from './components/FeatureCombo.vue'
@@ -17,55 +18,47 @@ const content = ref(null)
1718
const store = useStore()
1819
1920
const selectedFeatures = computed(() => store.state.features.selectedFeatures)
20-
const floatingTooltip = computed(() => store.state.ui.floatingTooltip)
21+
const bottomPanelFeatureInfo = computed(() => store.getters.bottomPanelFeatureInfo)
22+
const tooltipFeatureInfo = computed(() => store.getters.tooltipFeatureInfo)
2123
const showDrawingOverlay = computed(() => store.state.ui.showDrawingOverlay)
2224
const projection = computed(() => store.state.position.projection)
2325
2426
const selectedFeature = computed(() => selectedFeatures.value[0])
2527
26-
const isEdit = computed(() => !floatingTooltip.value && selectedFeature.value?.isEditable)
27-
const isList = computed(
28-
() => !floatingTooltip.value && !isEdit.value && selectedFeatures.value.length > 0
29-
)
30-
const showElevationProfile = computed(
31-
() =>
32-
selectedFeature.value &&
33-
(selectedFeature.value.featureType === EditableFeatureTypes.MEASURE ||
34-
(selectedFeature.value.featureType === EditableFeatureTypes.LINEPOLYGON &&
35-
floatingTooltip.value))
36-
)
37-
const isCombo = computed(
38-
() =>
39-
isEdit.value &&
40-
[EditableFeatureTypes.LINEPOLYGON, EditableFeatureTypes.MEASURE].includes(
41-
selectedFeature.value.featureType
42-
)
43-
)
44-
const showContainer = computed(
45-
() => isList.value || isEdit.value || showElevationProfile.value || isCombo.value
46-
)
47-
const showFloatingToggle = computed(
48-
() =>
49-
isList.value ||
50-
(isEdit.value && !showElevationProfile.value) ||
51-
(isCombo.value && !floatingTooltip.value)
28+
const isEdit = computed(() => selectedFeature.value?.isEditable)
29+
30+
const showElevationProfile = computed(() =>
31+
[EditableFeatureTypes.LINEPOLYGON, EditableFeatureTypes.MEASURE].includes(
32+
selectedFeature.value?.featureType
33+
)
5234
)
5335
36+
const showContainer = computed(() => {
37+
return (
38+
selectedFeatures.value.length > 0 &&
39+
(bottomPanelFeatureInfo.value || (showElevationProfile.value && tooltipFeatureInfo.value))
40+
)
41+
})
42+
const showTooltipToggle = computed(() => bottomPanelFeatureInfo.value)
43+
5444
watch(selectedFeatures, (features) => {
5545
if (features.length === 0) {
5646
return
5747
}
5848
showContent.value = true
5949
nextTick(() => {
60-
content.value.scrollTo(0, 0)
50+
content.value?.scrollTo(0, 0)
6151
})
6252
})
6353
6454
function onToggleContent() {
6555
showContent.value = !showContent.value
6656
}
67-
function onToggleFloating() {
68-
store.dispatch('toggleFloatingTooltip', dispatcher)
57+
function setTooltipInfoPosition() {
58+
store.dispatch('setFeatureInfoPosition', {
59+
featureInfo: FeatureInfoPositions.TOOLTIP,
60+
...dispatcher,
61+
})
6962
}
7063
function onPrint() {
7164
promptUserToPrintHtmlContent(content.value)
@@ -76,13 +69,13 @@ function onClose() {
7669
</script>
7770
7871
<template>
79-
<div v-show="showContainer" class="infobox card rounded-0" data-cy="infobox" @contextmenu.stop>
72+
<div v-if="showContainer" class="infobox card rounded-0" data-cy="infobox" @contextmenu.stop>
8073
<div class="infobox-header card-header d-flex justify-content-end" data-cy="infobox-header">
8174
<button
82-
v-if="showFloatingToggle"
75+
v-if="showTooltipToggle"
8376
class="btn btn-light btn-sm d-flex align-items-center"
8477
data-cy="infobox-toggle-floating"
85-
@click.stop="onToggleFloating"
78+
@click.stop="setTooltipInfoPosition"
8679
>
8780
<FontAwesomeIcon icon="caret-up" />
8881
</button>
@@ -108,15 +101,15 @@ function onClose() {
108101
109102
<div v-show="showContent" ref="content" class="infobox-content" data-cy="infobox-content">
110103
<FeatureElevationProfile
111-
v-if="showElevationProfile && !isCombo"
104+
v-if="showElevationProfile && tooltipFeatureInfo"
112105
class="card-body"
113106
:feature="selectedFeature"
114107
:read-only="!showDrawingOverlay"
115108
:projection="projection"
116109
/>
117110
118111
<FeatureCombo
119-
v-else-if="isCombo"
112+
v-else-if="showElevationProfile"
120113
class="card-body"
121114
:feature="selectedFeature"
122115
:read-only="!showDrawingOverlay"
@@ -129,7 +122,7 @@ function onClose() {
129122
:read-only="!showDrawingOverlay"
130123
/>
131124
132-
<FeatureList v-else-if="isList" />
125+
<FeatureList v-else />
133126
</div>
134127
</div>
135128
</template>

src/modules/map/MapModule.vue

-6
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
import { computed, defineAsyncComponent } from 'vue'
33
import { useStore } from 'vuex'
44
5-
import OpenLayersCompassButton from '@/modules/map/components/openlayers/OpenLayersCompassButton.vue'
6-
75
import CompareSlider from './components/CompareSlider.vue'
86
import LocationPopup from './components/LocationPopup.vue'
97
import WarningRibbon from './components/WarningRibbon.vue'
@@ -22,7 +20,6 @@ const displayLocationPopup = computed(
2220
const isCompareSliderActive = computed(() => {
2321
return store.state.ui.isCompareSliderActive && store.getters.visibleLayerOnTop
2422
})
25-
const isEmbed = computed(() => store.state.ui.embedMode)
2623
</script>
2724

2825
<template>
@@ -37,9 +34,6 @@ const isEmbed = computed(() => store.state.ui.embedMode)
3734
<!-- So that external modules can have access to the map instance through the provided 'getMap' -->
3835
<slot />
3936
<LocationPopup v-if="displayLocationPopup" />
40-
<teleport v-if="!isEmbed" to="#toolbox-compass-button">
41-
<OpenLayersCompassButton />
42-
</teleport>
4337
<CompareSlider v-if="isCompareSliderActive" />
4438
<slot name="footer" />
4539
</OpenLayersMap>

src/modules/map/components/CompareSlider.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ function releaseSlider() {
130130
<template>
131131
<div
132132
class="compare-slider position-absolute top-0 translate-middle-x h-100 d-inline-block"
133-
data-cy="compare_slider"
133+
data-cy="compareSlider"
134134
:style="compareSliderPosition"
135135
@touchstart.passive="grabSlider"
136136
@mousedown.passive="grabSlider"

src/modules/map/components/cesium/CesiumMap.vue

+15-6
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
<button
5959
class="btn btn-sm btn-light d-flex align-items-center"
6060
data-cy="toggle-floating-off"
61-
@click="toggleTooltip"
61+
@click="setBottomPanelFeatureInfoPosition()"
6262
>
6363
<FontAwesomeIcon icon="caret-down" />
6464
</button>
@@ -133,7 +133,7 @@ import {
133133
unhighlightGroup,
134134
} from '@/modules/map/components/cesium/utils/highlightUtils'
135135
import { ClickInfo, ClickType } from '@/store/modules/map.store'
136-
import { UIModes } from '@/store/modules/ui.store'
136+
import { FeatureInfoPositions, UIModes } from '@/store/modules/ui.store'
137137
import { WEBMERCATOR, WGS84 } from '@/utils/coordinates/coordinateSystems'
138138
import CustomCoordinateSystem from '@/utils/coordinates/CustomCoordinateSystem.class'
139139
import { identifyGeoJSONFeatureAt } from '@/utils/identifyOnVectorLayer'
@@ -169,7 +169,6 @@ export default {
169169
cameraPosition: (state) => state.position.camera,
170170
uiMode: (state) => state.ui.mode,
171171
previewYear: (state) => state.layers.previewYear,
172-
isFeatureTooltipInFooter: (state) => !state.ui.floatingTooltip,
173172
selectedFeatures: (state) => state.features.selectedFeatures,
174173
projection: (state) => state.position.projection,
175174
isFullScreenMode: (state) => state.ui.fullscreenMode,
@@ -180,6 +179,7 @@ export default {
180179
'hasDevSiteWarning',
181180
'visibleLayers',
182181
'backgroundLayersFor3D',
182+
'tooltipFeatureInfo',
183183
]),
184184
isProjectionWebMercator() {
185185
return this.projection.epsg === WEBMERCATOR.epsg
@@ -192,13 +192,16 @@ export default {
192192
(l) => l instanceof GeoAdminWMTSLayer || l instanceof GeoAdminWMSLayer
193193
)
194194
},
195+
isFeatureInfoInTooltip() {
196+
return this.tooltipFeatureInfo
197+
},
195198
visiblePrimitiveLayers() {
196199
return this.visibleLayers.filter(
197200
(l) => l instanceof GeoAdminGeoJsonLayer || l instanceof KMLLayer
198201
)
199202
},
200203
showFeaturesPopover() {
201-
return !this.isFeatureTooltipInFooter && this.selectedFeatures.length > 0
204+
return this.isFeatureInfoInTooltip && this.selectedFeatures.length > 0
202205
},
203206
editFeature() {
204207
return this.selectedFeatures.find((feature) => feature.isEditable)
@@ -292,7 +295,7 @@ export default {
292295
'setCameraPosition',
293296
'clearAllSelectedFeatures',
294297
'click',
295-
'toggleFloatingTooltip',
298+
'setFeatureInfoPosition',
296299
'setCenter',
297300
'mapModuleReady',
298301
]),
@@ -605,13 +608,19 @@ export default {
605608
})
606609
}
607610
},
611+
setBottomPanelFeatureInfoPosition() {
612+
this.setFeatureInfoPosition({
613+
featureInfo: FeatureInfoPositions.BOTTOMPANEL,
614+
...dispatcher,
615+
})
616+
},
608617
},
609618
}
610619
</script>
611620
612621
<style lang="scss" scoped>
613622
@import 'src/scss/webmapviewer-bootstrap-theme';
614-
@import 'src/modules/menu/scss/toolbox-buttons';
623+
@import 'src/modules/map/scss/toolbox-buttons';
615624
616625
// rule can't be scoped otherwise styles will be not applied
617626
:global(.cesium-viewer .cesium-widget-credits) {

src/modules/map/components/openlayers/OpenLayersCompassButton.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ export default {
5757
</script>
5858

5959
<style lang="scss" scoped>
60-
@import 'src/modules/menu/scss/toolbox-buttons';
60+
@import 'src/modules/map/scss/toolbox-buttons';
6161
.compass-button {
6262
&-icon {
6363
height: $map-button-diameter - 5px;

0 commit comments

Comments
 (0)