diff --git a/dump.rdb b/dump.rdb new file mode 100644 index 0000000000000000000000000000000000000000..8783eda81682fd23bb8226256569cdf2cbb774c8 Binary files /dev/null and b/dump.rdb differ diff --git a/src/components/feature/FeatureLinkedForm.vue b/src/components/feature/FeatureLinkedForm.vue index 80f10d776a4754d01cdcfb0d1568a566964d5e8b..02cd0bfe25a382e920681ea126841bc5ac80f971 100644 --- a/src/components/feature/FeatureLinkedForm.vue +++ b/src/components/feature/FeatureLinkedForm.vue @@ -20,7 +20,7 @@ form.relation_type.label }}</label> <Dropdown - :options="form.relation_type.field.choices" + :options="relationTypeChoices" :selected="selected_relation_type" :selection.sync="selected_relation_type" /> @@ -54,16 +54,65 @@ export default { Dropdown, }, + data() { + return { + form: { + errors: null, + relation_type: { + errors: null, + id_for_label: "relation_type", + html_name: "relation_type", + label: "Type de liaison", + value: { + name: "Doublon", + value: "doublon", + }, + }, + feature_to: { + errors: null, + id_for_label: "feature_to", + field: { + max_length: 30, + }, + html_name: "feature_to", + label: "Signalement lié", + value: { + name: "", + value: "", + }, + }, + }, + relationTypeChoices: [ + { name: "Doublon", value: "doublon" }, + { name: "Remplace", value: "remplace" }, + { name: "Est remplacé par", value: "est_remplace_par" }, + { name: "Dépend de", value: "depend_de" }, + ], + }; + }, + computed: { featureOptions: function () { - return this.features.map( - (el) => `${el.title} (${el.display_creator} - ${el.created_on})` - ); + return this.features + .filter( + (el) => + el.feature_type.slug === this.$route.params.slug_type_signal && //* filter only for the same feature + el.feature_id !== this.$route.params.slug_signal //* filter out current feature + ) + .map((el) => { + return { + name: `${el.title} (${el.display_creator} - ${this.formatDate( + el.created_on + )})`, + value: el.feature_id, + }; + }); }, + selected_relation_type: { // getter get() { - return this.form.relation_type.value; + return this.form.relation_type.value.name; }, // setter set(newValue) { @@ -71,10 +120,11 @@ export default { this.updateStore(); }, }, + selected_feature_to: { // getter get() { - return this.form.feature_to.value; + return this.form.feature_to.value.name; }, // setter set(newValue) { @@ -84,44 +134,35 @@ export default { }, }, - data() { - return { - form: { - errors: null, - relation_type: { - errors: null, - id_for_label: "relation_type", - field: { - choices: ["Doublon", "Remplace", "Est remplacé par", "Dépend de"], - }, - html_name: "relation_type", - label: "Type de liaison", - value: "Doublon", - }, - feature_to: { - errors: null, - id_for_label: "feature_to", - field: { - max_length: 30, - }, - html_name: "feature_to", - label: "Signalement lié", - value: "", - }, - }, - }; + watch: { + featureOptions(newValue) { + if (newValue) { + this.getExistingFeature_to(newValue); + } + }, }, + methods: { + formatDate(value) { + let date = new Date(value); + date = date.toLocaleString().replace(",", ""); + return date.substr(0, date.length - 3); //* quick & dirty way to remove seconds from date + }, + remove_linked_formset() { this.$store.commit("feature/REMOVE_LINKED_FORM", this.linkedForm.dataKey); }, + updateStore() { this.$store.commit("feature/UPDATE_LINKED_FORM", { dataKey: this.linkedForm.dataKey, - relation_type: this.form.relation_type.value, - feature_to: this.form.feature_to.value, + relation_type: this.form.relation_type.value.value, + feature_to: { + feature_id: this.form.feature_to.value.value, + }, }); }, + checkForm() { if (this.form.feature_to.value === "") { this.form.errors = [ @@ -135,6 +176,30 @@ export default { this.form.errors = []; return true; }, + + getExistingFeature_to(featureOptions) { + const feature_to = featureOptions.find( + (el) => el.value === this.linkedForm.feature_to.feature_id + ); + if (feature_to) { + this.form.feature_to.value = feature_to; + } + }, + + getExistingRelation_type() { + const relation_type = this.relationTypeChoices.find( + (el) => el.value === this.linkedForm.relation_type + ); + if (relation_type) { + this.form.relation_type.value = relation_type; + } + }, + }, + + mounted() { + if (this.linkedForm.relation_type) { + this.getExistingRelation_type(); + } }, }; </script> \ No newline at end of file diff --git a/src/store/index.js b/src/store/index.js index 5035d682a0b278a2279c895d9deb3318b400fd56..3060f1beb6337b71f7bbe3058bf2fb65d0b082d3 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -235,12 +235,12 @@ export default new Vuex.Store({ }); }, - GET_PROJECT_INFO({ state, commit, dispatch }, slug) { + async GET_PROJECT_INFO({ state, commit, dispatch }, slug) { commit("SET_PROJECT_SLUG", slug); - dispatch("GET_PROJECT_LAST_MESSAGES", slug); - dispatch("feature_type/GET_PROJECT_FEATURE_TYPES", slug); - dispatch("feature/GET_PROJECT_FEATURES", slug); - if (state.user) dispatch("map/GET_BASEMAPS", slug); + await dispatch("GET_PROJECT_LAST_MESSAGES", slug); + await dispatch("feature_type/GET_PROJECT_FEATURE_TYPES", slug); + await dispatch("feature/GET_PROJECT_FEATURES", slug); + if (state.user) await dispatch("map/GET_BASEMAPS", slug); }, GET_PROJECT_LAST_MESSAGES({ commit }, project_slug) { diff --git a/src/store/modules/feature.js b/src/store/modules/feature.js index b1ab9cac323c775fc41cc85482de36c232ef2133..0899a35162c5e4dd5eace6d497d316e152ed81c8 100644 --- a/src/store/modules/feature.js +++ b/src/store/modules/feature.js @@ -47,8 +47,8 @@ const feature = { CLEAR_ATTACHMENT_FORM(state) { state.attachmentFormset = []; }, - ADD_LINKED_FORM(state, dataKey) { - state.linkedFormset = [...state.linkedFormset, { dataKey }]; + ADD_LINKED_FORM(state, linkedFormset) { + state.linkedFormset = [...state.linkedFormset, linkedFormset]; }, UPDATE_LINKED_FORM(state, payload) { const index = state.linkedFormset.findIndex((el) => el.dataKey === payload.dataKey); @@ -60,12 +60,15 @@ const feature = { SET_LINKED_FEATURES(state, payload) { state.linked_features = payload; }, + CLEAR_LINKED_FORM(state) { + state.linkedFormset = []; + }, }, getters: { }, actions: { GET_PROJECT_FEATURES({ commit, rootState }, project_slug) { - axios + return axios .get(`${rootState.configuration.VUE_APP_DJANGO_API_BASE}projects/${project_slug}/feature/`) .then((response) => { if (response.status === 200 && response.data) { @@ -80,6 +83,23 @@ const feature = { }, SEND_FEATURE({ state, rootState, dispatch }, routeName) { + const message = routeName === "editer-signalement" ? "Le signalement a été mis à jour" : "Le signalement a été crée"; + function redirect(featureId) { + router.push({ + name: "details-signalement", + params: { + slug_type_signal: rootState.feature_type.current_feature_type_slug, + slug_signal: featureId, + message, + }, + }); + } + async function handleOtherForms(featureId) { + await dispatch("SEND_ATTACHMENTS", featureId) + await dispatch("PUT_LINKED_FEATURES", featureId) + redirect(featureId); + } + let extraFormObject = {}; //* prepare an object to be flatten in properties of geojson for (const field of state.extra_form) { extraFormObject[field.name] = field.value; @@ -103,14 +123,11 @@ const feature = { .put(`${rootState.configuration.VUE_APP_DJANGO_API_BASE}features/${state.form.feature_id}/`, geojson) .then((response) => { if (response.status === 200 && response.data) { - router.push({ - name: "details-signalement", - params: { - slug_type_signal: rootState.feature_type.current_feature_type_slug, - slug_signal: state.form.feature_id, - //message: "Le signalement a été mis à jour", - }, - }); + if (state.attachmentFormset.length > 0 || state.linkedFormset.length > 0) { + handleOtherForms(response.data.id) + } else { + redirect(response.data.id) + } } }) .catch((error) => { @@ -121,15 +138,11 @@ const feature = { .post(`${rootState.configuration.VUE_APP_DJANGO_API_BASE}features/`, geojson) .then((response) => { if (response.status === 201 && response.data) { - dispatch("SEND_ATTACHMENTS", response.data.id) - router.push({ - name: "details-signalement", - params: { - slug_type_signal: rootState.feature_type.current_feature_type_slug, - slug_signal: response.data.id, - //message: "Le signalement a été crée", - }, - }); + if (state.attachmentFormset.length > 0 || state.linkedFormset.length > 0) { + handleOtherForms(response.data.id) + } else { + redirect(response.data.id) + } } }) .catch((error) => { @@ -140,27 +153,43 @@ const feature = { SEND_ATTACHMENTS({ state, rootState }, featureId) { for (let attacht of state.attachmentFormset) { - let formdata = new FormData(); - formdata.append("file", attacht.fileToImport, attacht.fileToImport.name); - const data = { - title: attacht.title, - info: attacht.info, + if (attacht.fileToImport) { //* if no new file imported abort, until beeing able to do PUT + let formdata = new FormData(); + formdata.append("file", attacht.fileToImport, attacht.fileToImport.name); + const data = { + title: attacht.title, + info: attacht.info, + } + formdata.append("data", JSON.stringify(data)); + axios + .post(`${rootState.configuration.VUE_APP_DJANGO_API_BASE}features/${featureId}/attachments/`, formdata) + .then((response) => { + if (response.status === 200 && response.data) { + console.log(response, response.data) + return "La pièce jointe a bien été ajouté" + } + }) + .catch((error) => { + throw error; + }); } - formdata.append("data", JSON.stringify(data)); - axios - .post(`${rootState.configuration.VUE_APP_DJANGO_API_BASE}features/${featureId}/attachments/`, formdata) - .then((response) => { - if (response.status === 200 && response.data) { - console.log(response, response.data) - return "La pièce jointe a bien été ajouté" - } - }) - .catch((error) => { - throw error; - }); } }, + PUT_LINKED_FEATURES({ state, rootState }, featureId) { + return axios + .put(`${rootState.configuration.VUE_APP_DJANGO_API_BASE}features/${featureId}/feature-links/`, state.linkedFormset) + .then((response) => { + if (response.status === 200 && response.data) { + console.log(response, response.data) + return "La relation a bien été ajouté" + } + }) + .catch((error) => { + throw error; + }); + }, + /* GET_FEATURE_LINK({ commit }, featureId) { featureAPI .getlinked_features(featureId) diff --git a/src/views/feature/Feature_detail.vue b/src/views/feature/Feature_detail.vue index e24f5574b2dc64d6cdfa7a363cb68eb4b8fbf7b5..951ae83cd156f7b459544a87f0d177d62ac79414 100644 --- a/src/views/feature/Feature_detail.vue +++ b/src/views/feature/Feature_detail.vue @@ -144,7 +144,7 @@ :key="link.feature_to.title + index" > <td> - {{ link.relation_type }} + {{ link.relation_type_display }} <router-link :to="{ name: 'details-signalement', @@ -155,7 +155,7 @@ }" >{{ link.feature_to.title }}</router-link > - ({{ link.feature_to.creator }} - + ({{ link.feature_to.display_creator }} - {{ link.feature_to.created_on }}) </td> </tr> diff --git a/src/views/feature/Feature_edit.vue b/src/views/feature/Feature_edit.vue index 600cdedb283ec90d975c3722728d5b6f079be435..bb7cd9ca21d8820612073e7353807b539ae561b4 100644 --- a/src/views/feature/Feature_edit.vue +++ b/src/views/feature/Feature_edit.vue @@ -1,6 +1,12 @@ <template> <div v-frag> - <script type="application/javascript" :src="baseUrl+'/resources/leaflet-control-geocoder-1.13.0/Control.Geocoder.js'"></script> + <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 }}" @@ -241,12 +247,11 @@ import { mapUtil } from "@/assets/js/map-util.js"; const axios = require("axios"); 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; - })('csrftoken'); - +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"); export default { name: "Feature_edit", @@ -266,8 +271,8 @@ export default { data() { return { map: null, - feature_type:null, - baseUrl:this.$store.state.configuration.BASE_URL, + feature_type: null, + baseUrl: this.$store.state.configuration.BASE_URL, file: null, showGeoRef: false, showGeoPositionBtn: true, @@ -275,23 +280,23 @@ export default { erreurUploadMessage: null, attachmentDataKey: 0, linkedDataKey: 0, - statusChoicesFilter:[], + statusChoicesFilter: [], statusChoices: [ { name: "Brouillon", value: "draft", }, - { + { name: "Publié", - value: "published" + value: "published", }, - { + { name: "Archivé", - value: "archived" + value: "archived", }, - { + { name: "En attente de publication", - value: "pending" + value: "pending", }, ], form: { @@ -338,6 +343,7 @@ export default { "linkedFormset", "features", "extra_form", + "linked_features", ]), field_title() { if (this.feature_type) { @@ -369,30 +375,31 @@ export default { }, }, - watch: { + /* watch: { feature(newValue) { if (this.$route.name === "editer-signalement") { this.initForm(); this.initExtraForms(newValue); } }, - }, + }, */ methods: { - makeStatusChoicesFilter(){ - let newStatusChoices = this.statusChoices - if (this.project){ - if (!this.project.moderation){ - newStatusChoices = [] - this.statusChoices.forEach(function(status) { - if (status.value !== 'pending') { - newStatusChoices.push(status) + makeStatusChoicesFilter() { + let newStatusChoices = this.statusChoices; + if (this.project) { + if (!this.project.moderation) { + newStatusChoices = []; + this.statusChoices.forEach(function (status) { + if (status.value !== "pending") { + newStatusChoices.push(status); } }); } } - this.statusChoicesFilter = newStatusChoices + this.statusChoicesFilter = newStatusChoices; }, + initForm() { if (this.currentRouteName === "editer-signalement") { for (let key in this.feature) { @@ -410,6 +417,7 @@ export default { this.updateStore(); } }, + create_point_geoposition() { function success(position) { const latitude = position.coords.latitude; @@ -434,10 +442,12 @@ export default { ); } }, + handleFileUpload() { this.file = this.$refs.file.files[0]; console.log(">>>> 1st element in files array >>>> ", this.file); }, + georeferencement() { console.log("georeferencement"); const url = `${this.$store.state.configuration.VUE_APP_DJANGO_API_BASE}exif-geom-reader/`; @@ -452,25 +462,24 @@ export default { }, }) .then(function (response) { - console.log("SUCCESS!!",response.data); - if(response.data.geom.indexOf('POINT')>=0){ - let regexp=/POINT\s\((.*)\s(.*)\)/; + console.log("SUCCESS!!", response.data); + if (response.data.geom.indexOf("POINT") >= 0) { + let regexp = /POINT\s\((.*)\s(.*)\)/; var arr = regexp.exec(response.data.geom); - - let json={ "type": "Feature", - "geometry": { - "type": "Point", - "coordinates": [arr[1], arr[2]] + + let json = { + type: "Feature", + geometry: { + type: "Point", + coordinates: [arr[1], arr[2]], }, - "properties": { - } + properties: {}, }; - self.updateMap(self.map, json) - self.updateGeomField(json) + self.updateMap(self.map, json); + self.updateGeomField(json); // Set Attachment //self.addAttachment(self.file) } - }) .catch(function (response) { console.log("FAILURE!!"); @@ -503,7 +512,6 @@ export default { addExistingAttachementFormset(attachementFormset) { for (const attachment of attachementFormset) { - console.log("attachment", attachment); this.$store.commit("feature/ADD_ATTACHMENT_FORM", { dataKey: this.attachmentDataKey, title: attachment.title, @@ -516,10 +524,23 @@ export default { }, add_linked_formset() { - this.$store.commit("feature/ADD_LINKED_FORM", this.linkedDataKey); // * create an object with the counter in store + this.$store.commit("feature/ADD_LINKED_FORM", { + dataKey: this.linkedDataKey, + }); // * create an object with the counter in store this.linkedDataKey += 1; // * increment counter for key in v-for }, + addExistingLinkedFormset(linkedFormset) { + for (const linked of linkedFormset) { + this.$store.commit("feature/ADD_LINKED_FORM", { + dataKey: this.linkedDataKey, + relation_type: linked.relation_type, + feature_to: linked.feature_to, + }); + this.linkedDataKey += 1; + } + }, + updateStore() { this.$store.commit("feature/UPDATE_FORM", { title: this.form.title.value, @@ -780,8 +801,8 @@ export default { ); }, - updateMap(map, geomFeatureJSON) { - this.drawnItems.clearLayers(); + updateMap(geomFeatureJSON) { + if (this.drawnItems) this.drawnItems.clearLayers(); console.log("update map"); var geomType = this.feature_type.geom_type; if (geomFeatureJSON) { @@ -825,7 +846,7 @@ export default { axios .get(url) .then((response) => { - //console.log(response); + console.log(response.data.features); const features = response.data.features; if (features) { const allFeaturesExceptCurrent = features.filter( @@ -863,11 +884,25 @@ export default { this.erreurGeolocalisationMessage = ""; } }, + + getFeatureAttachments() { + featureAPI + .getFeatureAttachments(this.$route.params.slug_signal) + .then((data) => this.addExistingAttachementFormset(data)); + }, + + getLinkedFeatures() { + featureAPI + .getFeatureLinks(this.$route.params.slug_signal) + .then((data) => this.addExistingLinkedFormset(data)); + }, }, created() { if (!this.project) { - this.project = this.$store.state.projects.find((project) => project.slug === this.$store.state.project_slug); + this.project = this.$store.state.projects.find( + (project) => project.slug === this.$store.state.project_slug + ); this.makeStatusChoicesFilter(); } @@ -876,37 +911,40 @@ export default { this.$route.params.slug_type_signal ); - // todo : mutualize in store with feature_detail.vue if (this.$route.params.slug_signal) { - featureAPI - .getFeatureAttachments(this.$route.params.slug_signal) - .then((data) => this.addExistingAttachementFormset(data)); - } else { - //* be sure that previous attachemntFormset has been cleared for creation - this.$store.commit("feature/CLEAR_ATTACHMENT_FORM"); + this.getFeatureAttachments(); + this.getLinkedFeatures(); } }, mounted() { - let ftSlug=this.$route.params.slug_type_signal; - this.$store.dispatch("GET_PROJECT_INFO", this.$route.params.slug).then(data=>{ - console.log(data) + let ftSlug = this.$route.params.slug_type_signal; + this.$store + .dispatch("GET_PROJECT_INFO", this.$route.params.slug) + .then((data) => { + console.log(data); this.initForm(); this.initMap(); - this.feature_type=this.$store.state.feature_type.feature_types.find( - (el) => el.slug === ftSlug - ); + console.log(this.$store.state.feature_type.feature_types); + this.feature_type = this.$store.state.feature_type.feature_types.find( + (el) => el.slug === ftSlug + ); this.onFeatureTypeLoaded(); this.initExtraForms(); setTimeout( function () { mapUtil.addGeocoders(this.$store.state.configuration); - }.bind(this), 1000); - }) - + }.bind(this), + 1000 + ); + }); + }, - + destroyed() { + //* be sure that previous Formset have been cleared for creation + this.$store.commit("feature/CLEAR_ATTACHMENT_FORM"); + this.$store.commit("feature/CLEAR_LINKED_FORM"); }, }; </script>