diff --git a/src/router/index.js b/src/router/index.js index 7452cef029f74f2747d3e30ca687cad4bcac0294..cf769571958b7f1c75195b7157bcad0f22062e3b 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -42,6 +42,7 @@ const routes = [ { path: '/projet/:slug', name: 'project_detail', + props: true, component: () => import('../views/project/Project_detail.vue'), }, { diff --git a/src/store/modules/feature_type.js b/src/store/modules/feature_type.js index 510d9fc04a1ce16edef475fea6e0bb1d264410f1..4bbb82bd1712e6103f5231a0b636c4096bc2e34b 100644 --- a/src/store/modules/feature_type.js +++ b/src/store/modules/feature_type.js @@ -22,6 +22,9 @@ const feature_type = { UPDATE_FORM(state, payload) { state.form = payload; }, + EMPTY_FORM(state) { + state.form = null; + }, ADD_CUSTOM_FORM(state, customForm) { state.customForms = [...state.customForms, customForm]; }, @@ -32,6 +35,9 @@ const feature_type = { REMOVE_CUSTOM_FORM(state, payload) { state.customForms = state.customForms.filter(form => form.dataKey !== payload); }, + EMPTY_CUSTOM_FORMS(state) { + state.customForms = []; + }, UPDATE_COLOR_STYLE(state) { // * un peu dirty (mais pas quick) car getter pas réactif avec nested et compliqué de faire dans composants enfants multiples let res = []; for (let form of state.customForms) { @@ -42,9 +48,6 @@ const feature_type = { SET_IMPORT_FEATURE_TYPES_DATA(state, payload) { state.importFeatureTypeData = payload; }, - EMPTY_CUSTOM_FORMS(state) { - state.customForms = []; - }, SET_FILE_NAME_TO_IMPORT(state, payload) { state.filenameToImport = payload; }, @@ -77,14 +80,12 @@ const feature_type = { } //console.log("data", data) - return axios + return axios .post(`${process.env.VUE_APP_DJANGO_API_BASE}feature-types/`, data) .then((response) => { const feature_type_slug = response.data.slug; - console.log(feature_type_slug); - //console.log(response) - //console.log(response.data.slug) - return feature_type_slug; + const status = response.status; + return { feature_type_slug, status }; }) .catch((error) => { console.error(error); @@ -93,7 +94,6 @@ const feature_type = { POST_FEATURES_FROM_GEOJSON({ state, dispatch }, payload) { const { slug, feature_type_slug } = payload - console.log(slug, feature_type_slug) if (state.filenameToImport.size > 0) { var formData = new FormData(); @@ -110,7 +110,7 @@ const feature_type = { }, }) .then((response) => { - if (response.status == 200) { + if (response.status === 200) { dispatch("GET_IMPORTS", feature_type_slug); // TODO : RELOAD DERNIER SIGNALEMENTS } diff --git a/src/views/feature_type/Feature_type_edit.vue b/src/views/feature_type/Feature_type_edit.vue index 5944387e375c6790965ac02bc3045b6aaafb56d8..7cae8875c72d7bdc4b115c94abafa13c3f91a498 100644 --- a/src/views/feature_type/Feature_type_edit.vue +++ b/src/views/feature_type/Feature_type_edit.vue @@ -1,5 +1,10 @@ <template> <div v-frag> + <div id="message" class="fullwidth"> + <div v-if="error" class="ui negative message"> + <p><i class="cross icon"></i> {{ error }}</p> + </div> + </div> <div class="fourteen wide column"> <form id="form-type-edit" @@ -122,7 +127,7 @@ v-if="geojson" class="ui teal icon button" type="button" - @click="postFeatureTypeNfeatures" + @click="postFeatureTypeThenFeatures" > <i class="white save icon"></i> Créer et importer le(s) signalement(s) du geojson @@ -158,6 +163,7 @@ export default { return { action: "create", dataKey: 0, + error: null, geomTypeChoices: [ { value: "linestring", name: "Ligne" }, { value: "point", name: "Point" }, @@ -310,10 +316,10 @@ export default { }); }, - postFeatureType() { + checkForm() { if (this.form.title.value) { this.form.title.errors = []; - this.$store.dispatch("feature_type/POST_FEATURE_TYPE"); + return true; } else if ( !this.form.title.errors.includes("Veuillez compléter ce champ.") // TODO : Gérer les autres champs ) { @@ -322,32 +328,72 @@ export default { .getElementById("errorlist") .scrollIntoView({ block: "end", inline: "nearest" }); } + return false; }, - async postFeatureTypeNfeatures() { - // todo : post feature_type and create & post features - if (this.form.title.value) { - this.form.title.errors = []; + goBackToProject() { + this.$router.push({ + name: "project_detail", + params: { + slug: this.project.slug, + message: "Le nouveau type de signalement a bien été importé", + }, + }); + }, + + postFeatureType() { + if (this.checkForm()) { + this.$store + .dispatch("feature_type/POST_FEATURE_TYPE") + .then(({ status }) => { + console.log(status); + if (status === 201) { + this.goBackToProject(); + } else { + this.displayMessage( + "Une erreur est survenue lors de l'import du type de signalement" + ); + } + }); + } + }, + + postFeatures(feature_type_slug) { + this.$store + .dispatch("feature_type/POST_FEATURES_FROM_GEOJSON", { + slug: this.$route.params.slug, + feature_type_slug, + }) + .then((response) => { + if (response) { + this.goBackToProject(); + } else { + this.displayMessage( + "Une erreur est survenue lors de l'import de signalement." + ); + } + }); + }, + + async postFeatureTypeThenFeatures() { + if (this.checkForm()) { await this.$store .dispatch("feature_type/POST_FEATURE_TYPE") - .then((feature_type_slug) => { - console.log(feature_type_slug); - this.$store.dispatch("feature_type/POST_FEATURES_FROM_GEOJSON", { - slug: this.$route.params.slug, - feature_type_slug: feature_type_slug, - //filenameToImport: this.filenameToImport, - }); + .then(({ feature_type_slug }) => { + if (feature_type_slug) { + this.postFeatures(feature_type_slug); + } }); - } else if ( - !this.form.title.errors.includes("Veuillez compléter ce champ.") // TODO : Gérer les autres champs - ) { - this.form.title.errors.push("Veuillez compléter ce champ."); - document - .getElementById("errorlist") - .scrollIntoView({ block: "end", inline: "nearest" }); } }, + displayMessage(message) { + this.error = message; + document + .getElementById("message") + .scrollIntoView({ block: "end", inline: "nearest" }); + }, + // * Methodes for geojson import * // toNewFeatureType() { this.$router.push({ @@ -384,7 +430,6 @@ export default { }, importGeoJson() { - // TODO : VALIDATION IF A JSONDICT HAS NOT FEATURES if (this.geojson.features && this.geojson.features.length) { //* in order to get feature_type properties, the first feature is enough const { properties, geometry } = this.geojson.features[0]; @@ -395,22 +440,15 @@ export default { //* loop properties to create a customForm for each of them for (const [key, val] of Object.entries(properties)) { //* check that the property is not a keyword from the backend or map style - // todo: add map style keywords) + // todo: add map style keywords if (!this.reservedKeywords.includes(key)) { const customForm = { label: { value: key || "" }, name: { value: key || "" }, - // todo : increment position - position: { value: this.dataKey }, // * use dataKey incremented at addCustomForm + position: { value: this.dataKey }, // * use dataKey already incremented by addCustomForm field_type: { value: this.transformProperties(val) }, // * guessed from the type options: { value: [] }, // * not available in export }; - console.log( - "val", - val, - "transformProperties", - this.transformProperties(val) - ); this.addCustomForm(customForm); } } @@ -449,23 +487,9 @@ export default { this.importGeoJson(); } }, - /* beforeDestroy() { - this.RESET(); - }, */ - /* checkform() { - let form_idx = $('#id_form-TOTAL_FORMS').val(); - for (var i=0; i <= form_idx;i++ ){ - let id_form_options = 'id_form-' + i + '-options'; - let id_form_options_elem = document.getElementById(id_form_options); - if (typeof id_form_options_elem !== null && id_form_options_elem !== 'undefined'){ - let id_form_options_val = document.getElementById(id_form_options); - if (id_form_options_val != undefined && id_form_options_val != null){ - let new_id_form_options_val = document.getElementById(id_form_options).value.replace(/^,|,$/g, ''); - document.getElementById(id_form_options).value = new_id_form_options_val; - } - } - } - } */ + beforeDestroy() { + this.$store.commit("feature_type/EMPTY_FORM"); + }, }; </script> diff --git a/src/views/project/Project_detail.vue b/src/views/project/Project_detail.vue index 253b6ea2688b97cd9172b35e4ee79df2b9c71518..2a516156cff502c437cf10c86bd5c84d599f853f 100644 --- a/src/views/project/Project_detail.vue +++ b/src/views/project/Project_detail.vue @@ -1,6 +1,15 @@ <template> <div v-frag> <div v-frag v-if="permissions.can_view_project && project"> + <div id="message" class="fullwidth"> + <div v-if="tempMessage" class="ui positive message"> + <!-- <i class="close icon"></i> --> + <!-- <div class="header">You are eligible for a reward</div> --> + + <p><i class="check icon"></i> {{ tempMessage }}</p> + </div> + </div> + <div class="row"> <div class="four wide middle aligned column"> <img @@ -452,6 +461,8 @@ import { mapGetters, mapState } from "vuex"; export default { name: "Project_details", + props: ["message"], + directives: { frag, }, @@ -479,8 +490,10 @@ export default { can_view_project: true, can_create_feature: true, }, + tempMessage: null, }; }, + computed: { ...mapGetters(["project"]), ...mapState("feature_type", ["feature_types"]), @@ -491,21 +504,15 @@ export default { return this.$store.state.feature.features.slice(-5); }, }, - created() { - this.$store.dispatch("GET_PROJECT_INFO", this.slug); - }, - - mounted() { - if (this.project) { - this.$store.dispatch("map/INITIATE_MAP"); - } - }, methods: { toNewFeatureType() { this.$router.push({ name: "ajouter-type-signalement", - params: { geojson: this.geojsonImport, filenameToImport: this.filenameToImport }, + params: { + geojson: this.geojsonImport, + filenameToImport: this.filenameToImport, + }, }); }, onFileChange(e) { @@ -521,13 +528,35 @@ export default { }; fr.readAsText(this.filenameToImport); //* stock filename to import features afterward - this.$store.commit("feature_type/SET_FILE_NAME_TO_IMPORT", this.filenameToImport) + this.$store.commit( + "feature_type/SET_FILE_NAME_TO_IMPORT", + this.filenameToImport + ); } }, subsribeProject() { console.log("Subsribe to project"); }, }, + + created() { + this.$store.dispatch("GET_PROJECT_INFO", this.slug); + }, + + mounted() { + if (this.project) { + this.$store.dispatch("map/INITIATE_MAP"); + } + if (this.message) { + this.tempMessage = this.message; + document + .getElementById("message") + .scrollIntoView({ block: "end", inline: "nearest" }); + setTimeout(() => { + this.tempMessage = null; + }, 5000); + } + }, }; </script> @@ -555,4 +584,7 @@ export default { #button-import { padding-top: 0.5em; } +.fullwidth { + width: 100%; +} </style> \ No newline at end of file