diff --git a/src/App.vue b/src/App.vue index 03b56a1ec3cd57c660fa6607e19535ca01eeb91a..f3850df87b3f7a0a6960e2183b903171ac896271 100644 --- a/src/App.vue +++ b/src/App.vue @@ -74,7 +74,9 @@ v-if="user && user.is_administrator" class="item ui label vertical" > - <span> {{ USER_LEVEL_PROJECTS }}</span> + <span v-if="project"> + {{ USER_LEVEL_PROJECTS[project.slug] }}</span + > <br /> <span v-if="user.is_administrator"> Gestionnaire métier </span> </div> @@ -95,26 +97,26 @@ <div class="ui stackable grid centered container"> <!-- // todo : add messages --> <!-- {% if messages %} --> - <!-- <div v-if="false" class="row"> - <div class="fourteen wide column"> - {% for message in messages %} - {% if message.tags == 'success'%} - <div class="ui positive message"> - {% else %} + <div v-if="messages" class="row"> + <div class="fourteen wide column"> + <div + v-for="(message, index) in messages" + :key="'message-' + index" + class="ui positive message" + > <div class="ui info message"> - {% endif %} - {% endfor %} - <div class="header"> - <i class="info circle icon"></i> Informations + <div class="header"> + <i class="info circle icon"></i> Informations + </div> + <ul class="list"> + {{ + message.comment + }} + </ul> + </div> </div> - <ul class="list"> - {% for message in messages %} - {{ message }} - {% endfor %} - </ul> </div> </div> - </div> --> <!-- {% endif %} --> <router-view /> <!-- //* Les views sont injectées ici --> @@ -141,6 +143,7 @@ export default { data() { return { menuIsOpen: false, + messages: null, }; }, diff --git a/src/router/index.js b/src/router/index.js index c7fef2cd6b4ac90f16fd87ca453c03eaf7675ab3..fe3fdd93aab8d11551432319665845fdaeebd798 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -101,7 +101,7 @@ const routes = [ name: 'ajouter-signalement', component: () => import('../views/feature/Feature_edit.vue') }, - { // todo : créer le template + { path: '/projet/:slug/type-signalement/:slug_type_signal/signalement/:slug_signal', name: 'details-signalement', component: () => import('../views/feature/Feature_detail.vue') diff --git a/src/store/index.js b/src/store/index.js index 85597f12aaa0972ee3a7474ad3a18d65ae7e1b7b..1e65b11f22a19f7ae60fe22e40f035c444a7ee3c 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -35,6 +35,7 @@ export default new Vuex.Store({ user: false, project_slug: null, projects: [], + last_comments: [], staticPages: null, SSO_SETTED: false, USER_LEVEL_PROJECTS: null @@ -68,6 +69,9 @@ export default new Vuex.Store({ SET_LOGGED(state, value) { state.logged = value }, + SET_PROJECT_COMMENTS(state, last_comments) { + state.last_comments = last_comments + }, }, getters: { @@ -109,7 +113,6 @@ export default new Vuex.Store({ password: payload.password, }) .then((response) => { - console.log(router.options.routerHistory) // * use stored previous route to go back after login if page not open on login at first const routerHistory = router.options.routerHistory[0].name !== "login" ? router.options.routerHistory : "/" commit("SET_USER", response.data.user); @@ -117,47 +120,79 @@ export default new Vuex.Store({ dispatch("GET_USER_LEVEL_PROJECTS"); }) .catch(() => { - commit("SET_USER", false) + commit("SET_USER", false); }); } }, - USER_INFO({ commit }) { // ? not used currently ? + USER_INFO({ commit }) { axios .get(`${DJANGO_API_BASE}user_info/`) .then((response) => { const user = response.data.user; - commit("SET_USER", user) - window.localStorage.setItem("user", JSON.stringify(user)) + commit("SET_USER", user); + window.localStorage.setItem("user", JSON.stringify(user)); }) // todo: ajouter au localestorage .catch(() => { router.push({ name: "login" }); }); }, - LOGOUT({ commit }) { // ? logout dans django ? + LOGOUT({ commit }) { // ? logout bien dans django ? axios .get(`${DJANGO_API_BASE}logout/`) .then((response) => { - console.log(response) - commit("SET_USER", false) // ? better false or null - commit("SET_USER_LEVEL_PROJECTS", null) + console.log(response); + commit("SET_USER", false); // ? better false or null + commit("SET_USER_LEVEL_PROJECTS", null); }) .catch((error) => { - throw error + throw error; }); - }, GET_USER_LEVEL_PROJECTS({ commit }) { - commit("SET_USER_LEVEL_PROJECTS", "Administrateur projet") // todo : use authentification) - /* axios + axios .get(`${DJANGO_API_BASE}user_level_project/`) .then((response) => (commit("SET_USER_LEVEL_PROJECTS", response.data))) .catch((error) => { throw error; - }); */ + }); + }, + + GET_PROJECT_INFO({ commit, dispatch }, slug) { + commit("SET_PROJECT_SLUG", slug); + dispatch("GET_PROJECT_LAST_MESSAGES", slug); + dispatch("GET_PROJECT_FEATURES", slug); + dispatch("GET_PROJECT_FEATURE_TYPES", slug); + }, + + GET_PROJECT_LAST_MESSAGES({ commit }, project_slug) { + axios + .get(`${DJANGO_API_BASE}projet/${project_slug}/comments`) + .then((response) => commit("SET_PROJECT_COMMENTS", response.data.last_comments)) + .catch((error) => { + throw error; + }); + }, + + GET_PROJECT_FEATURES({ commit }, project_slug) { + axios + .get(`${DJANGO_API_BASE}projet/${project_slug}/feature`) + .then((response) => commit("feature/SET_FEATURES", response.data.features)) + .catch((error) => { + throw error; + }); + }, + + GET_PROJECT_FEATURE_TYPES({ commit }, project_slug) { + axios + .get(`${DJANGO_API_BASE}projet/${project_slug}/feature_types`) + .then((response) => commit("feature_type/SET_FEATURE_TYPES", response.data.feature_types)) + .catch((error) => { + throw error; + }); }, /* GET_PROJECT({ commit }, project_slug) { axios diff --git a/src/store/modules/feature.js b/src/store/modules/feature.js index 020ba7ffa4fb631f8e0ca1e4d72c15ce8a5ed1c2..5db97dba3e7f4d7695be00aca55201578d3c05cb 100644 --- a/src/store/modules/feature.js +++ b/src/store/modules/feature.js @@ -110,6 +110,9 @@ const feature = { ] }, mutations: { + SET_FEATURES(state, features) { + state.features = features; + }, UPDATE_FORM(state, payload) { state.form = payload; }, diff --git a/src/store/modules/feature_type.js b/src/store/modules/feature_type.js index b07e19a01ace26530e8dc569e1892182ee58e6f9..070498e0326bb53d89bb95537b61dbbade20f4fb 100644 --- a/src/store/modules/feature_type.js +++ b/src/store/modules/feature_type.js @@ -41,6 +41,9 @@ const feature_type = { ], }, mutations: { + SET_FEATURE_TYPES(state, feature_types) { + state.feature_types = feature_types; + }, SET_CURRENT_FEATURE_TYPE_SLUG(state, payload) { state.current_feature_type_slug = payload; }, diff --git a/src/views/Index.vue b/src/views/Index.vue index cf9930c389774fdbcd53c3fb221e6aeb3f16bd66..a8038847b85a79fa84aaef9b5fc6f8b91bc4faf8 100644 --- a/src/views/Index.vue +++ b/src/views/Index.vue @@ -70,7 +70,7 @@ Mon niveau d'autorisation : <!-- //todo: get this value --> <!-- {{ USER_LEVEL_PROJECTS|lookup:project.slug }} --> - {{ USER_LEVEL_PROJECTS }} + {{ USER_LEVEL_PROJECTS[project.slug] }} {{ user && user.is_administrator ? "+ Gestionnaire métier" : "" }} </span> </div> @@ -115,11 +115,5 @@ export default { APPLICATION_NAME: () => process.env.VUE_APP_APPLICATION_NAME, APPLICATION_ABSTRACT: () => process.env.VUE_APP_APPLICATION_ABSTRACT, }, - created() { - // * delete selected project to hide project menu in header - if (this.$store.getters.project) { - this.$store.commit("SET_PROJECT_SLUG", null); - } - }, }; </script> \ No newline at end of file diff --git a/src/views/feature/Feature_detail.vue b/src/views/feature/Feature_detail.vue index 17bcd83d1d85e69005b2a734b60f41e206a08d30..95baee1547f4fe473695d0cfd7d91bafd109596b 100644 --- a/src/views/feature/Feature_detail.vue +++ b/src/views/feature/Feature_detail.vue @@ -475,8 +475,10 @@ export default { computed: { ...mapState(["user"]), feature: function () { - return this.$store.state.feature.features.find( - (el) => el.title === this.$route.params.slug_signal + return ( + this.$store.state.feature.features.find( + (el) => el.feature_id === this.$route.params.slug_signal + ) || [] ); }, linked_features: function () { @@ -513,8 +515,9 @@ export default { }, created() { + console.log; if (!this.project) { - this.$store.commit("SET_PROJECT_SLUG", this.$route.params.slug); + this.$store.dispatch("GET_PROJECT_INFO", this.$route.params.slug); } this.$store.commit( "feature_type/SET_CURRENT_FEATURE_TYPE_SLUG", diff --git a/src/views/feature/Feature_edit.vue b/src/views/feature/Feature_edit.vue index 88c3af60636e9abf8741eff00cff46791090e84e..cbec88b13cfcdd9c37c9a90dc9e1165a96b6ceaf 100644 --- a/src/views/feature/Feature_edit.vue +++ b/src/views/feature/Feature_edit.vue @@ -405,7 +405,7 @@ export default { }, created() { if (!this.project) { - this.$store.commit("SET_PROJECT_SLUG", this.$route.params.slug); + this.$store.dispatch("GET_PROJECT_INFO", this.$route.params.slug); } this.$store.commit( "feature_type/SET_CURRENT_FEATURE_TYPE_SLUG", diff --git a/src/views/feature/Feature_list.vue b/src/views/feature/Feature_list.vue index 9eec2c540833d3b985b8ae3f7af35fee0e0ca023..ed161fdb14aa7083b41ecbfa8921476eee55d188 100644 --- a/src/views/feature/Feature_list.vue +++ b/src/views/feature/Feature_list.vue @@ -277,7 +277,7 @@ export default { created() { if (!this.project) { - this.$store.commit("SET_PROJECT_SLUG", this.$route.params.slug); + this.$store.dispatch("GET_PROJECT_MESSAGES", this.$route.params.slug); } }, mounted() { diff --git a/src/views/feature_type/Feature_type_detail.vue b/src/views/feature_type/Feature_type_detail.vue index acd5e177d096c2cd038dabee60feba326008cb04..8efb0803a07aad89909db1dc60c04eb2489cd821 100644 --- a/src/views/feature_type/Feature_type_detail.vue +++ b/src/views/feature_type/Feature_type_detail.vue @@ -259,7 +259,7 @@ export default { created() { if (!this.project) { - this.$store.commit("SET_PROJECT_SLUG", this.$route.params.slug); + this.$store.dispatch("GET_PROJECT_INFO", this.$route.params.slug); } this.getImports(); }, diff --git a/src/views/feature_type/Feature_type_edit.vue b/src/views/feature_type/Feature_type_edit.vue index c722b3986471e2e2b2ca81060d92f3b421d0237c..bf7485961082999cfc8c8146eef7520efd212cee 100644 --- a/src/views/feature_type/Feature_type_edit.vue +++ b/src/views/feature_type/Feature_type_edit.vue @@ -277,7 +277,7 @@ export default { created() { if (!this.project) { - this.$store.commit("SET_PROJECT_SLUG", this.$route.params.slug); + this.$store.dispatch("GET_PROJECT_INFO", this.$route.params.slug); } this.$store.commit( "feature_type/SET_CURRENT_FEATURE_TYPE_SLUG", diff --git a/src/views/project/Project_detail.vue b/src/views/project/Project_detail.vue index 5c4ae9d2378e5da94bfef10aa4885f5f890ee036..9a440bdf370d1dfd6c5eb209bea2b46c05437a41 100644 --- a/src/views/project/Project_detail.vue +++ b/src/views/project/Project_detail.vue @@ -42,7 +42,7 @@ <!-- {% endif %} {% if project and permissions|lookup:'can_update_project' %} --> <router-link - v-if="$store.state.user" + v-if="user" :to="{ name: 'project_edit', params: { slug: project.slug } }" class="ui button button-hover-orange" data-tooltip="Modifier le projet" @@ -188,47 +188,45 @@ </router-link> </div> <div class="nouveau-type-signalement"> - <div - class="ui compact basic button button-hover-green" - > - <div - onclick="document.getElementById('json_file').click()" - > - <label - class="ui " - for="json_file" - > - <i class="ui plus icon"></i> - <span class="label">Créer un nouveau type de signalement avec un geojson</span> - </label> - <input - type="file" - accept="application/json, .json, .geojson" - style="display: none" - name="json_file" - id="json_file" - @change="onFileChange" + <div class="ui compact basic button button-hover-green"> + <div onclick="document.getElementById('json_file').click()"> + <label class="ui" for="json_file"> + <i class="ui plus icon"></i> + <span class="label" + >Créer un nouveau type de signalement avec un geojson</span + > + </label> + <input + type="file" + accept="application/json, .json, .geojson" + style="display: none" + name="json_file" + id="json_file" + @change="onFileChange" /> + </div> + </div> + <br /> + <div id="button-import" v-if="filenameToImport.size > 0"> + <button + :disabled="filenameToImport.size == 0" + @click="importGeoJson" + class="ui fluid teal icon button" + > + <i class="upload icon"></i> Lancer l'import avec le fichier + {{ filenameToImport.name }} + </button> </div> - </div> - <br> - <div id="button-import" v-if="filenameToImport.size>0"> - <button - :disabled="filenameToImport.size == 0" - @click="importGeoJson" class="ui fluid teal icon button"> - <i class="upload icon"></i> Lancer l'import avec le fichier {{filenameToImport.name}} - </button> </div> </div> - </div> - <div class="seven wide column"> - <router-link - :to="{ name: 'liste-signalements', params: { slug: project.slug } }" - class="item" - > - <div id="map"></div> - </router-link> - </div> + <div class="seven wide column"> + <router-link + :to="{ name: 'liste-signalements', params: { slug: project.slug } }" + class="item" + > + <div id="map"></div> + </router-link> + </div> </div> <div class="row"> @@ -251,6 +249,7 @@ :to="{ name: 'details-signalement', params: { + slug: project.slug, slug_type_signal: item.feature_type.title, slug_signal: item.title, }, @@ -260,23 +259,18 @@ </div> <div class="description"> <i - >[{{ item.created_on }} - {{ - $store.state.user - ? `, par - ${item.display_creator}` - : "" - }} + >[{{ item.created_on + }}<span v-if="user" + >, par {{ item.display_creator }} + </span> ]</i > </div> </div> </div> - <!-- {% empty %} --> <i v-if="last_features.length === 0" >Aucun signalement pour le moment.</i > - <!-- {% endfor %} --> </div> </div> </div> @@ -287,23 +281,23 @@ <div class="center aligned description"> <div class="ui relaxed list"> <div - v-for="item in last_comments" - :key="item.id" + v-for="(item, index) in last_comments" + :key="'comment ' + index" class="item" > - // ? item.id exists ? <div class="content"> <div> <!-- // todo : adapt --> - <a href="item.related_feature.feature_url" - >"{{ item.comment }}"</a + <router-link + :to="item.related_feature.feature_url" + >"{{ item.comment }}"</router-link > </div> <div class="description"> <i - >[ {{ item.created_on }} - <span v-if="user.is_authenticated"> - , par {{ item.display_user }} + >[ {{ item.created_on + }}<span v-if="user" + >, par {{ item.display_author }} </span> ]</i > @@ -395,7 +389,7 @@ </div> </div> <!-- {% else %} --> - <span v-else> + <span v-else-if="!permissions.can_view_project"> <i class="icon exclamation triangle"></i> <span >Vous ne disposez pas des droits nécessaires pour consulter ce @@ -453,7 +447,7 @@ </template> <script> -import axios from 'axios'; +import axios from "axios"; import frag from "vue-frag"; import { mapGetters, mapState } from "vuex"; @@ -466,11 +460,10 @@ export default { data() { return { - filenameToImport: {name: '', size: 0}, + filenameToImport: { name: "", size: 0 }, slug: this.$route.params.slug, isModalOpen: false, is_suscriber: false, - last_comments: [], permissions: { can_view_project: true, can_create_feature: true, @@ -479,6 +472,7 @@ export default { }, computed: { ...mapGetters(["project"]), + ...mapState(["last_comments", "user"]), ...mapState("feature_type", ["feature_types"]), BASE_URL: () => process.env.VUE_APP_BASE_URL, last_features: function () { @@ -486,7 +480,7 @@ export default { }, }, created() { - this.$store.commit("SET_PROJECT_SLUG", this.slug); + this.$store.dispatch("GET_PROJECT_INFO", this.slug); }, mounted() { @@ -497,39 +491,46 @@ export default { methods: { importGeoJson() { - if (this.filenameToImport.size > 0){ + if (this.filenameToImport.size > 0) { var formData = new FormData(); formData.append("json_file", this.filenameToImport); - let url = process.env.VUE_APP_URL_BASE + 'projet/' + this.$route.params.slug + '/importer-geojson/' ; - axios.post(url, formData, { headers: { - 'Content-Type': 'multipart/form-data' - } + let url = + process.env.VUE_APP_URL_BASE + + "projet/" + + this.$route.params.slug + + "/importer-geojson/"; + axios + .post(url, formData, { + headers: { + "Content-Type": "multipart/form-data", + }, }) .then((response) => { - if (response.status == 200){ - console.log(response.data) + if (response.status == 200) { + console.log(response.data); // TODO : Router :to="{ // name: 'ajouter-type-signalement', // params: { slug: project.slug }, // }" - } }) - .catch(err => { + .catch((err) => { // TODO : HANDLER ERROR - console.log(err) + console.log(err); }); } }, onFileChange(e) { var files = e.target.files || e.dataTransfer.files; - if (!files.length) - return; - this.filenameToImport = files[0] + if (!files.length) return; + this.filenameToImport = files[0]; }, subsribeProject() { console.log("Subsribe to project"); }, + getFeatureSlug(url) { + return url.split("type-signalement")[1].split("signalement"); + }, }, }; </script> @@ -551,11 +552,11 @@ export default { float: right; margin: 0 0 0 1em; } -.nouveau-type-signalement{ +.nouveau-type-signalement { padding-top: 1em; } -#button-import{ +#button-import { padding-top: 0.5em; } </style> \ No newline at end of file diff --git a/src/views/project/Project_edit.vue b/src/views/project/Project_edit.vue index d5b1b4359bfc5003bbc750bf1f9d79925d08ffb8..8ef6fab17591ea8fccee1b38ddd7fc42c9a26f55 100644 --- a/src/views/project/Project_edit.vue +++ b/src/views/project/Project_edit.vue @@ -259,7 +259,7 @@ export default { created() { this.definePageType(); if (!this.project && this.action !== "create") { - this.$store.commit("SET_PROJECT_SLUG", this.$route.params.slug); + this.$store.dispatch("GET_PROJECT_INFO", this.$route.params.slug); } }, }; diff --git a/src/views/project/Project_members.vue b/src/views/project/Project_members.vue index 49c1142703632d2a30d3122b745acc0d1bf60029..bd7e6f7bdddbc291c67c625f9cd17187fbea104a 100644 --- a/src/views/project/Project_members.vue +++ b/src/views/project/Project_members.vue @@ -95,7 +95,6 @@ export default { .post(`${DJANGO_API_BASE}projet/${payload.slug}/utilisateurs/`, payload.data) .then((response) => { const user = response.data.user; - }) .catch(() => { router.push({ name: "login" }); @@ -125,7 +124,7 @@ export default { created() { if (!this.project) { - this.$store.commit("SET_PROJECT_SLUG", this.$route.params.slug); + this.$store.dispatch("GET_PROJECT_INFO", this.$route.params.slug); } this.populateMembers(); },