diff --git a/src/App.vue b/src/App.vue index af053b2d87e67b5a9deebc44bcec4e30cd73fdf9..df9cc79758d9a6dcb88a3989e639bd090acc1eb2 100644 --- a/src/App.vue +++ b/src/App.vue @@ -93,7 +93,10 @@ <div class="mobile"> <router-link v-if="user" - :to="{name: 'my_account', params: { slug: $route.params.slug ? $route.params.slug : '-' }}" + :to="{ + name: 'my_account', + params: { slug: isSharedProject && $route.params.slug ? $route.params.slug : null } + }" class="item" > {{ userFullname || user.username || "Utilisateur inconnu" }} @@ -146,7 +149,10 @@ <div class="desktop flex push-right-desktop"> <router-link v-if="user" - :to="{name: 'my_account', params: { slug: $route.params.slug ? $route.params.slug : '-' }}" + :to="{ + name: 'my_account', + params: { slug: isSharedProject && $route.params.slug ? $route.params.slug : null } + }" class="item" > {{ userFullname || user.username || "Utilisateur inconnu" }} diff --git a/src/assets/styles/base.css b/src/assets/styles/base.css index 73e95a5b5531f93c4da75db118267ab48ad7a5a8..f77d223bc0e28657f22ab8017e15c4ed3f490920 100644 --- a/src/assets/styles/base.css +++ b/src/assets/styles/base.css @@ -35,6 +35,9 @@ main { .pointer:hover { cursor: pointer; } +.dimmer-anchor { + position: relative; +} /* ---------------------------------- */ /* MAIN */ /* ---------------------------------- */ diff --git a/src/components/Pagination.vue b/src/components/Pagination.vue index d0f730bab725b56ccaab46e4c02835e7c197da65..2afc85dfff08547813bd8d477c290efe1632ddd3 100644 --- a/src/components/Pagination.vue +++ b/src/components/Pagination.vue @@ -8,7 +8,7 @@ > <a class="page-link" - href="#" + :href="currentLocation" @click="page -= 1" > <i class="ui icon big angle left" /> @@ -26,7 +26,7 @@ > <a class="page-link" - href="#" + :href="currentLocation" @click="changePage(index)" > {{ index }} @@ -45,7 +45,7 @@ > <a class="page-link" - href="#" + :href="currentLocation" @click="page = index" > {{ index }} @@ -58,7 +58,7 @@ > <a class="page-link" - href="#" + :href="currentLocation" @click="page += 1" > <i class="ui icon big angle right" /> @@ -89,7 +89,8 @@ export default { data() { return { - page: 1 + page: 1, + currentLocation: window.location.origin + window.location.pathname + '#', }; }, diff --git a/src/services/project-api.js b/src/services/project-api.js index f150a81ed390fc9d128cb131201e1cc2fae1a135..5b2e79ee8b58fcec74b863f781cb1e83da6b30a4 100644 --- a/src/services/project-api.js +++ b/src/services/project-api.js @@ -45,21 +45,22 @@ const projectAPI = { } }, - async getProjects(baseUrl, filters, page) { + async getProjects({ baseUrl, filters, page, projectSlug, ismyaccount }) { + let url = `${baseUrl}projects/`; + if (projectSlug) url += `${projectSlug}/`; + url += `?page=${page}`; + if (ismyaccount) { + url += '&ismyaccount'; + } try { - const url = `${baseUrl}projects/?page=${page}`; - - let filteredUrl; if (Object.values(filters).some(el => el && el.length > 0)) { - filteredUrl = url; for (const filter in filters) { if (filters[filter]) { - filteredUrl = filteredUrl.concat('', `&${filter}=${filters[filter]}`); + url = url.concat('', `&${filter}=${filters[filter]}`); } } } - - const response = await axios.get(filteredUrl ? filteredUrl : url); + const response = await axios.get(url); if (response.status === 200 && response.data) { return response.data; } diff --git a/src/store/modules/projects.store.js b/src/store/modules/projects.store.js index e6229cff4e35e2dcbae23a160ed0b9b517596226..ba6754768d2c7e36922acc13d940856da4d46732 100644 --- a/src/store/modules/projects.store.js +++ b/src/store/modules/projects.store.js @@ -1,6 +1,13 @@ import axios from '@/axios-client.js'; import projectAPI from '@/services/project-api'; +const initialFilters = { + moderation: null, + access_level: null, + user_access_level: null, + accessible: null +}; + const projects = { namespaced: true, @@ -8,12 +15,7 @@ const projects = { state: { count: 0, currentPage: 1, - filters: { - moderation: null, - access_level: null, - user_access_level: null, - accessible: null - }, + filters: { ...initialFilters }, isProjectsListSearched: null, last_comments: [], projects: [], @@ -22,11 +24,6 @@ const projects = { searchProjectsFilter: null, }, - getters: { - project_types: state => state.projects.filter(projet => projet.is_project_type), - project_user: state => state.projects.filter(projet => projet.creator === state.user.id), - }, - mutations: { SET_CURRENT_PAGE (state, payload) { state.currentPage = payload; @@ -54,6 +51,10 @@ const projects = { state.filters[payload.filter] = payload.value; }, + RESET_PROJECTS_FILTER(state) { + state.filters = { ...initialFilters }; + }, + SET_PROJECTS_SEARCH_STATE(state, payload) { state.isProjectsListSearched = payload.isSearched; state.searchProjectsFilter = payload.text; @@ -78,13 +79,21 @@ const projects = { } }, - async GET_PROJECTS({ state, rootState, commit }, page) { + async GET_PROJECTS({ state, rootState, commit }, payload) { + let { page, ismyaccount, projectSlug } = payload || {}; if (!page) { page = state.currentPage; } const baseUrl = rootState.configuration.VUE_APP_DJANGO_API_BASE; - const projects = await projectAPI.getProjects(baseUrl, state.filters, page); + const projects = await projectAPI.getProjects({ + baseUrl, + filters : state.filters, + page, + projectSlug, + ismyaccount, + }); commit('SET_PROJECTS', projects); + return; }, async SEARCH_PROJECTS({ commit, dispatch }, text) { @@ -99,7 +108,7 @@ const projects = { } }, - async GET_PROJECT({ rootState, commit }, slug) { + async GET_PROJECT({ rootState, commit }, slug) { // todo : use GET_PROJECTS instead, with slug const baseUrl = rootState.configuration.VUE_APP_DJANGO_API_BASE; const project = await projectAPI.getProject(baseUrl, slug); commit('SET_PROJECT', project); diff --git a/src/views/My_account.vue b/src/views/My_account.vue index 1959ce4516be28b94ffd585199fddc44879a4685..bf6e2886182a555a126e9b0da8c8a7752b6a3058 100644 --- a/src/views/My_account.vue +++ b/src/views/My_account.vue @@ -58,9 +58,9 @@ MES PROJETS </h4> - <div class="ui divided items"> + <div class="ui divided items dimmer-anchor"> <div - v-for="project in availableProjects" + v-for="project in projectsArray" :key="project.slug" class="item" > @@ -133,6 +133,21 @@ </div> </div> </div> + + <div + :class="['ui inverted dimmer', { active: projectsLoading }]" + > + <div class="ui text loader"> + Récupération des projets en cours... + </div> + </div> + <!-- PAGINATION --> + <Pagination + v-if="count" + :nb-pages="Math.ceil(count/10)" + :on-page-change="SET_CURRENT_PAGE" + @change-page="changePage" + /> </div> </div> </div> @@ -308,8 +323,10 @@ <script> import frag from 'vue-frag'; -import { mapState } from 'vuex'; +import { mapActions, mapMutations, mapState } from 'vuex'; import miscAPI from '@/services/misc-api'; +import Pagination from '@/components/Pagination.vue'; + export default { name: 'MyAccount', @@ -318,11 +335,16 @@ export default { frag, }, + components: { + Pagination, + }, + data() { return { events: [], features: [], comments: [], + projectsLoading: true, }; }, @@ -333,9 +355,9 @@ export default { 'user_permissions', ]), - // todo : filter projects to user ...mapState('projects', [ - 'projects' + 'projects', + 'count', ]), DJANGO_BASE_URL() { @@ -352,19 +374,30 @@ export default { return this.$route.path.includes('projet-partage'); }, - availableProjects() { - if (this.isSharedProject) { - return this.projects.filter((el) => el.slug === this.$route.params.slug); - } - return this.projects; + projectsArray() { //* if only one project, only project object is returned + return Array.isArray(this.projects) ? this.projects : [this.projects]; } }, created(){ + this.RESET_PROJECTS_FILTER(); //* empty remaining filters in store + this.SET_PROJECTS([]); //* empty previous project to avoid undefined user_permissions[project.slug] + this.getData(); this.getEvents(); }, methods: { + ...mapActions('projects', [ + 'GET_PROJECTS', + ]), + ...mapMutations('projects', [ + 'SET_PROJECTS', + 'RESET_PROJECTS_FILTER', + ]), + ...mapMutations('projects', [ + 'SET_CURRENT_PAGE', + ]), + refreshId() { return '?ver=' + Math.random(); }, @@ -383,7 +416,18 @@ export default { return url.replace('projet', 'projet-partage'); } return url; - } + }, + + getData(page) { + this.projectsLoading = true; + this.GET_PROJECTS({ ismyaccount: true, projectSlug: this.$route.params.slug, page }) + .then(() => this.projectsLoading = false) + .catch(() => this.projectsLoading = false); + }, + + changePage(e) { + this.getData(e); + }, } }; </script> \ No newline at end of file diff --git a/src/views/Projects.vue b/src/views/Projects.vue index 42640515ef9d34aa72360921eabb32370d568721..92574b20b07a2abb96ac78320eb593e8cc34d39a 100644 --- a/src/views/Projects.vue +++ b/src/views/Projects.vue @@ -48,12 +48,6 @@ v-if="projects" class="ui divided items dimmable dimmed" > - <div - :class="{ active: loading }" - class="ui inverted dimmer" - > - <div class="ui loader" /> - </div> <div v-for="project in projects" :key="project.slug" @@ -124,16 +118,21 @@ v-if="!projects || projects.length === 0" >Vous n'avez accès à aucun projet.</span> - <div class="item" /> - </div> + <div + :class="{ active: loading }" + class="ui inverted dimmer" + > + <div class="ui loader" /> + </div> - <!-- PAGINATION --> - <pagination - v-if="count" - :nb-pages="Math.ceil(count/10)" - :on-page-change="SET_CURRENT_PAGE" - @change-page="changePage" - /> + <!-- PAGINATION --> + <Pagination + v-if="count" + :nb-pages="Math.ceil(count/10)" + :on-page-change="SET_CURRENT_PAGE" + @change-page="changePage" + /> + </div> </div> </template> @@ -236,7 +235,7 @@ export default { getData(page) { this.loading = true; - this.GET_PROJECTS(page) + this.GET_PROJECTS({ page }) .then(() => { this.loading = false; }) diff --git a/src/views/project/Project_detail.vue b/src/views/project/Project_detail.vue index c2abc54a4dd46760520cab3280b28e15948f7ead..62cac6b6f1d2da33c7cc13b04b81d04578059e01 100644 --- a/src/views/project/Project_detail.vue +++ b/src/views/project/Project_detail.vue @@ -1164,7 +1164,6 @@ export default { .then((response) => { this.modalType = false; if (response === 'success') { - this.GET_PROJECT(); this.retrieveProjectInfo(); this.DISPLAY_MESSAGE({ comment: `Le type de signalement ${this.featureTypeToDelete.title} a bien été supprimé.`,