github.com/benoitkugler/goacve@v0.0.0-20201217100549-151ce6e55dc8/server/frontend/bv/src/pages/vote/admin/Votes.vue (about)

     1  <template>
     2    <b-overlay :show="loading">
     3      <b-card>
     4        <b-card-title>
     5          <b-row>
     6            <b-col> Votes en cours</b-col>
     7            <b-col class="text-right">
     8              <b-button variant="success" @click="createVote">
     9                <b-icon-plus></b-icon-plus>
    10                Ajouter un vote</b-button
    11              >
    12              <b-button
    13                :href="urlExportVotes"
    14                target="_blank"
    15                variant="info"
    16                class="ml-2"
    17                title="Télécharger les votes clôturés au format PDF"
    18                :disabled="exportDisabled"
    19              >
    20                <b-icon-download></b-icon-download>
    21                Bilan des votes
    22              </b-button>
    23              <b-button
    24                @click="refresh"
    25                variant="light"
    26                title="Rafraichir les données"
    27                class="ml-2"
    28              >
    29                <b-icon-arrow-repeat></b-icon-arrow-repeat>
    30              </b-button>
    31            </b-col>
    32          </b-row>
    33        </b-card-title>
    34        <b-card v-for="(vote, i) in votes" :key="i" class="my-1 border-secondary">
    35          <b-card-text>
    36            <b-form>
    37              <b-row>
    38                <b-col cols="8">
    39                  <b-form-group label="Nom" label-cols="3">
    40                    <b-form-input
    41                      v-model="vote.nom"
    42                      required
    43                      :disabled="!editModes[vote.id]"
    44                    ></b-form-input>
    45                  </b-form-group>
    46                </b-col>
    47                <b-col cols="4" class="text-right">
    48                  <b-button
    49                    v-if="!editModes[vote.id] && isVoteEditable(vote)"
    50                    @click="editVote(vote)"
    51                    size="sm"
    52                    v-b-tooltip.hover
    53                    title="Modifier les paramètres du vote..."
    54                  >
    55                    <b-icon-pencil></b-icon-pencil>
    56                    Editer
    57                  </b-button>
    58                  <b-button
    59                    v-else-if="isVoteEditable(vote)"
    60                    @click="save(vote)"
    61                    size="sm"
    62                    v-b-tooltip.hover
    63                    title="Enregistrer les modifications"
    64                  >
    65                    <b-icon-check></b-icon-check>
    66                    Enregistrer
    67                  </b-button>
    68  
    69                  <b-button
    70                    v-if="vote.participation > 0 && !vote.is_locked"
    71                    @click="clear(vote)"
    72                    size="sm"
    73                    v-b-tooltip.hover
    74                    variant="danger"
    75                    title="Supprimer les suffrages déjà exprimés"
    76                    class="ml-2"
    77                  >
    78                    Remettre à zéro
    79                  </b-button>
    80                  <b-button
    81                    @click="lockVote(vote)"
    82                    size="sm"
    83                    v-b-tooltip.hover
    84                    variant="outline-warning"
    85                    :title="
    86                      vote.is_locked ? 'Ré-ouvrir ce vote' : 'Cloturer ce vote'
    87                    "
    88                    :disabled="editModes[vote.id]"
    89                    class="ml-2"
    90                  >
    91                    <b-icon-unlock v-if="vote.is_locked"></b-icon-unlock>
    92                    <b-icon-lock v-else></b-icon-lock>
    93                    <b-badge v-if="vote.is_locked" variant="warning" class="ml-2"
    94                      >Vote cloturé</b-badge
    95                    >
    96                  </b-button>
    97                  <b-button
    98                    @click="deleteVote(vote)"
    99                    size="sm"
   100                    v-b-tooltip.hover
   101                    variant="danger"
   102                    title="Supprimer ce vote"
   103                    class="ml-2"
   104                  >
   105                    <b-icon-trash></b-icon-trash>
   106                  </b-button>
   107                </b-col>
   108              </b-row>
   109              <b-form-group label="Choix multiples" label-cols="2">
   110                <b-form-checkbox
   111                  v-model="vote.is_qcm"
   112                  :disabled="!editModes[vote.id]"
   113                  >Permet plusieurs choix par personne.</b-form-checkbox
   114                >
   115              </b-form-group>
   116              <b-form-group label="Description" label-cols="2">
   117                <b-form-textarea
   118                  v-model="vote.description"
   119                  placeholder="Optionnel"
   120                  :disabled="!editModes[vote.id]"
   121                ></b-form-textarea>
   122              </b-form-group>
   123              <b-form-group
   124                label-cols="2"
   125                label="Choix possibles"
   126                v-if="!editModes[vote.id]"
   127              >
   128                <b-list-group horizontal class="flex-wrap">
   129                  <b-list-group-item
   130                    v-for="candidat in vote.candidats || []"
   131                    :key="candidat.id"
   132                    class="border rounded py-2 px-3"
   133                    style="width: 33%"
   134                  >
   135                    <b-row no-gutters>
   136                      <b-col>{{ candidat.label }}</b-col>
   137                      <b-col cols="3" class="text-right">
   138                        <b-badge variant="info">
   139                          {{ (vote.voix || {})[candidat.id] }} voix
   140                        </b-badge>
   141                      </b-col>
   142                    </b-row>
   143                  </b-list-group-item>
   144                  <b-list-group-item v-if="(vote.candidats || []).length == 0">
   145                    Aucun choix possible.
   146                  </b-list-group-item>
   147                </b-list-group>
   148              </b-form-group>
   149              <b-form-group label="Choix possibles" label-cols="2" v-else>
   150                <edit-candidats
   151                  :vote="vote"
   152                  :completion="completion"
   153                ></edit-candidats>
   154              </b-form-group>
   155            </b-form>
   156          </b-card-text>
   157        </b-card>
   158      </b-card>
   159    </b-overlay>
   160  </template>
   161  
   162  <script lang="ts">
   163  import Vue from "vue";
   164  import Component from "vue-class-component";
   165  import EditCandidats from "./EditCandidats.vue";
   166  
   167  import { C, BASE_URL } from "./controller";
   168  import { VoteAdmin, Candidat, Vote, LockVote } from "@/shared/logic/types";
   169  
   170  const VotesProps = Vue.extend({
   171    props: {}
   172  });
   173  
   174  @Component({
   175    components: { EditCandidats }
   176  })
   177  export default class Votes extends VotesProps {
   178    loading = false;
   179    votes: VoteAdmin[] = [];
   180    editModes: { [key: number]: boolean } = {};
   181    C = C;
   182  
   183    urlExportVotes = BASE_URL + "/votes/export";
   184  
   185    created() {
   186      this.refresh();
   187    }
   188  
   189    async refresh() {
   190      this.loading = true;
   191      const data = await C.getVotes();
   192      this.loading = false;
   193      if (data == undefined) return;
   194      this.votes = data || [];
   195      this.editModes = {};
   196      C.notifications.success = {
   197        title: "Votes",
   198        message: "Liste des votes en cours chargées."
   199      };
   200    }
   201  
   202    async createVote() {
   203      this.loading = true;
   204      const data = await C.createVote({
   205        id: -1,
   206        nom: "",
   207        description: "",
   208        is_qcm: true,
   209        is_locked: false,
   210        candidats: []
   211      });
   212      this.loading = false;
   213      if (data == undefined) return;
   214      this.votes = data || [];
   215      this.editModes = {};
   216      C.notifications.success = {
   217        title: "Nouveau vote",
   218        message: "Vote ajouté avec succés."
   219      };
   220    }
   221  
   222    get completion() {
   223      return C.membres.map(m => m.nom_prenom);
   224    }
   225  
   226    /** si aucun vote n'est verrouillé, le document sera vide */
   227    get exportDisabled() {
   228      return this.votes.filter(v => v.is_locked).length == 0;
   229    }
   230  
   231    isVoteEditable(vote: VoteAdmin) {
   232      return !vote.is_locked && vote.participation == 0;
   233    }
   234  
   235    editVote(vote: VoteAdmin) {
   236      this.$set(this.editModes, vote.id, true);
   237    }
   238  
   239    async save(vote: VoteAdmin) {
   240      this.loading = true;
   241      const data = await C.updateVote(vote);
   242      this.loading = false;
   243      this.editModes[vote.id] = false;
   244      if (data == undefined) return;
   245      this.votes = data || [];
   246      this.editModes = {};
   247      C.notifications.success = {
   248        title: "Vote",
   249        message: "Vote modifié avec succés."
   250      };
   251    }
   252  
   253    async lockVote(vote: VoteAdmin) {
   254      this.loading = true;
   255      // on inverse l'état actuel
   256      const params: LockVote = { id_vote: vote.id, is_locked: !vote.is_locked };
   257      const data = await C.lockVote(params);
   258      this.loading = false;
   259      if (data == undefined) return;
   260      this.votes = data || [];
   261      this.editModes = {};
   262      let message = "Vote cloturé avec succès.";
   263      if (vote.is_locked) {
   264        message = "Vote ouvert à nouveau.";
   265      }
   266      C.notifications.success = {
   267        title: "Verrou",
   268        message
   269      };
   270    }
   271  
   272    async doDeleteVote(vote: VoteAdmin) {
   273      this.loading = true;
   274      const data = await C.deleteVote(vote.id);
   275      this.loading = false;
   276      this.editModes = {};
   277      if (data === undefined) return;
   278      this.votes = data || [];
   279      C.notifications.success = {
   280        title: "Suppression",
   281        message: "Vote supprimé avec succés."
   282      };
   283    }
   284  
   285    deleteVote(vote: VoteAdmin) {
   286      this.$bvModal
   287        .msgBoxConfirm("Confirmer la suppression du vote", {
   288          title: "Suppression",
   289          okVariant: "danger",
   290          cancelTitle: "Retour"
   291        })
   292        .then(value => {
   293          if (value) {
   294            this.doDeleteVote(vote);
   295          }
   296        });
   297    }
   298  
   299    async doClear(vote: VoteAdmin) {
   300      this.loading = true;
   301      const data = await C.clearVote(vote.id);
   302      this.loading = false;
   303      this.editModes = {};
   304  
   305      if (data === undefined) return;
   306      this.votes = data || [];
   307      C.notifications.success = {
   308        title: "Suppression",
   309        message: "Voix supprimées avec succés."
   310      };
   311    }
   312  
   313    clear(vote: VoteAdmin) {
   314      this.$bvModal
   315        .msgBoxConfirm("Confirmer la suppression des suffrages", {
   316          title: "Suppression",
   317          okVariant: "danger",
   318          cancelTitle: "Retour"
   319        })
   320        .then(value => {
   321          if (value) {
   322            this.doClear(vote);
   323          }
   324        });
   325    }
   326  }
   327  </script>
   328  
   329  <style scoped></style>