Skip to content
Snippets Groups Projects
ProjectsList.vue 4.56 KiB
<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>