<template> <div id="projects" class="page" > <h2 class="ui horizontal divider header"> PROJETS </h2> <div class="flex"> <router-link v-if="user && user.can_create_project && isOnline" :to="{ name: 'project_create', params: { action: 'create' } }" class="ui green basic button" > <i class="plus icon" aria-hidden="true" /> Créer un nouveau projet </router-link> <router-link v-if="user && user.can_create_project && isOnline" :to="{ name: 'project_type_list', }" class="ui blue basic button" > <i class="copy icon" aria-hidden="true" /> Accéder à la liste des modèles de projets </router-link> </div> <!-- FILTRES DES PROJETS --> <ProjectsMenu @filter="setProjectsFilters" @loading="setLoader" /> <div v-if="configuration.DISPLAY_FORBIDDEN_PROJECTS" id="forbidden-projects" class="ui toggle checkbox" > <input v-model="displayForbiddenProjects" type="checkbox" > <label> N'afficher que les projets disponibles à la consultation </label> </div> <!-- LISTE DES PROJETS --> <div v-if="projects" class="ui divided items dimmable dimmed" > <div :class="{ active: loading }" class="ui inverted dimmer" > <div class="ui loader" /> </div> <ProjectsListItem v-for="project in projects" :key="project.slug" :project="project" /> <span v-if="!projects || projects.length === 0" > Vous n'avez accès à aucun projet. </span> <!-- PAGINATION --> <Pagination v-if="count" :nb-pages="Math.ceil(count/10)" :on-page-change="SET_CURRENT_PAGE" @change-page="changePage" /> </div> </div> </template> <script> import { mapState, mapMutations, mapActions } from 'vuex'; import ProjectsMenu from '@/components/Projects/ProjectsMenu'; import ProjectsListItem from '@/components/Projects/ProjectsListItem'; import Pagination from '@/components/Pagination'; export default { name: 'ProjectsList', components: { ProjectsMenu, ProjectsListItem, Pagination }, data() { return { loading: false, displayForbiddenProjects: false }; }, computed: { ...mapState([ 'configuration', 'user', 'isOnline', ]), ...mapState('projects', [ 'projects', 'count', 'filters', ]), DJANGO_BASE_URL() { return this.$store.state.configuration.VUE_APP_DJANGO_BASE; }, }, watch: { filters: { deep: true, handler(newValue) { if (newValue) { this.getData(); } } }, displayForbiddenProjects(newValue) { if (newValue) { this.SET_PROJECTS_FILTER({ filter: 'accessible', value: 'true' }); } else { this.SET_PROJECTS_FILTER({ filter: 'accessible', value: null }); } this.getData(); } }, created() { this.$store.commit('projects/SET_PROJECT', null); this.SET_PROJECTS_FILTER({ filter: 'accessible', value: 'true' }); this.displayForbiddenProjects = this.configuration.DISPLAY_FORBIDDEN_PROJECTS_DEFAULT; }, methods: { ...mapMutations('projects', [ 'SET_CURRENT_PAGE', 'SET_PROJECTS_FILTER' ]), ...mapActions('projects', [ 'GET_PROJECTS' ]), getData(page) { this.loading = true; this.GET_PROJECTS({ page }) .then(() => { this.loading = false; }) .catch(() => { this.loading = false; }); }, setLoader(e) { this.loading = e; }, changePage(e) { this.getData(e); }, setProjectsFilters(e) { this.SET_PROJECTS_FILTER(e); }, } }; </script> <style lang="less" scoped> #projects { margin: 0 auto; .dimmable { .dimmer { .loader { top: 25%; } } } } .flex { display: flex; justify-content: space-between; } #filters-divider { padding-top: 0; color: gray !important; } #forbidden-projects.checkbox { font-size: 1.2em; font-weight: 600; label { color: rgb(94, 94, 94); } input:checked ~ label::before { background-color: teal !important; } input:checked ~ label { color: teal !important; } } </style>