Skip to content
Snippets Groups Projects
candidate-lists.js 17.8 KiB
Newer Older
  • Learn to ignore specific revisions
  • // Imports
    import * as Auth from "/services/auth/auth.js";
    
    import * as Common from "/services/common/common.js";
    import * as Messages from "/services/messages/messages.js";
    
    import * as AreaModel from "/services/model/area-model.js";
    
    import * as PartyModel from "/services/model/party-model.js";
    import * as CandidateListModel from "/services/model/candidateList-model.js";
    
    import * as CandidateModel from "/services/model/candidate-model.js";
    
    import { Delete } from "/services/common/delete.js";
    
    
    // DOM elements
    
    export async function mount(where, parent) {
      const candidateListComponent = new CandidateList(parent);
      await candidateListComponent.mount(where);
      return candidateListComponent;
    }
    
    class CandidateList {
      constructor(parent) {
        this.method = null;
        this.parent = parent;
    
        this.AreaModel = AreaModel.getAreaModel();
    
        this.PartyModel = PartyModel.getPartyModel();
        this.CandidateListModel = CandidateListModel.getCandidateListModel();
    
        this.CandidateModel = CandidateModel.getCandidateModel();
    
      }
    
      async mount(where) {
    
        this.AreaModel.current_user = await Auth.GetUser();
    
        this.PartyModel.current_user = await Auth.GetUser();
        this.CandidateListModel.current_user = await Auth.GetUser();
    
        this.CandidateModel.current_user = await Auth.GetUser();
    
        const mountpoint = where;
        document.getElementById(mountpoint).innerHTML = /* HTML */ `
          <header class="card-header">
    
            <p id="candidate-list-title" class="card-header-title">
    
              Liste des candidats par circonscription
    
    Alexis POYEN's avatar
    Alexis POYEN committed
            <button id="candidate-list-new" class="button is-success" disabled>
    
              <span class="icon is-small">
                <i class="fas fa-plus"></i>
              </span>
            </button>
          </header>
    
          <div class="columns card-content">
            <div class="column">
              <div id="areas-round"></div>
    
            <div class="column">
              <div id="candidate-lists-list"></div>
            </div>
    
            <div class="column is-two-thirds">
              <div id="candidate-list" class="card"></div>
    
            </div>
          </div>
    
        this.mountModal("candidateList-modal");
        this.handleDom();
    
    
      areaTemplate(area) {
        return /* HTML */ `<div class="card card-list">
          <div id="areas-area-${area.ID}" class="card-content">
            <div class="content">
              <nav class="level">
                <div class="level-left">
                  ${area.Name} (Nombre de siège : ${area.SeatNumber})
                </div>
              </nav>
            </div>
          </div>
        </div>`;
      }
    
    
      candidateListTemplate(candidateList) {
        return /* HTML */ `<div class="card card-list">
          <div
            id="candidateLists-candidateList-${candidateList.ID}"
            class="card-content"
          >
            <div class="content">
              <nav class="level">
                <div
                  id="candidateLists-candidateList-desc-${candidateList.ID}"
                  class="level-left"
                >
                  ${candidateList.Name}
                </div>
                <div class="level-right">
                  <a
                    id="candidateLists-candidateList-edit-${candidateList.ID}"
                    class="button is-link is-small"
                    title="Modifier"
                  >
                    <span class="icon is-small">
                      <i class="fas fa-pen"></i>
                    </span>
                  </a>
                  <a
                    id="candidateLists-candidateList-delete-${candidateList.ID}"
                    class="button is-danger is-small"
                    title="Supprimer"
                  >
                    <span class="icon is-small">
                      <i class="fas fa-times"></i>
                    </span>
                  </a>
                </div>
              </nav>
            </div>
          </div>
        </div>`;
      }
    
      mountModal(where) {
        const mountpoint = where;
        document.getElementById(mountpoint).innerHTML = /* HTML */ `
          <div class="modal-background"></div>
          <div class="modal-card" id="candidateList-modal-card">
            <header class="modal-card-head">
              <p class="modal-card-title">Ajout/modification d'un tour</p>
              <button
                class="delete"
                aria-label="close"
                id="candidateList-modal-close"
              ></button>
            </header>
            <section class="modal-card-body">
              <div class="field">
                <label>Id</label>
                <div class="control">
                  <input
                    class="input"
                    type="number"
                    id="candidateList-modal-id"
                    disabled
                  />
                </div>
              </div>
              <div class="field">
                <label>Name</label>
                <div class="control">
                  <input class="input" type="text" id="candidateList-modal-name" />
                </div>
              </div>
              <div class="field">
                <label>Parti</label><br />
                <div class="control select">
                  <select name="party" id="candidateList-modal-party"></select>
                </div>
              </div>
            </section>
            <footer class="modal-card-foot">
              <button id="candidateList-modal-save" class="button is-success">
                Sauvegarder
              </button>
              <button id="candidateList-modal-cancel" class="button">
                Annuler
              </button>
            </footer>
          </div>
        `;
      }
    
    
      async displayCandidates() {
        document.getElementById("candidate-list").innerHTML = /* HTML */ `<div
          class="table-container"
        >
          <table class="table is-bordered is-narrow is-hoverable is-fullwidth">
            <thead>
              <tr class="is-selected">
                <th hidden>Id</th>
                <th>Nom complet</th>
                <th>Rang</th>
                <th>Conseiller communautaire</th>
                <th>Date de naissance</th>
                <th>Incompatibilité potentielle</th>
                <th>Refusé</th>
                <th>Supprimé</th>
                <th>Actions</th>
              </tr>
            </thead>
            <tbody id="candidates"></tbody>
          </table>
        </div> `;
    
        let candidates = await this.updateCandidates();
        const markup = candidates
          .map((candidate) => this.candidateTemplate(candidate))
          .join("");
        document.getElementById("candidates").innerHTML = markup;
    
        let candidate = {
          ID: 0,
          FullName: "",
          Rank: 0,
          CommunityCounseller: false,
          Birthdate: "2000-01-01",
          PotentialIncompatibility: false,
          Refused: false,
          Removed: false,
        };
        document.getElementById("candidates").innerHTML += this.candidateTemplate(
          candidate
        );
        document
          .getElementById(`candidates-candidate-edit-0`)
          .addEventListener("click", function () {
            candidateListHandler.method = "POST";
            candidateListHandler.saveCandidate(candidate.ID);
          });
        document.getElementById(`candidates-candidate-delete-0`).remove();
    
        let candidateListHandler = this;
        candidates.map((candidate) => {
          document
            .getElementById(`candidates-candidate-edit-${candidate.ID}`)
            .addEventListener("click", function () {
              candidateListHandler.method = "PUT";
              candidateListHandler.saveCandidate(candidate.ID);
            });
          document
            .getElementById(`candidates-candidate-delete-${candidate.ID}`)
            .addEventListener("click", function () {
              new Delete(() => {
                candidateListHandler.deleteCandidate(candidate);
              });
            });
        });
      }
    
      candidateTemplate(candidate) {
        return /* HTML */ `
          <tr id="candidates-candidate-${candidate.ID}">
            <td hidden>
              <input
                class="input"
                type="number"
                id="${candidate.ID}-candidate-id"
                value="${candidate.ID}"
                disabled
              />
            </td>
            <td>
              <input
                class="input"
                type="text"
                id="${candidate.ID}-candidate-fullname"
                value="${candidate.FullName}"
              />
            </td>
            <td>
              <input
                class="input"
                type="number"
                id="${candidate.ID}-candidate-rank"
                value="${candidate.Rank}"
              />
            </td>
            <td>
              <input
                type="checkbox"
                id="${candidate.ID}-candidate-community-counseller"
                ${candidate.CommunityCounseller ? "checked" : ""}
              />
            </td>
            <td>
              <input
                class="input"
                type="date"
                id="${candidate.ID}-candidate-birthdate"
                value="${candidate.Birthdate}"
              />
            </td>
            <td>
              <input
                type="checkbox"
                id="${candidate.ID}-candidate-potential-incompatibility"
                ${candidate.PotentialIncompatibility ? "checked" : ""}
              />
            </td>
            <td>
              <input
                type="checkbox"
                id="${candidate.ID}-candidate-refused"
                ${candidate.Refused ? "checked" : ""}
              />
            </td>
            <td>
              <input
                type="checkbox"
                id="${candidate.ID}-candidate-removed"
                ${candidate.Removed ? "checked" : ""}
              />
            </td>
            <td>
              <a
                id="candidates-candidate-edit-${candidate.ID}"
                class="button is-success is-small"
              >
                <span>Valider</span>
                <span class="icon is-small">
                  <i class="fas fa-check"></i>
                </span>
              </a>
              <a
                id="candidates-candidate-delete-${candidate.ID}"
                class="button is-danger is-small"
              >
                <span>Supprimer</span>
                <span class="icon is-small">
                  <i class="fas fa-times"></i>
                </span>
              </a>
            </td>
          </tr>
        `;
      }
    
    
      handleDom() {
        let candidateListHandler = this;
        document
          .getElementById(`candidate-list-new`)
          .addEventListener("click", function () {
            candidateListHandler.newCandidateList();
          });
    
        document
          .getElementById(`candidateList-modal-close`)
          .addEventListener("click", function () {
            Common.toggleModal("candidateList-modal", "candidateList-modal-card");
          });
        document
          .getElementById(`candidateList-modal-cancel`)
          .addEventListener("click", function () {
            Common.toggleModal("candidateList-modal", "candidateList-modal-card");
          });
        document
          .getElementById(`candidateList-modal-save`)
          .addEventListener("click", async function () {
            if (
              document.getElementById("candidateList-modal-party").value === "0"
            ) {
              Messages.Show("is-danger", "Veuillez sélectionner un parti.");
              return;
            }
            await candidateListHandler.saveCandidateList();
          });
      }
    
    
      async displayAreas() {
        let candidateListHandler = this;
        let areas = await this.updateAreas();
        const markup = areas.map((area) => this.areaTemplate(area)).join("");
        document.getElementById("areas-round").innerHTML = markup;
    
        areas.map((area) => {
          document
            .getElementById(`areas-area-${area.ID}`)
            .addEventListener("click", async function () {
    
              candidateListHandler.emptyCandidateList();
    
              await candidateListHandler.activateArea(area);
              await candidateListHandler.displayCandidateLists();
            });
        });
    
    
        this.emptyCandidateList();
    
      }
    
      async updateAreas() {
        let candidateListHandler = this;
        let areas = await this.AreaModel.getAreas();
        return areas.filter(function (area) {
          return area.ElectionID == candidateListHandler.round.ElectionID;
        });
      }
    
    
      async activateArea(areaToActivate) {
        this.area = areaToActivate;
        let areas = await this.updateAreas();
        areas.forEach((area) => {
          document
            .getElementById(`areas-area-${area.ID}`)
            .classList.remove("active-card");
        });
        document
          .getElementById(`areas-area-${areaToActivate.ID}`)
          .classList.add("active-card");
        document.getElementById("candidate-list-new").removeAttribute("disabled");
      }
    
    
      async activateCandidateList(candidateListToActivate) {
        this.candidateList = candidateListToActivate;
        let candidateLists = await this.updateCandidateLists();
        candidateLists.forEach((candidateList) => {
          document
            .getElementById(`candidateLists-candidateList-${candidateList.ID}`)
            .classList.remove("active-card");
        });
        document
    
          .getElementById(
            `candidateLists-candidateList-${candidateListToActivate.ID}`
          )
    
          .classList.add("active-card");
    
        this.displayCandidates();
    
    
      async displayCandidateLists() {
        let candidateListHandler = this;
        let candidateLists = await this.updateCandidateLists();
        const markup = candidateLists
          .map((candidateList) => this.candidateListTemplate(candidateList))
          .join("");
        document.getElementById("candidate-lists-list").innerHTML = markup;
    
        candidateLists.map(async (candidateList) => {
          let party = await this.PartyModel.getParty(candidateList.PartyID);
          document.getElementById(
            `candidateLists-candidateList-desc-${candidateList.ID}`
          ).innerHTML += "(" + party.Name + ")";
          document
            .getElementById(`candidateLists-candidateList-edit-${candidateList.ID}`)
            .addEventListener("click", function () {
              candidateListHandler.editCandidateList(candidateList);
            });
          document
            .getElementById(
              `candidateLists-candidateList-delete-${candidateList.ID}`
            )
            .addEventListener("click", function () {
              new Delete(() => {
                candidateListHandler.deleteCandidateList(candidateList);
              });
            });
    
          document
            .getElementById(`candidateLists-candidateList-${candidateList.ID}`)
            .addEventListener("click", async function () {
              await candidateListHandler.activateCandidateList(candidateList);
              await candidateListHandler.displayCandidates();
            });
    
        });
      }
    
      async updateCandidateLists() {
        let candidateListHandler = this;
        let candidateLists = await this.CandidateListModel.getCandidateLists();
        return candidateLists.filter(function (candidateList) {
    
          return (
            candidateList.AreaID == candidateListHandler.area.ID &&
            candidateList.RoundID == candidateListHandler.round.ID
          );
    
      async updateCandidates() {
        let candidateListHandler = this;
        let candidates = await this.CandidateModel.getCandidates();
        return candidates.filter(function (candidate) {
          return candidate.CandidateListID == candidateListHandler.candidateList.ID;
        });
      }
    
    
      async newCandidateList() {
        this.method = "POST";
        await this.refreshParties();
        document.getElementById("candidateList-modal-id").value = null;
        document.getElementById("candidateList-modal-party").value = null;
        document.getElementById("candidateList-modal-name").value = null;
        Common.toggleModal("candidateList-modal", "candidateList-modal-card");
    
      async editCandidateList(candidateList) {
        this.method = "PUT";
        await this.refreshParties();
        document.getElementById("candidateList-modal-id").value = candidateList.ID;
        document.getElementById("candidateList-modal-party").value =
          candidateList.PartyID;
        document.getElementById("candidateList-modal-name").value =
          candidateList.Name;
        Common.toggleModal("candidateList-modal", "candidateList-modal-card");
      }
    
      async refreshParties() {
        let selectParties = document.getElementById("candidateList-modal-party");
        let parties = await this.PartyModel.getParties();
        for (let i = selectParties.options.length - 1; i >= 0; i--) {
          selectParties.remove(i);
        }
    
        let el = document.createElement("option");
        el.textContent = "Veuillez sélectionner un parti";
        el.value = 0;
        selectParties.appendChild(el);
        parties.forEach((party) => {
          el = document.createElement("option");
          el.textContent = party.Name;
          el.value = party.ID;
          selectParties.appendChild(el);
        });
      }
    
      async saveCandidateList() {
        if (this.method == "POST")
          document.getElementById("candidateList-modal-id").value = null;
    
        let candidateList = await this.CandidateListModel.saveCandidateList(
          this.method,
          parseInt(document.getElementById("candidateList-modal-id").value),
          document.getElementById("candidateList-modal-name").value,
          parseInt(document.getElementById("candidateList-modal-party").value),
          this.round.ID,
          this.area.ID
        );
        await this.displayCandidateLists();
        Common.toggleModal("candidateList-modal", "candidateList-modal-card");
        this.activateCandidateList(candidateList);
        return candidateList;
      }
    
      async deleteCandidateList(candidateList) {
        await this.CandidateListModel.deleteCandidateList(candidateList.ID);
        await this.displayCandidateLists();
    
        // TODO empty Candidates
      }
    
      async saveCandidate(candidateID) {
        let candidate = await this.CandidateModel.saveCandidate(
          this.method,
          candidateID,
          this.candidateList.ID,
          document.getElementById(candidateID + "-candidate-fullname").value,
          parseInt(document.getElementById(candidateID + "-candidate-rank").value),
          document.getElementById(candidateID + "-candidate-community-counseller")
            .checked,
          document.getElementById(candidateID + "-candidate-birthdate").value,
          document.getElementById(
            candidateID + "-candidate-potential-incompatibility"
          ).checked,
          document.getElementById(candidateID + "-candidate-refused").checked,
          document.getElementById(candidateID + "-candidate-removed").checked
        );
        await this.displayCandidates();
        return candidate;
      }
    
      async deleteCandidate(candidate) {
        await this.CandidateModel.deleteCandidate(candidate.ID);
        await this.displayCandidates();
    
    
      emptyCandidateList() {
        this.area = null;
        document.getElementById("candidate-lists-list").innerHTML = "";
        this.candidateList = null;
        document.getElementById("candidate-list").innerHTML = "";
      }