diff --git a/src/App.vue b/src/App.vue index 954fe28fa431592cd8f246ee7d8b0e35c8a0c703..6318200de53a648114dbce4085498216ca450e97 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,5 +1,12 @@ <template> <div v-frag> + <script + type="application/javascript" + :src=" + baseUrl + + 'resources/leaflet-control-geocoder-1.13.0/Control.Geocoder.js' + " + ></script> <header class="header-menu"> <div class="menu container"> <div class="ui inverted icon menu"> @@ -184,6 +191,7 @@ export default { return { menuIsOpen: false, rightMenuIsOpen: true, + baseUrl: this.$store.state.configuration.BASE_URL, width: window.innerWidth > 0 ? window.innerWidth : screen.width, }; }, diff --git a/src/assets/js/map-util.js b/src/assets/js/map-util.js index d48ea574eff57d30246ea2198584aadf536a6c9c..8fac44860d2fd12c161d7b7ef3ee51d585db1f92 100644 --- a/src/assets/js/map-util.js +++ b/src/assets/js/map-util.js @@ -199,7 +199,7 @@ const mapUtil = { addGeocoders: function (configuration) { let geocoder; const geocoderLabel = configuration.SELECTED_GEOCODER.PROVIDER; - if (geocoderLabel) { + if (geocoderLabel && L.Control.Geocoder) { const LIMIT_RESULTS = 5; if ( geocoderLabel === configuration.GEOCODER_PROVIDERS.ADDOK diff --git a/src/store/modules/feature.js b/src/store/modules/feature.js index d081b0b6b49432a88d697d0434f0871b913466c2..4b80d47b4cf1d305fde28b27484597f1d9a54650 100644 --- a/src/store/modules/feature.js +++ b/src/store/modules/feature.js @@ -16,6 +16,7 @@ const feature = { checkedFeatures: [], extra_form: [], features: [], + current_feature: [], form: null, linkedFormset: [], linked_features: [], @@ -42,6 +43,9 @@ const feature = { SET_FEATURES(state, features) { state.features = features; }, + SET_CURRENT_FEATURE(state, feature) { + state.current_feature = feature; + }, UPDATE_FORM(state, payload) { state.form = payload; }, @@ -133,6 +137,30 @@ const feature = { throw error; }); }, + GET_PROJECT_FEATURE({ commit, rootState }, { project_slug, feature_id }) { + if (rootState.cancellableSearchRequest.length > 0) { + const currentRequestCancelToken = + rootState.cancellableSearchRequest[rootState.cancellableSearchRequest.length - 1]; + currentRequestCancelToken.cancel(); + } + + const cancelToken = axios.CancelToken.source(); + commit('SET_CANCELLABLE_SEARCH_REQUEST', cancelToken, { root: true }); + commit("SET_CURRENT_FEATURE", null); + let url = `${rootState.configuration.VUE_APP_DJANGO_API_BASE}projects/${project_slug}/feature/?id=${feature_id}`; + return axios + .get(url , { cancelToken: cancelToken.token }) + .then((response) => { + if (response.status === 200 && response.data.features) { + const feature = response.data.features[0]; + commit("SET_CURRENT_FEATURE", feature); + } + return response; + }) + .catch((error) => { + throw error; + }); + }, SEND_FEATURE({ state, rootState, commit, dispatch }, routeName) { commit("DISPLAY_LOADER", "Le signalement est en cours de création", { root: true }) diff --git a/src/store/modules/feature_type.js b/src/store/modules/feature_type.js index cfc3c0ddb6f6d5d20bd0133ac18b4c046ee99b9a..612c4140631d3e8990f056d995417a9bf0bdb12f 100644 --- a/src/store/modules/feature_type.js +++ b/src/store/modules/feature_type.js @@ -160,12 +160,13 @@ const feature_type = { }, SEND_FEATURES_FROM_GEOJSON({ state, dispatch }, payload) { - const { feature_type_slug } = payload + console.log(payload); + const { feature_type_slug } = payload; if (state.fileToImport.size > 0) { let formData = new FormData(); - formData.append("json_file", state.fileToImport); - formData.append("feature_type_slug", feature_type_slug); + formData.append('json_file', state.fileToImport); + formData.append('feature_type_slug', feature_type_slug); let url = this.state.configuration.VUE_APP_DJANGO_API_BASE + 'import-tasks/' diff --git a/src/views/feature/Feature_detail.vue b/src/views/feature/Feature_detail.vue index 416703ec722b0be57646869861ec0da713ad0e22..9b2a4e319cde78cbae88c25bf4125f5d01da7eff 100644 --- a/src/views/feature/Feature_detail.vue +++ b/src/views/feature/Feature_detail.vue @@ -41,7 +41,7 @@ <!-- (permissions && permissions.can_delete_feature) || --> <a v-if=" - isFeatureCreator || permissions.is_project_super_contributor + isFeatureCreator || (permissions && permissions.is_project_super_contributor) " @click="isCanceling = true" id="feature-delete" @@ -403,9 +403,7 @@ export default { }, feature() { - const result = this.$store.state.feature.features.find( - (el) => el.feature_id === this.$route.params.slug_signal - ); + const result = this.$store.state.feature.current_feature; return result; }, @@ -417,7 +415,7 @@ export default { }, isModerator() { - return this.USER_LEVEL_PROJECTS && + return this.USER_LEVEL_PROJECTS && this.project && this.USER_LEVEL_PROJECTS[this.project.slug] === "Modérateur" ? true : false; @@ -689,13 +687,23 @@ export default { axios.all([ this.$store .dispatch("GET_PROJECT_INFO", this.$route.params.slug), - this.$store.dispatch('feature/GET_PROJECT_FEATURES', { - project_slug: this.$route.params.slug + this.$store.dispatch('feature/GET_PROJECT_FEATURE', { + project_slug: this.$route.params.slug, + feature_id: this.$route.params.slug_signal })]) .then(() => { this.$store.commit("DISCARD_LOADER"); this.initMap(); }); + } if (!this.feature || this.feature.feature_id != this.$route.params.slug_signal) { + this.$store.dispatch('feature/GET_PROJECT_FEATURE', { + project_slug: this.$route.params.slug, + feature_id: this.$route.params.slug_signal + }) + .then(() => { + this.$store.commit("DISCARD_LOADER"); + this.initMap(); + }); } else { this.$store.commit("DISCARD_LOADER"); this.initMap(); diff --git a/src/views/feature/Feature_edit.vue b/src/views/feature/Feature_edit.vue index 30ceab1a5636a89b695fe2f8c4991fa3b40ec77e..981b12d9a19a8c5b1e56906d770b34449fbf7a38 100644 --- a/src/views/feature/Feature_edit.vue +++ b/src/views/feature/Feature_edit.vue @@ -1,12 +1,5 @@ <template> <div v-frag> - <script - type="application/javascript" - :src=" - baseUrl + - 'resources/leaflet-control-geocoder-1.13.0/Control.Geocoder.js' - " - ></script> <div class="fourteen wide column"> <h1 v-if="feature && currentRouteName === 'editer-signalement'"> Mise à jour du signalement "{{ feature.title || feature.feature_id }}" @@ -375,9 +368,8 @@ export default { }, feature: function () { - return this.$store.state.feature.features.find( - (el) => el.feature_id === this.$route.params.slug_signal - ); + const result = this.$store.state.feature.current_feature; + return result; }, orderedCustomFields() { @@ -1016,8 +1008,12 @@ export default { }, mounted() { - this.$store - .dispatch("GET_PROJECT_INFO", this.$route.params.slug) + axios.all([this.$store + .dispatch("GET_PROJECT_INFO", this.$route.params.slug), + this.$store.dispatch('feature/GET_PROJECT_FEATURE', { + project_slug: this.$route.params.slug, + feature_id: this.$route.params.slug_signal + })]) .then(() => { this.initForm(); this.initMap(); diff --git a/src/views/feature/Feature_list.vue b/src/views/feature/Feature_list.vue index 7d6ecaed2fdd020b35d5f4cd9dfe3864dd50f2c3..7d8d20d05794a6c88f07e8b509f900c7ad7a3c23 100644 --- a/src/views/feature/Feature_list.vue +++ b/src/views/feature/Feature_list.vue @@ -1,12 +1,6 @@ <template> <div class="fourteen wide column"> - <script - type="application/javascript" - :src=" - baseUrl + - 'resources/leaflet-control-geocoder-1.13.0/Control.Geocoder.js' - " - ></script> + <div id="feature-list-container" class="ui grid mobile-column"> <div class="four wide column mobile-fullwidth"> <h1>Signalements</h1> @@ -390,7 +384,10 @@ export default { ); mapUtil.getMap().invalidateSize(); mapUtil.getMap()._onResize(); // force refresh for vector tiles - + if(window.layerMVT) { + window.layerMVT.redraw(); + } + if (this.featureGroup.getLayers().length > 0) { mapUtil .getMap() diff --git a/src/views/feature_type/Feature_type_detail.vue b/src/views/feature_type/Feature_type_detail.vue index 80e1e6eb516e735b21fd0cabc7c7ed37f8fd5b91..b872358948af2d14266505ad65aa954b9ecbe9ab 100644 --- a/src/views/feature_type/Feature_type_detail.vue +++ b/src/views/feature_type/Feature_type_detail.vue @@ -267,6 +267,7 @@ export default { return "integer"; } else if ( type === "string" && + ['/', ':', '-'].some(el => prop.includes(el)) && // check for chars found in datestring date instanceof Date && !isNaN(date.valueOf()) ) { @@ -288,24 +289,22 @@ export default { }); for (const feature of json.features) { for (const { name, field_type, options } of fields) { - //* check if custom field is present - if (!(name in feature.properties)) { - return false; - } - const fieldInFeature = feature.properties[name]; - const customType = this.transformProperties(fieldInFeature); - //* if custom field value is not null, then check validity of field - if (fieldInFeature !== null) { - //* if field type is list, it's not possible to guess from value type - if (field_type === "list") { - //*then check if the value is an available option - if (!options.includes(fieldInFeature)) { + if (name in feature.properties) { + const fieldInFeature = feature.properties[name]; + const customType = this.transformProperties(fieldInFeature); + //* if custom field value is not null, then check validity of field + if (fieldInFeature !== null) { + //* if field type is list, it's not possible to guess from value type + if (field_type === "list") { + //*then check if the value is an available option + if (!options.includes(fieldInFeature)) { + return false; + } + } else if (customType !== field_type) { + //* check if custom field value match + this.importError = `Le fichier est invalide: Un champ de type ${field_type} ne peut pas avoir la valeur [ ${fieldInFeature} ]`; return false; } - } else if (customType !== field_type) { - //* check if custom field value match - this.importError = `Le fichier est invalide: Un champ de type ${field_type} ne peut pas avoir la valeur [ ${fieldInFeature} ]`; - return false; } } } @@ -331,7 +330,7 @@ export default { }, importGeoJson() { - this.$store.dispatch("feature_type/SEND_FEATURES_FROM_GEOJSON", { + this.$store.dispatch('feature_type/SEND_FEATURES_FROM_GEOJSON', { slug: this.$route.params.slug, feature_type_slug: this.$route.params.feature_type_slug, fileToImport: this.fileToImport,