<template> <div id="projects"> <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" data-test="create-project" > <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" data-test="to-project-models" > <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 :checked="displayForbiddenProjects" type="checkbox" @input="toggleForbiddenProjects" > <label> N'afficher que les projets disponibles à la consultation </label> </div> <!-- LISTE DES PROJETS --> <div v-if="projects" class="ui divided items dimmable dimmed" data-test="project-list" > <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="nbPages" :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; }, nbPages() { return Math.ceil(this.count / 10); } }, created() { this.SET_CURRENT_PAGE(1); this.$store.commit('projects/SET_PROJECT', null); this.displayForbiddenProjects = this.configuration.DISPLAY_FORBIDDEN_PROJECTS_DEFAULT; this.setForbiddenProjectsFilter(); }, 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); this.getData(); }, toggleForbiddenProjects(e) { this.displayForbiddenProjects = e.target.checked; this.setForbiddenProjectsFilter(); }, setForbiddenProjectsFilter() { this.setProjectsFilters({ filter: 'accessible', value: this.displayForbiddenProjects ? 'true' : null }); }, } }; </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: var(--primary-color, #008c86) !important; } input:checked ~ label { color: var(--primary-color, #008c86) !important; } } </style>