Skip to content

Commit 996b12f

Browse files
committed
feat: Validate style JSON, display any errors, and only show preview if valid
1 parent 8303dac commit 996b12f

File tree

1 file changed

+39
-24
lines changed

1 file changed

+39
-24
lines changed

web/src/components/ControlsBar.vue

Lines changed: 39 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
<script setup lang="ts">
2-
import { ref, watch } from "vue";
2+
import { ref, watch, computed } from "vue";
33
import html2canvas from "html2canvas";
44
import { Map } from "maplibre-gl";
55
66
import JsonEditorVue from 'json-editor-vue'
77
import 'vanilla-jsoneditor/themes/jse-theme-dark.css'
88
import { Mode } from 'vanilla-jsoneditor'
9+
import { validateStyleMin } from '@maplibre/maplibre-gl-style-spec';
910
1011
import { useAppStore, useLayerStore, useMapStore } from "@/store";
1112
import { createBasemap } from "@/api/rest";
@@ -24,7 +25,13 @@ const newBasemapTab = ref<'url' | 'json'>('url')
2425
const newBasemapName = ref();
2526
const newBasemapTileURL = ref();
2627
const newBasemapStyleJSON = ref();
28+
const jsonErrors = ref();
2729
const newBasemapPreview = ref<Map | undefined>();
30+
const newBasemapValid = computed(() => (
31+
newBasemapName.value?.length &&
32+
newBasemapStyleJSON.value &&
33+
!jsonErrors.value.length
34+
))
2835
2936
function createBasemapPreviews() {
3037
if (basemapList.value) {
@@ -57,12 +64,14 @@ function cancelBasemapCreate() {
5764
newBasemapName.value = undefined;
5865
newBasemapTileURL.value = undefined;
5966
newBasemapStyleJSON.value = undefined;
67+
jsonErrors.value = []
6068
newBasemapPreview.value = undefined;
6169
}
6270
6371
function switchBasemapCreateTab() {
6472
newBasemapTileURL.value = undefined;
6573
newBasemapStyleJSON.value = undefined;
74+
jsonErrors.value = []
6675
createNewBasemapPreview()
6776
}
6877
@@ -91,37 +100,42 @@ function setNewBasemapStyleFromTileURL() {
91100
}
92101
93102
function createNewBasemapPreview() {
103+
const map = mapStore.getMap();
104+
const center = map.getCenter();
105+
const zoom = map.getZoom();
94106
if (!newBasemapPreview.value) {
95-
const map = mapStore.getMap();
96-
const center = map.getCenter();
97-
const zoom = map.getZoom();
98107
newBasemapPreview.value = new Map({
99108
container: 'basemap-preview-new',
100109
attributionControl: false,
101-
center,
102-
zoom,
103110
})
104111
}
112+
newBasemapPreview.value.setCenter(center);
113+
newBasemapPreview.value.setZoom(zoom);
105114
if (newBasemapStyleJSON.value) {
106-
newBasemapPreview.value.setStyle(newBasemapStyleJSON.value);
107-
} else {
108-
newBasemapPreview.value.setStyle({
109-
version: 8,
110-
sources: {},
111-
layers: []
112-
})
115+
jsonErrors.value = validateStyleMin(newBasemapStyleJSON.value);
116+
if (!jsonErrors.value?.length) {
117+
newBasemapPreview.value.setStyle(newBasemapStyleJSON.value);
118+
return;
119+
}
113120
}
121+
newBasemapPreview.value.setStyle({
122+
version: 8,
123+
sources: {},
124+
layers: []
125+
})
114126
}
115127
116128
function submitBasemapCreate() {
117-
createBasemap({
118-
name: newBasemapName.value,
119-
style: newBasemapStyleJSON.value,
120-
}).then((basemap) => {
121-
cancelBasemapCreate();
122-
mapStore.fetchAvailableBasemaps();
123-
mapStore.currentBasemap = basemap;
124-
})
129+
if (newBasemapValid.value) {
130+
createBasemap({
131+
name: newBasemapName.value,
132+
style: newBasemapStyleJSON.value,
133+
}).then((basemap) => {
134+
cancelBasemapCreate();
135+
mapStore.fetchAvailableBasemaps();
136+
mapStore.currentBasemap = basemap;
137+
})
138+
}
125139
}
126140
127141
async function fitMap() {
@@ -292,14 +306,15 @@ watch(newBasemapStyleJSON, createNewBasemapPreview)
292306
</v-window-item>
293307
</v-window>
294308
<v-spacer />
295-
<div>Map Preview:</div>
296-
<div id="basemap-preview-new"></div>
309+
<div v-for="err in jsonErrors">Error: {{ err.message }}</div>
310+
<div v-if="!jsonErrors?.length">Map Preview:</div>
311+
<div id="basemap-preview-new" :style="jsonErrors?.length ? 'display: none' : ''"></div>
297312
</v-card-text>
298313
<v-card-actions style="text-align: right;">
299314
<v-btn @click="cancelBasemapCreate" variant="tonal">
300315
Cancel
301316
</v-btn>
302-
<v-btn color="primary" :disabled="!newBasemapName || !newBasemapStyleJSON" @click="submitBasemapCreate">
317+
<v-btn color="primary" :disabled="!newBasemapValid" @click="submitBasemapCreate">
303318
Create
304319
</v-btn>
305320
</v-card-actions>

0 commit comments

Comments
 (0)