diff --git a/package.json b/package.json index 9c54f9e0edfd6ca848a1c84a8bcde9746b2e0b28..3aab9d9ac4a43cd270fd2e234771ef76aede3a57 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "geocontrib-frontend", - "version": "2.3.1", + "version": "2.3.2-rc1", "private": true, "scripts": { "serve": "npm run init-proxy & npm run init-serve", diff --git a/src/assets/js/map-util.js b/src/assets/js/map-util.js index f1652af4f7f8b1ad8673d42870f7343e08114f47..b66c3c1eb7b43871b1a48c2e3a42f72b5d8d13b4 100644 --- a/src/assets/js/map-util.js +++ b/src/assets/js/map-util.js @@ -49,7 +49,7 @@ L.TileLayer.BetterWMS = L.TileLayer.WMS.extend({ getFeatureInfo: function (evt) { if (this.wmsParams.basemapId != undefined) { - const queryableLayerSelected = document.getElementById(`queryable-layers-selector-${this.wmsParams.basemapId}`).getElementsByClassName('selected')[0].innerHTML; + const queryableLayerSelected = document.getElementById(`queryable-layers-selector-${this.wmsParams.basemapId}`).getElementsByClassName('selected')[0].textContent; if (queryableLayerSelected.trim() === this.wmsParams.title.trim()) { // Make an AJAX request to the server and hope for the best var params = this.getFeatureInfoUrl(evt.latlng); @@ -181,7 +181,7 @@ const mapUtil = { ], !zoom ? mapDefaultViewZoom : zoom ); - + map.setMaxBounds( [[-90,-180], [90,180]] ) if (zoomControl) { L.control .zoom({ @@ -226,6 +226,7 @@ const mapUtil = { layers.forEach((layer) => { if (layer) { const options = layer.options; + options.noWrap=true; if (options) { options.opacity = layer.opacity; @@ -250,6 +251,7 @@ const mapUtil = { } }); } else { + optionsMap.noWrap=true; L.tileLayer(serviceMap, optionsMap).addTo(map); } }, @@ -308,6 +310,7 @@ const mapUtil = { addVectorTileLayer: function (url, project_slug, featureTypes, form_filters) { layerMVT = L.vectorGrid.protobuf(url, { + noWrap:true, vectorTileLayerStyles: { "default": (properties) => { const featureType = featureTypes.find((x) => x.slug.split('-')[0] === '' + properties.feature_type_id); diff --git a/src/store/modules/feature.js b/src/store/modules/feature.js index 5e74e1df3382e98d06b6a0d1e84d46be719d81de..7d42ef515fa16c814ea1aede68311d54b46ff486 100644 --- a/src/store/modules/feature.js +++ b/src/store/modules/feature.js @@ -1,12 +1,6 @@ import axios from '@/axios-client.js'; 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; -// })('csrftoken'); - const feature = { namespaced: true, @@ -98,7 +92,6 @@ const feature = { }, ADD_ATTACHMENT_TO_DELETE(state, attachementId) { - // state.attachmentFormset = state.attachmentFormset.filter(el => el.id !== attachementId); state.attachmentsToDelete.push(attachementId); }, @@ -131,7 +124,7 @@ const feature = { url = url.concat('', `${url.includes('?') ? '&' : '?'}ordering=${ordering}`); } if (search) { - url = url.concat('', `${url.includes('?') ? '&' : '?'}title__contains=${search}`); + url = url.concat('', `${url.includes('?') ? '&' : '?'}title__icontains=${search}`); } if (limit) { url = url.concat('', `${url.includes('?') ? '&' : '?'}limit=${limit}`); @@ -145,7 +138,6 @@ const feature = { commit("SET_FEATURES", features); const features_count = response.data.count; commit("SET_FEATURES_COUNT", features_count); - //dispatch("map/ADD_FEATURES", null, { root: true }); //todo: should check if map was initiated } return response; }) @@ -181,7 +173,6 @@ const feature = { SEND_FEATURE({ state, rootState, commit, dispatch }, routeName) { commit("DISPLAY_LOADER", "Le signalement est en cours de création", { root: true }) const message = routeName === "editer-signalement" ? "Le signalement a été mis à jour" : "Le signalement a été crée"; - function redirect(featureId) { dispatch( 'GET_PROJECT_FEATURE', @@ -229,109 +220,66 @@ const feature = { } } + let url = `${rootState.configuration.VUE_APP_DJANGO_API_BASE}features/` if (routeName === "editer-signalement") { - return axios - .put(`${rootState.configuration.VUE_APP_DJANGO_API_BASE}features/${state.form.feature_id}/?` + - `feature_type__slug=${rootState.feature_type.current_feature_type_slug}` + - `&project__slug=${rootState.project_slug}` - , geojson) - .then((response) => { - if (response.status === 200 && response.data) { - if (state.attachmentFormset.length > 0 || state.linkedFormset.length > 0) { - handleOtherForms(response.data.id) - } else { - redirect(response.data.id) - } - } - }) - .catch((error) => { - commit("DISCARD_LOADER", null, { root: true }) - if (error.message === "Network Error" || window.navigator.onLine === false) { - let arraysOffline = []; - let localStorageArray = localStorage.getItem("geocontrib_offline"); - if (localStorageArray) { - arraysOffline = JSON.parse(localStorageArray); - } - let updateMsg = { - project: rootState.project_slug, - type: 'put', - featureId: state.form.feature_id, - geojson: geojson - }; - arraysOffline.push(updateMsg); - localStorage.setItem("geocontrib_offline", JSON.stringify(arraysOffline)); - router.push({ - name: "offline-signalement", - params: { - slug_type_signal: rootState.feature_type.current_feature_type_slug - }, - }); + url += `${state.form.feature_id}/?` + + `feature_type__slug=${rootState.feature_type.current_feature_type_slug}` + + `&project__slug=${rootState.project_slug}` + } + return axios({ + url, + method: routeName === "editer-signalement" ? "PUT" : "POST", + data: geojson + }).then((response) => { + if ((response.status === 200 || response.status === 201) && response.data) { + if (state.attachmentFormset.length > 0 || state.linkedFormset.length > 0 || state.attachmentFormset.length > 0 || state.attachmentsToDelete.length > 0) { + handleOtherForms(response.data.id) + } else { + redirect(response.data.id) } - else { - console.error(error) - throw error; + } + }) + .catch((error) => { + commit("DISCARD_LOADER", null, { root: true }) + if (error.message === "Network Error" || window.navigator.onLine === false) { + let arraysOffline = []; + let localStorageArray = localStorage.getItem("geocontrib_offline"); + if (localStorageArray) { + arraysOffline = JSON.parse(localStorageArray); } - + let updateMsg = { + project: rootState.project_slug, + type: 'put', + featureId: state.form.feature_id, + geojson: geojson + }; + arraysOffline.push(updateMsg); + localStorage.setItem("geocontrib_offline", JSON.stringify(arraysOffline)); + router.push({ + name: "offline-signalement", + params: { + slug_type_signal: rootState.feature_type.current_feature_type_slug + }, + }); + } + else { + console.error(error) throw error; - }); - } else { - return axios - .post(`${rootState.configuration.VUE_APP_DJANGO_API_BASE}features/`, geojson) - .then((response) => { - if (response.status === 201 && response.data) { - if (state.attachmentFormset.length > 0 || state.linkedFormset.length > 0) { - handleOtherForms(response.data.id) - } else { - redirect(response.data.id) - } - } - }) - .catch((error) => { - commit("DISCARD_LOADER", null, { root: true }) - if (error.message === "Network Error" || window.navigator.onLine === false) { - let arraysOffline = []; - let localStorageArray = localStorage.getItem("geocontrib_offline"); - if (localStorageArray) { - arraysOffline = JSON.parse(localStorageArray); - } - let updateMsg = { - project: rootState.project_slug, - type: 'post', - geojson: geojson - }; - arraysOffline.push(updateMsg); - localStorage.setItem("geocontrib_offline", JSON.stringify(arraysOffline)); - router.push({ - name: "offline-signalement", - params: { - slug_type_signal: rootState.feature_type.current_feature_type_slug - }, - }); - - } - else { - console.error(error) - throw error; - } - - }); - } - // this.$store.dispatch("GET_ALL_PROJECTS"), //* & refresh project list + } + throw error; + }); }, async SEND_ATTACHMENTS({ state, rootState, dispatch }, featureId) { const DJANGO_API_BASE = rootState.configuration.VUE_APP_DJANGO_API_BASE; - + function addFile(attachment, attchmtId) { let formdata = new FormData(); formdata.append("file", attachment.fileToImport, attachment.fileToImport.name); return axios .put(`${DJANGO_API_BASE}features/${featureId}/attachments/${attchmtId}/upload-file/`, formdata) .then((response) => { - if (response && response.status === 200) { - console.log(response.status) - } return response; }) .catch((error) => { @@ -345,33 +293,25 @@ const feature = { formdata.append("title", attachment.title); formdata.append("info", attachment.info); - if (!attachment.id) { //* used to check if doesn't exist in DB and should be send through post (useless now) - return axios - .post(`${DJANGO_API_BASE}features/${featureId}/attachments/`, formdata) - .then((response) => { - if (response && response.status === 201 && attachment.fileToImport) { - return addFile(attachment, response.data.id); - } - return response - }) - .catch((error) => { - console.error(error); - return error - }); - } else { - return axios - .put(`${DJANGO_API_BASE}features/${featureId}/attachments/${attachment.id}/`, formdata) - .then((response) => { - if (response && response.status === 200 && attachment.fileToImport) { - return addFile(attachment, response.data.id); - } - }) - .catch((error) => { - console.error(error); - return error - }); - + let url = `${DJANGO_API_BASE}features/${featureId}/attachments/` + if (attachment.id) { + url += `${attachment.id}/` } + + return axios({ + url, + method: attachment.id ? "PUT" : "POST", + data: formdata + }).then((response) => { + if (response && (response.status === 200 || response.status === 201) && attachment.fileToImport) { + return addFile(attachment, response.data.id); + } + return response + }) + .catch((error) => { + console.error(error); + return error + }); } function deleteAttachement(attachmentsId, featureId) { @@ -382,6 +322,7 @@ const feature = { return dispatch("DELETE_ATTACHMENTS", payload) .then((response) => response); } + const promisesResult = await Promise.all([ ...state.attachmentFormset.map((attachment) => putOrPostAttachement(attachment)), ...state.attachmentsToDelete.map((attachmentsId) => deleteAttachement(attachmentsId, featureId)) diff --git a/src/views/Index.vue b/src/views/Index.vue index 33ced862f9a5074b1d1184ce1d75dbb4877b4ecd..96f4a9b021ac0c93a4ba879913061afbbf09986c 100644 --- a/src/views/Index.vue +++ b/src/views/Index.vue @@ -62,7 +62,7 @@ >Niveau d'autorisation requis : {{ project.access_level_pub_feature }}</span ><br /> - <span> + <span v-if="user"> Mon niveau d'autorisation : <span v-if="USER_LEVEL_PROJECTS && project">{{ USER_LEVEL_PROJECTS[project.slug] diff --git a/src/views/feature/Feature_edit.vue b/src/views/feature/Feature_edit.vue index cb385b603c3ff389104e02639bec5f6100e5d1ee..62230a8ad09640c59bce137bb9c811e6f2ce1469 100644 --- a/src/views/feature/Feature_edit.vue +++ b/src/views/feature/Feature_edit.vue @@ -181,11 +181,6 @@ /> <div class="ui tab active map-container" data-tab="map"> <div id="map" ref="map"></div> - <!-- // todo: ajouter v-if --> - <!-- {% if serialized_base_maps|length > 0 %} {% include - "geocontrib/map-layers/sidebar-layers.html" with - basemaps=serialized_base_maps layers=serialized_layers - project=project.slug%} {% endif %} --> <SidebarLayers v-if="basemaps && map" /> </div> </div> @@ -849,7 +844,10 @@ export default { if (this.currentRouteName === "editer-signalement") { this.map.addControl(this.drawControlEditOnly); - } else this.map.addControl(this.drawControlFull); + } else { + this.map.addControl(this.drawControlFull); + } + this.changeMobileBtnOrder(); this.map.on( "draw:created", @@ -983,6 +981,24 @@ export default { } }, + changeMobileBtnOrder() { //* move large toolbar for polygon creation, cutting map in the middle + function changeDisplay() { + let buttons = document.querySelector(".leaflet-draw-actions.leaflet-draw-actions-top.leaflet-draw-actions-bottom") + if (buttons && buttons.style) { + buttons.style.display = "flex" + buttons.style["flex-direction"] = "column" + } + } + if (window.screen.availWidth < 767) { //* change button order all the time to keep homogeinity on mobile + let wrapper = document.querySelector(".leaflet-top.leaflet-right"); + if (wrapper) wrapper.appendChild(wrapper.children[0]); + if (this.feature_type.geom_type === "polygon") { //* if it's a polygon, change tools direction to vertical + let polygonBtn = document.querySelector(".leaflet-draw-draw-polygon"); //* since elements are generated + if (polygonBtn) polygonBtn.addEventListener("click", changeDisplay) //* it should be done at each click + } + } + }, + getFeatureAttachments() { featureAPI .getFeatureAttachments(this.$route.params.slug_signal) diff --git a/src/views/project/Project_detail.vue b/src/views/project/Project_detail.vue index 7b9c388aaedf2b29afdf46e17b1feaa7f91875ad..f284036ef0bd1236bb247ab9a9d5429170fd316b 100644 --- a/src/views/project/Project_detail.vue +++ b/src/views/project/Project_detail.vue @@ -975,6 +975,10 @@ export default { setTimeout(() => (this.tempMessage = null), 5000); //* hide message after 5 seconds } }, + + destroyed() { + this.CLEAR_RELOAD_INTERVAL_ID(); + }, }; </script>