diff --git a/src/components/Dropdown.vue b/src/components/Dropdown.vue index 797a9782df2038175f37c0e513c4ae7edf5b8369..b63ebe80e5432298cc6b9851b9c2f6e30f37d69a 100644 --- a/src/components/Dropdown.vue +++ b/src/components/Dropdown.vue @@ -10,18 +10,18 @@ > <input v-if="search" + v-model="input" + v-on:keyup.enter="select(0)" + v-on:keyup.esc="toggleDropdown(false)" class="search" autocomplete="off" tabindex="0" - @input="handelInput" - v-on:keyup.enter="select(0)" - v-model="input" - :placeholder="placeholder" + :placeholder="placehold" + ref="input" /> - <!-- {{placeholder}} --> - <div class="default text">{{ selected || placeholder }}</div> + <div v-if="!input" class="default text">{{ selected }}</div> <i - :class="['dropdown icon', { clear: search && selected }]" + :class="['dropdown icon', { clear: clearable && selected }]" @click="clear" ></i> <div :class="['menu', { 'visible transition': isOpen }]"> @@ -44,7 +44,14 @@ export default { name: "Dropdown", - props: ["options", "selected", "disabled", "search", "placeholder"], + props: [ + "options", + "selected", + "disabled", + "search", + "placeholder", + "clearable", + ], computed: { processedOptions: function () { @@ -57,6 +64,10 @@ export default { } return options.length > 0 ? options : null; }, + + placehold() { + return this.input ? "" : this.placeholder; + }, }, data() { @@ -66,44 +77,53 @@ export default { identifier: 0, }; }, + methods: { - toggleDropdown() { - this.isOpen = !this.isOpen; + toggleDropdown(val) { + if (this.isOpen) { + this.input = ""; // * clear input field when closing dropdown + } else if (this.search) { + //* focus on input if is a search dropdown + this.$refs.input.focus({ + preventScroll: true, + }); + } else if (this.clearable && val.target && this.selected) { + this.clear(); //* clear selected and input + } + this.isOpen = typeof val === "boolean" ? val : !this.isOpen; }, + select(index) { + // * toggle dropdown is called several time, timeout delay this function to be the last setTimeout(() => { - this.isOpen = false; // * quick & dirty, car toggle dropdown est rappelé plusieurs fois aileurs, à creuser... - }, 500); + this.isOpen = false; + }, 0); this.$emit("update:selection", this.options[index]); this.input = ""; }, + searchOptions(options) { return options.filter((el) => el.toLowerCase().includes(this.input.toLowerCase()) ); }, + clear() { - if (this.search) { + if (this.clearable) { this.input = ""; - this.clearSelected(); + this.$emit("update:selection", ""); + if (this.isOpen) this.toggleDropdown(false); } }, - clearSelected() { - this.$emit("update:selection", ""); - }, - handelInput() { - this.isOpen = true; - this.clearSelected(); - }, + clickOutsideDropdown(e) { if (!e.target.closest(`#custom-dropdown${this.identifier}`)) - this.isOpen = false; + this.toggleDropdown(false); }, }, created() { - let randomnum = Math.floor(Math.random() * 10000); - this.identifier = randomnum; + this.identifier = Math.floor(Math.random() * 10000); window.addEventListener("mousedown", this.clickOutsideDropdown); }, diff --git a/src/components/map-layers/SidebarLayers.vue b/src/components/map-layers/SidebarLayers.vue index 59cd5d1f1a489d7b76f4efbd8454f9c92d5002ea..8ee1575b5b5e6790735d6d1dca07218175aaf406 100644 --- a/src/components/map-layers/SidebarLayers.vue +++ b/src/components/map-layers/SidebarLayers.vue @@ -47,7 +47,6 @@ <div v-for="basemap in baseMaps" - :key="`list-${basemap.id}`" class="basemaps-items ui accordion styled" > @@ -58,15 +57,17 @@ > {{ basemap.title }} </div> - <div :id="`queryable-layers-selector-${basemap.id}`" v-if="isQueryable(basemap)"> + <div + :id="`queryable-layers-selector-${basemap.id}`" + v-if="isQueryable(basemap)" + > <b>Couche requêtable</b> - <Dropdown + <Dropdown @update:selection="onQueryLayerChange($event)" :options="getQueryableLayers(basemap)" :selected="selectedQueryLayer" :search="true" /> - </div> <div :class="{ active: isActive(basemap) }" @@ -77,7 +78,8 @@ <div v-for="(layer, index) in basemap.layers" :key="basemap.id + '-' + layer.id + '-' + index" - class="layer-item transition visible item list-group-item" :data-id="layer.id" + class="layer-item transition visible item list-group-item" + :data-id="layer.id" > <p class="layer-handle-sort"> <i class="th icon"></i>{{ layer.title }} @@ -104,168 +106,201 @@ </template> <script> -import { mapUtil } from "@/assets/js/map-util.js"; +import { mapState } from "vuex"; +import Sortable from "sortablejs"; import Dropdown from "@/components/Dropdown.vue"; -import Sortable from 'sortablejs'; +import { mapUtil } from "@/assets/js/map-util.js"; export default { name: "SidebarLayers", + components: { Dropdown, }, + data() { return { - selectedQueryLayer:null, - activeBasemap:null, + selectedQueryLayer: null, + activeBasemap: null, baseMaps: [], - layers: [], expanded: false, }; }, + + computed: { + ...mapState("map", ["availableLayers"]), + }, + methods: { isActive(basemap) { - return basemap.active != undefined && basemap.active; + return basemap.active !== undefined && basemap.active; }, + activateGroup(basemap) { this.baseMaps.forEach((basemap) => (basemap.active = false)); basemap.active = true; - this.activeBasemap=basemap; + this.activeBasemap = basemap; basemap.title += " "; //weird!! Force refresh this.addLayers(basemap); - let mapOptions = localStorage.getItem('geocontrib-map-options') || {}; - mapOptions = mapOptions.length ? JSON.parse(mapOptions) : {}; - let project=this.$route.params.slug; - mapOptions[project] = { - ...mapOptions[project], - 'current-basemap-index': basemap.id - }; - localStorage.setItem('geocontrib-map-options', JSON.stringify(mapOptions)); - - + let mapOptions = localStorage.getItem("geocontrib-map-options") || {}; + mapOptions = mapOptions.length ? JSON.parse(mapOptions) : {}; + let project = this.$route.params.slug; + mapOptions[project] = { + ...mapOptions[project], + "current-basemap-index": basemap.id, + }; + localStorage.setItem( + "geocontrib-map-options", + JSON.stringify(mapOptions) + ); }, + updateOpacity(event, layer) { console.log(event.target.value, layer); mapUtil.updateOpacity(layer.id, event.target.value); layer.opacity = event.target.value; }, + getOpacity(opacity) { return Math.round(parseFloat(opacity) * 100); }, - onQueryLayerChange(layer){ + + onQueryLayerChange(layer) { console.log(layer); - this.selectedQueryLayer=layer.name; + this.selectedQueryLayer = layer.name; }, - isQueryable(baseMap){ - let queryableLayer=baseMap.layers.filter(l => l.queryable === true); - return queryableLayer.length>0; + + isQueryable(baseMap) { + let queryableLayer = baseMap.layers.filter((l) => l.queryable === true); + return queryableLayer.length > 0; }, - onlayerMove(event){ - console.log(event) - // Get the names of the current layers in order. - const currentLayersNamesInOrder = Array.from(document.getElementsByClassName('layer-item transition visible')).map(el => el.children[0].innerText); + onlayerMove(event) { + console.log(event); + // Get the names of the current layers in order. + const currentLayersNamesInOrder = Array.from( + document.getElementsByClassName("layer-item transition visible") + ).map((el) => el.children[0].innerText); // Create an array to put the layers in order. let movedLayers = []; - + for (const layerName of currentLayersNamesInOrder) { - movedLayers.push(this.activeBasemap.layers.filter(el => el.title === layerName)[0]); + movedLayers.push( + this.activeBasemap.layers.filter((el) => el.title === layerName)[0] + ); } - // Remove existing layers undefined - movedLayers = movedLayers.filter(function(x) { + movedLayers = movedLayers.filter(function (x) { return x !== undefined; }); - const eventOrder = new CustomEvent('change-layers-order', { + const eventOrder = new CustomEvent("change-layers-order", { detail: { - layers: movedLayers - } - }) + layers: movedLayers, + }, + }); document.dispatchEvent(eventOrder); // Save the basemaps options into the localstorage - console.log(this.baseMaps) - this.setLocalstorageMapOptions(this.baseMaps) + console.log(this.baseMaps); + this.setLocalstorageMapOptions(this.baseMaps); }, + setLocalstorageMapOptions(basemaps) { - let mapOptions = localStorage.getItem('geocontrib-map-options') || {}; + let mapOptions = localStorage.getItem("geocontrib-map-options") || {}; mapOptions = mapOptions.length ? JSON.parse(mapOptions) : {}; - let project=this.$route.params.slug; + let project = this.$route.params.slug; mapOptions[project] = { ...mapOptions[project], - 'basemaps': basemaps + basemaps: basemaps, }; - localStorage.setItem('geocontrib-map-options', JSON.stringify(mapOptions)); + localStorage.setItem( + "geocontrib-map-options", + JSON.stringify(mapOptions) + ); }, - initSortable(){ + initSortable() { this.baseMaps.forEach((basemap) => { - new Sortable(document.getElementById(`list-${basemap.id}`), { - animation: 150, - handle: '.layer-handle-sort', // The element that is active to drag - ghostClass: 'blue-background-class', - dragClass: 'white-opacity-background-class', - onEnd: this.onlayerMove.bind(this) - }); + new Sortable(document.getElementById(`list-${basemap.id}`), { + animation: 150, + handle: ".layer-handle-sort", // The element that is active to drag + ghostClass: "blue-background-class", + dragClass: "white-opacity-background-class", + onEnd: this.onlayerMove.bind(this), + }); }); }, - // Check if there are changes in the basemaps settings. Changes are detected if: - // - one basemap has been added or deleted - // - one layer has been added or deleted to a basemap - areChangesInBasemaps(basemapFromServer, basemapFromLocalstorage={}) { - let isSameBasemaps = false; - let isSameLayers = true; - let isSameTitles = true; - - // Compare the length and the id values of the basemaps - const idBasemapsServer = basemapFromServer.map(b => b.id).sort(); - const idBasemapsLocalstorage = basemapFromLocalstorage.length ? basemapFromLocalstorage.map(b => b.id).sort() : {}; - isSameBasemaps = (idBasemapsServer.length === idBasemapsLocalstorage.length - && idBasemapsServer.every((value, index) => value === idBasemapsLocalstorage[index])) - - // For each basemap, compare the length and id values of the layers - outer_block: { - for(let basemapServer of basemapFromServer) { - let idLayersServer = basemapServer.layers.map(b => b.id).sort(); - if (basemapFromLocalstorage.length){ - for (let basemapLocalstorage of basemapFromLocalstorage) { - if (basemapServer.id === basemapLocalstorage.id) { - let idLayersLocalstorage = basemapLocalstorage.layers.map(b => b.id).sort(); - isSameLayers = (idLayersServer.length === idLayersLocalstorage.length - && idLayersServer.every((value, index) => value === idLayersLocalstorage[index])); - if (!isSameLayers) { - break outer_block; + // - one basemap has been added or deleted + // - one layer has been added or deleted to a basemap + areChangesInBasemaps(basemapFromServer, basemapFromLocalstorage = {}) { + let isSameBasemaps = false; + let isSameLayers = true; + let isSameTitles = true; + // Compare the length and the id values of the basemaps + const idBasemapsServer = basemapFromServer.map((b) => b.id).sort(); + const idBasemapsLocalstorage = basemapFromLocalstorage.length + ? basemapFromLocalstorage.map((b) => b.id).sort() + : {}; + isSameBasemaps = + idBasemapsServer.length === idBasemapsLocalstorage.length && + idBasemapsServer.every( + (value, index) => value === idBasemapsLocalstorage[index] + ); + // For each basemap, compare the length and id values of the layers + outer_block: { + for (let basemapServer of basemapFromServer) { + let idLayersServer = basemapServer.layers.map((b) => b.id).sort(); + if (basemapFromLocalstorage.length) { + for (let basemapLocalstorage of basemapFromLocalstorage) { + if (basemapServer.id === basemapLocalstorage.id) { + let idLayersLocalstorage = basemapLocalstorage.layers + .map((b) => b.id) + .sort(); + isSameLayers = + idLayersServer.length === idLayersLocalstorage.length && + idLayersServer.every( + (value, index) => value === idLayersLocalstorage[index] + ); + if (!isSameLayers) { + break outer_block; + } } } } } - } - - // Compare basemaps titles - const titlesBasemapsServer = basemapFromServer.map(b => b.title).sort(); - const titlesBasemapsLocalstorage = basemapFromLocalstorage.length ? basemapFromLocalstorage.map(b => b.title).sort() : {}; + // Compare basemaps titles + const titlesBasemapsServer = basemapFromServer + .map((b) => b.title) + .sort(); + const titlesBasemapsLocalstorage = basemapFromLocalstorage.length + ? basemapFromLocalstorage.map((b) => b.title).sort() + : {}; - isSameTitles = titlesBasemapsServer.every((title, index) => title === titlesBasemapsLocalstorage[index]); + isSameTitles = titlesBasemapsServer.every( + (title, index) => title === titlesBasemapsLocalstorage[index] + ); - if (!isSameTitles) { - break outer_block; + if (!isSameTitles) { + break outer_block; + } } - } - return !(isSameBasemaps && isSameLayers && isSameTitles); - }, - getQueryableLayers(baseMap){ - let queryableLayer=baseMap.layers.filter(l => l.queryable === true); - return queryableLayer.map(x=>{ + return !(isSameBasemaps && isSameLayers && isSameTitles); + }, + + getQueryableLayers(baseMap) { + let queryableLayer = baseMap.layers.filter((l) => l.queryable === true); + return queryableLayer.map((x) => { return { - name:x.title, - value:x - } + name: x.title, + value: x, + }; }); }, + addLayers(baseMap) { - baseMap.layers.forEach((layer) => { - var layerOptions = this.layers.find((l) => l.id === layer.id); + var layerOptions = this.availableLayers.find((l) => l.id === layer.id); console.log(layerOptions); layer = Object.assign(layer, layerOptions); layer.options.basemapId = baseMap.id; @@ -276,35 +311,39 @@ export default { mapUtil.addLayers(baseMap.layers.slice().reverse(), null, null); }, }, + mounted() { this.baseMaps = this.$store.state.map.basemaps; - let project=this.$route.params.slug; - const mapOptions = JSON.parse(localStorage.getItem('geocontrib-map-options')) || {}; - if (mapOptions - && mapOptions[project]) { - - // If already in the storage, we need to check if the admin did some + let project = this.$route.params.slug; + const mapOptions = + JSON.parse(localStorage.getItem("geocontrib-map-options")) || {}; + if (mapOptions && mapOptions[project]) { + // If already in the storage, we need to check if the admin did some // modification in the basemaps on the server side. The rule is: if one layer has been added // or deleted in the server, then we reset the localstorage. - const baseMapsFromLocalstorage = mapOptions[project]['basemaps']; - const areChanges = this.areChangesInBasemaps(this.baseMaps, baseMapsFromLocalstorage); + const baseMapsFromLocalstorage = mapOptions[project]["basemaps"]; + const areChanges = this.areChangesInBasemaps( + this.baseMaps, + baseMapsFromLocalstorage + ); if (areChanges) { mapOptions[project] = { - 'map-options': this.baseMaps, - 'current-basemap-index': 0, + "map-options": this.baseMaps, + "current-basemap-index": 0, }; - localStorage.setItem('geocontrib-map-options', JSON.stringify(mapOptions)); + localStorage.setItem( + "geocontrib-map-options", + JSON.stringify(mapOptions) + ); } else { this.baseMaps = baseMapsFromLocalstorage; } } - - this.layers = this.$store.state.map.layers; if (this.baseMaps.length > 0) { this.baseMaps[0].active = true; - this.activeBasemap=this.baseMaps[0]; + this.activeBasemap = this.baseMaps[0]; this.addLayers(this.baseMaps[0]); } else { mapUtil.addLayers( @@ -313,11 +352,7 @@ export default { this.$store.state.configuration.DEFAULT_BASE_MAP.OPTIONS ); } - setTimeout(this.initSortable.bind(this),1000) - - - - + setTimeout(this.initSortable.bind(this), 1000); }, }; </script> diff --git a/src/components/project/ProjectMappingContextLayer.vue b/src/components/project/ProjectMappingContextLayer.vue index 02837647f558390fbc411a13f495f80d20e86b50..9b732a334589c3b263cb0067bd770bfbc8093730 100644 --- a/src/components/project/ProjectMappingContextLayer.vue +++ b/src/components/project/ProjectMappingContextLayer.vue @@ -11,7 +11,7 @@ <!-- {{ form.layer }} --> <!-- {% else %} --> <Dropdown - :options="availableLayers" + :options="availableLayerOptions" :selected="selectedLayer.name" :selection.sync="selectedLayer" :search="true" @@ -70,23 +70,16 @@ export default { }, computed: { - ...mapState("map", ["layers", "availableLayers"]), + ...mapState("map", ["availableLayers"]), selectedLayer: { get() { - const matchingLayer = this.retrieveLayer(this.layer.title); - if (matchingLayer != undefined) { - return { - name: matchingLayer != undefined ? matchingLayer.service : "", - value: this.layer ? this.layer.title : "", - }; - } - return []; + return this.retrieveLayer(this.layer.title) || []; }, set(newValue) { const matchingLayer = this.retrieveLayer(newValue.title); - if (matchingLayer != undefined) { + if (matchingLayer !== undefined) { this.updateLayer({ ...this.layer, service: newValue.name, @@ -109,11 +102,11 @@ export default { }, }, - availableLayers: function () { - return this.layers.map((el) => { + availableLayerOptions: function () { + return this.availableLayers.map((el) => { return { id: el.id, - name: el.service, + name: `${el.title} - ${el.service}`, value: el.title, title: el.title, }; @@ -122,14 +115,14 @@ export default { placeholder: function () { return this.selectedLayer && this.selectedLayer.name - ? this.selectedLayer.name + ? "" : "Choisissez une couche"; }, }, methods: { retrieveLayer(title) { - return this.layers.find((el) => el.title === title); + return this.availableLayerOptions.find((el) => el.title === title); }, removeLayer() { @@ -150,7 +143,7 @@ export default { mounted() { const matchingLayer = this.retrieveLayer(this.layer.title); - if (matchingLayer != undefined) { + if (matchingLayer !== undefined) { this.updateLayer({ ...this.layer, service: matchingLayer.service, diff --git a/src/main.js b/src/main.js index 22fdd2b3b48d5fa8a340a744abf90bded82bf99a..724a17140dc042cedd811c9027eb374e807a067d 100644 --- a/src/main.js +++ b/src/main.js @@ -20,7 +20,7 @@ axios.get("/config/config.json") store.dispatch("GET_ALL_PROJECTS"), store.dispatch("GET_STATIC_PAGES"), store.dispatch("GET_USER_LEVEL_PROJECTS"), - store.dispatch("map/GET_LAYERS"), + store.dispatch("map/GET_AVAILABLE_LAYERS"), store.dispatch("GET_USER_LEVEL_PERMISSIONS"), ]).then(axios.spread(function () { new Vue({ diff --git a/src/services/project-api.js b/src/services/project-api.js index fd46c39241a72d1928e49af49f081730d497da9c..b918ad2270c8dbcd20cd0d46f8c903af3176a3a4 100644 --- a/src/services/project-api.js +++ b/src/services/project-api.js @@ -5,7 +5,7 @@ import store from '../store' axios.defaults.headers.common['X-CSRFToken'] = (name => { var re = new RegExp(name + "=([^;]+)"); var value = re.exec(document.cookie); - return (value != null) ? unescape(value[1]) : null; + return (value !== null) ? unescape(value[1]) : null; })('csrftoken'); diff --git a/src/store/index.js b/src/store/index.js index 713cf40a33323737061d331985840c6e09a39361..329d9b0b684344a2d4a6da266d1715b3deb8c71e 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -10,7 +10,7 @@ import map from "./modules/map" axios.defaults.headers.common['X-CSRFToken'] = (name => { var re = new RegExp(name + "=([^;]+)"); var value = re.exec(document.cookie); - return (value != null) ? unescape(value[1]) : null; + return (value !== null) ? unescape(value[1]) : null; })('csrftoken'); @@ -22,7 +22,7 @@ function updateAxiosHeader() { axios.defaults.headers.common['X-CSRFToken'] = (name => { var re = new RegExp(name + "=([^;]+)"); var value = re.exec(document.cookie); - return (value != null) ? unescape(value[1]) : null; + return (value !== null) ? unescape(value[1]) : null; })('csrftoken'); } // ! À vérifier s'il y a un changement de token pendant l'éxécution de l'appli @@ -92,7 +92,10 @@ export default new Vuex.Store({ }, DISPLAY_MESSAGE(state, comment) { state.messages = [{ comment }, ...state.messages]; - document.getElementById("content").scrollIntoView({ block: "start", inline: "nearest" }); + document.getElementById("messages").scrollIntoView({ block: "start", inline: "nearest" }); + setTimeout(() => { + state.messages = []; + }, 3000); }, CLEAR_MESSAGES(state) { state.messages = []; diff --git a/src/store/modules/feature.js b/src/store/modules/feature.js index 8b186bc236bdd069aaaf7f063adff57a06c3c4e4..02c889157156c82b25dfa1d9916228691c872d55 100644 --- a/src/store/modules/feature.js +++ b/src/store/modules/feature.js @@ -4,7 +4,7 @@ import router from '../../router' axios.defaults.headers.common['X-CSRFToken'] = (name => { var re = new RegExp(name + "=([^;]+)"); var value = re.exec(document.cookie); - return (value != null) ? unescape(value[1]) : null; + return (value !== null) ? unescape(value[1]) : null; })('csrftoken'); diff --git a/src/store/modules/feature_type.js b/src/store/modules/feature_type.js index 1ef68a93448748fdd2c13dc533fba5f02c6714df..a763e047ceb1110cf6576881b9f42d6403e425ed 100644 --- a/src/store/modules/feature_type.js +++ b/src/store/modules/feature_type.js @@ -3,7 +3,7 @@ import axios from "axios" axios.defaults.headers.common['X-CSRFToken'] = (name => { var re = new RegExp(name + "=([^;]+)"); var value = re.exec(document.cookie); - return (value != null) ? unescape(value[1]) : null; + return (value !== null) ? unescape(value[1]) : null; })('csrftoken'); diff --git a/src/store/modules/map.js b/src/store/modules/map.js index 76cfc0bcdd942f9380b417c3e73cc9014587ccce..d47afc9ef721f6a3201ff1db473b051c92552a1e 100644 --- a/src/store/modules/map.js +++ b/src/store/modules/map.js @@ -4,7 +4,7 @@ import { mapUtil } from "@/assets/js/map-util.js"; axios.defaults.headers.common['X-CSRFToken'] = (name => { var re = new RegExp(name + "=([^;]+)"); var value = re.exec(document.cookie); - return (value != null) ? unescape(value[1]) : null; + return (value !== null) ? unescape(value[1]) : null; })('csrftoken'); @@ -15,11 +15,11 @@ const map = { basemapsToDelete: [], features: [], geojsonFeatures: null, - layers: null, + availableLayers: null, }, mutations: { - SET_LAYERS(state, layers) { - state.layers = layers; + SET_LAYERS(state, availableLayers) { + state.availableLayers = availableLayers; }, SET_GEOJSON_FEATURES(state, geojsonFeatures) { state.geojsonFeatures = geojsonFeatures; @@ -87,7 +87,7 @@ const map = { }, actions: { - GET_LAYERS({ commit }) { + GET_AVAILABLE_LAYERS({ commit }) { return axios .get(`${this.state.configuration.VUE_APP_DJANGO_API_BASE}layers/`) .then((response) => (commit("SET_LAYERS", response.data))) @@ -138,7 +138,7 @@ const map = { : 0; layersToLoad = state.baseMaps[basemapIndex].layers; layersToLoad.forEach((layerToLoad) => { - state.layers.forEach((layer) => { + state.availableLayers.forEach((layer) => { if (layer.id === layerToLoad.id) { layerToLoad = Object.assign(layerToLoad, layer); } diff --git a/src/views/feature/Feature_detail.vue b/src/views/feature/Feature_detail.vue index c1a5260d995a927fe087fbad2379afa4a0fb723d..1a1dd773c9dcee010166c237b86b973dc046dbf0 100644 --- a/src/views/feature/Feature_detail.vue +++ b/src/views/feature/Feature_detail.vue @@ -563,7 +563,7 @@ export default { // - if not, load the default map and service options let layersToLoad = null; var baseMaps = this.$store.state.map.basemaps; - var layers = this.$store.state.map.layers; + var layers = this.$store.state.map.availableLayers; if (baseMaps && baseMaps.length > 0) { const basemapIndex = 0; layersToLoad = baseMaps[basemapIndex].layers; @@ -599,7 +599,7 @@ export default { if (feature) { const currentFeature = [feature]; const featureGroup = mapUtil.addFeatures(currentFeature); - mapUtil.getMap().fitBounds(featureGroup.getBounds()); + mapUtil.getMap().fitBounds(featureGroup.getBounds(), { padding: [25, 25] }); } }) .catch((error) => { diff --git a/src/views/feature/Feature_edit.vue b/src/views/feature/Feature_edit.vue index bf455ac417517635948694ad077698dda856b37a..cefa6f35cbb71d4d7ba9b5fb7bb21b0cb5785199 100644 --- a/src/views/feature/Feature_edit.vue +++ b/src/views/feature/Feature_edit.vue @@ -250,7 +250,7 @@ import flip from "@turf/flip"; axios.defaults.headers.common["X-CSRFToken"] = ((name) => { var re = new RegExp(name + "=([^;]+)"); var value = re.exec(document.cookie); - return value != null ? unescape(value[1]) : null; + return value !== null ? unescape(value[1]) : null; })("csrftoken"); export default { @@ -838,7 +838,7 @@ export default { } else if (geomType === "polygon") { L.polygon(geomJSON.coordinates).addTo(this.drawnItems); } - this.map.fitBounds(this.drawnItems.getBounds()); + this.map.fitBounds(this.drawnItems.getBounds(), { padding: [25, 25] }); } else { this.map.setView( this.$store.state.configuration.DEFAULT_MAP_VIEW.center, diff --git a/src/views/feature/Feature_list.vue b/src/views/feature/Feature_list.vue index fb5d7ff0fc43efae37ceb4f73e503164e3f54938..79b7f1342d4563e29850e5e7793f52d0eaa0c0b7 100644 --- a/src/views/feature/Feature_list.vue +++ b/src/views/feature/Feature_list.vue @@ -93,6 +93,7 @@ :selected="form.type.selected" :selection.sync="form.type.selected" :search="true" + :clearable="true" /> </div> <div class="field wide four column no-padding-mobile no-margin-mobile"> @@ -104,6 +105,7 @@ :selected="form.status.selected.name" :selection.sync="form.status.selected" :search="true" + :clearable="true" /> </div> <div class="field wide four column"> @@ -333,7 +335,9 @@ export default { this.featureGroup.clearLayers(); this.featureGroup = mapUtil.addFeatures(features, {}); if (features.length > 0) { - mapUtil.getMap().fitBounds(this.featureGroup.getBounds()); + mapUtil + .getMap() + .fitBounds(this.featureGroup.getBounds(), { padding: [25, 25] }); } }, @@ -402,7 +406,9 @@ export default { (this.lat === "" || this.lng === "" || this.zoom === "") && this.geojsonFeatures.length > 0 ) { - mapUtil.getMap().fitBounds(this.featureGroup.getBounds()); + mapUtil + .getMap() + .fitBounds(this.featureGroup.getBounds(), { padding: [25, 25] }); } this.form.type.choices = [ //* converting Set to an Array with spread "..." diff --git a/src/views/project/Project_detail.vue b/src/views/project/Project_detail.vue index ddff358b08a2ed0bdacf60f88b1f951ce7f11252..b7fbff0231327a8f1606f9182f26e87add209dc2 100644 --- a/src/views/project/Project_detail.vue +++ b/src/views/project/Project_detail.vue @@ -589,7 +589,9 @@ export default { const features = response.data.features; const featureGroup = mapUtil.addFeatures(features); if (featureGroup && featureGroup.getLayers().length > 0) { - mapUtil.getMap().fitBounds(featureGroup.getBounds()); + mapUtil + .getMap() + .fitBounds(featureGroup.getBounds(), { padding: [25, 25] }); self.$store.commit("map/SET_GEOJSON_FEATURES", features); } }) diff --git a/src/views/project/Project_edit.vue b/src/views/project/Project_edit.vue index 4d250f598a9afc0f5a2acfe376fa1954f074c213..7bbf384af7270a9e3657214bde60d19468d5887d 100644 --- a/src/views/project/Project_edit.vue +++ b/src/views/project/Project_edit.vue @@ -199,7 +199,7 @@ import { mapGetters } from "vuex"; axios.defaults.headers.common["X-CSRFToken"] = ((name) => { var re = new RegExp(name + "=([^;]+)"); var value = re.exec(document.cookie); - return value != null ? unescape(value[1]) : null; + return value !== null ? unescape(value[1]) : null; })("csrftoken"); export default { diff --git a/src/views/project/Project_members.vue b/src/views/project/Project_members.vue index bb03c3d8e0f18ab5e9b3b6b4364ba77b8db70b35..a838d755e80c0131efa9de35a3b5b1c63955eea9 100644 --- a/src/views/project/Project_members.vue +++ b/src/views/project/Project_members.vue @@ -107,6 +107,12 @@ export default { .then((response) => { if (response.status === 200) { this.$store.dispatch("GET_USER_LEVEL_PROJECTS"); //* update user status in top right menu + this.$store.commit("DISPLAY_MESSAGE", "Permissions mises à jour"); + } else { + this.$store.commit( + "DISPLAY_MESSAGE", + "Une erreur s'est produite pendant la mises à jour des permissions" + ); } }) .catch((error) => {