Skip to content
Snippets Groups Projects
results-zone.js 17.3 KiB
Newer Older
Alexis POYEN's avatar
Alexis POYEN committed
// Imports
import * as Auth from "/services/auth/auth.js";
import * as PartyModel from "/services/model/party-model.js";
import * as CandidateListModel from "/services/model/candidateList-model.js";
import * as AreaModel from "/services/model/area-model.js";
import * as Scroller from "/services/common/scroller.js";
Alexis POYEN's avatar
Alexis POYEN committed
import * as Common from "/services/common/common.js";
Alexis POYEN's avatar
Alexis POYEN committed

export async function mount(where, parent) {
  const resultZoneComponent = new ResultZoneComponent(parent);
  await resultZoneComponent.mount(where);
  return resultZoneComponent;
}

class ResultZoneComponent {
  constructor(parent) {
    this.parent = parent;
    this.PartyModel = PartyModel.getPartyModel();
    this.CandidateListModel = CandidateListModel.getCandidateListModel();
    this.AreaModel = AreaModel.getAreaModel();
  }

  async mount(where) {
    this.PartyModel.current_user = await Auth.GetUser();
    this.CandidateListModel.current_user = await Auth.GetUser();
    this.AreaModel.current_user = await Auth.GetUser();
    const mountpoint = where;
    document.getElementById(mountpoint).innerHTML = /* HTML */ `
      <div class="column is-half">
        <div id="map-section" class="card-no-hover">
          <header class="card-header">
            <p class="card-header-title">
              Carte
            </p>
            <button id="zoom-map" class="button is-success">
              <span class="icon is-small">
                <i class="fa fa-expand-arrows-alt"></i>
Alexis POYEN's avatar
Alexis POYEN committed
              </span>
            </button>
          </header>
          <div class="card-content">
            <div id="round-list" class="content">
              La carte du tour
            </div>
          </div>
        </div>
      </div>
      <div class="column">
        <div id="news-flow-section" class="card-no-hover">
          <header class="card-header">
            <p class="card-header-title">
              Actualités
            </p>
            <label class="checkbox">
              <input id="auto-scroll" type="checkbox" checked />
              Défilement automatique &nbsp
            </label>
            <button id="zoom-news-flow" class="button is-success">
              <span class="icon is-small">
                <i class="fa fa-expand-arrows-alt"></i>
Alexis POYEN's avatar
Alexis POYEN committed
              </span>
            </button>
          </header>
          <div class="card-content">
            <div id="news-flow" class="content">
              Flux d'actualité
            </div>
          </div>
        </div>
        <div id="results-section" class="card-no-hover" ">
        <header class="card-header">
          <p class="card-header-title">
            Résultats
          </p>
          <button id="zoom-results" class="button is-success">
            <span class="icon is-small">
              <i class="fa fa-expand-arrows-alt"></i>
Alexis POYEN's avatar
Alexis POYEN committed
            </span>
          </button>
        </header>
        <div class="card-content">
          <div id="detailed-results" class="content">
            <div class="control select">
              <select id="select-areas" class="input"></select>
            </div>
            <div class="control select">
              <select id="select-sections" class="input"></select>
            </div>
            <div id="zone-results"></div>
            <div id="zone-detaileds-results" style="display:none"></div>
          </div>
        </div>
      </div>
    `;
    this.handleDom();
Alexis POYEN's avatar
Alexis POYEN committed
    this.scroller = Scroller.scrollInit("news-flow");
Alexis POYEN's avatar
Alexis POYEN committed
  }

  resultFlowTemplate(zone) {
    let html = document.createElement("div");
    html.classList = "card-list card-no-hover";
    html.innerHTML = /* HTML */ `
      <div class="card-content clickable">
Alexis POYEN's avatar
Alexis POYEN committed
        <div id="flow-content-${zone.ID}" class="content">
          <h5 class="title is-5">${zone.Name}</h5>
        </div>
      </div>
    `;
    html.addEventListener("click", async () => {
      if (this.parent.zone == "sections") {
        let area = await this.AreaModel.getArea(zone.AreaID);
Alexis POYEN's avatar
Alexis POYEN committed
        this.refreshSections(area);
Alexis POYEN's avatar
Alexis POYEN committed
        document.getElementById("select-sections").value = zone.ID;
        document.getElementById("select-areas").value = zone.AreaID;
      } else {
        document.getElementById("select-areas").value = zone.ID;
      }
      this.displayZoneResults(zone);
    });
    return html;
  }

  handleDom() {
    let resultHandler = this;
    document.getElementById("zoom-map").addEventListener("click", function () {
      resultHandler.zoomMap();
    });
    document
      .getElementById("zoom-news-flow")
      .addEventListener("click", function () {
        resultHandler.zoomNewsFlow();
      });
    document
      .getElementById("zoom-results")
      .addEventListener("click", function () {
        resultHandler.zoomResults();
      });

    let radioButtons = document.getElementsByName("filter");
    for (var i = 0; i < radioButtons.length; i++) {
      radioButtons[i].addEventListener("click", async (e) => {
        await this.parent.calculateResults();
        this.displayResults();
      });
    }

    document.addEventListener(
      "input",
      function __listener(event) {
        if (event.target.id == "select-areas") {
          if (event.target.value != 0) {
Alexis POYEN's avatar
Alexis POYEN committed
            let area = resultHandler.parent.results.areasResults.find(
              (areaFind) => areaFind.ID == event.target.value
Alexis POYEN's avatar
Alexis POYEN committed
            if (resultHandler.parent.zone === "areas") {
Alexis POYEN's avatar
Alexis POYEN committed
              resultHandler.displayZoneResults(area);
Alexis POYEN's avatar
Alexis POYEN committed
              resultHandler.areaDisplayed = area;
            } else if (resultHandler.parent.zone === "sections") {
Alexis POYEN's avatar
Alexis POYEN committed
              resultHandler.refreshSections(area);
              resultHandler.displayZoneResults(area.Sections[0]);
Alexis POYEN's avatar
Alexis POYEN committed
              resultHandler.areaDisplayed = area;
              resultHandler.sectionDisplayed = area.Sections[0];
Alexis POYEN's avatar
Alexis POYEN committed
            }
          }
        } else if (event.target.id == "select-sections") {
Alexis POYEN's avatar
Alexis POYEN committed
          let area = resultHandler.parent.results.areasResults.find(
            (areaFind) => areaFind.ID == document.getElementById("select-areas").value
Alexis POYEN's avatar
Alexis POYEN committed
          );
          let section = area.Sections.find(
            (sectionFind) => sectionFind.ID == event.target.value
Alexis POYEN's avatar
Alexis POYEN committed
          );
          resultHandler.displayZoneResults(section);
Alexis POYEN's avatar
Alexis POYEN committed
          resultHandler.sectionDisplayed = section;
Alexis POYEN's avatar
Alexis POYEN committed
        }
      },
      false
    );
  }

  zoomMap() {
    let resultHandler = this;
    document.getElementById("map-section").parentElement.className =
      "column is-full";
    document.getElementById("zoom-map").addEventListener("click", function () {
      resultHandler.unZoom();
    });
    document.getElementById("zoom-map").innerHTML = /* HTML */ `<span
      class="icon is-small"
    >
      <i class="fa fa-compress-arrows-alt"></i>
    </span>`;
Alexis POYEN's avatar
Alexis POYEN committed
  }

  zoomNewsFlow() {
    let resultHandler = this;
    document.getElementById("news-flow-section").parentElement.className =
      "column is-full";
    document.getElementById("news-flow-section").style.height = "70vh";
    document.getElementById("map-section").parentElement.className = "column";
    document.getElementById("map-section").parentElement.style.display = "none";
    document.getElementById("results-section").style.display = "none";
    document
      .getElementById("zoom-news-flow")
      .addEventListener("click", function () {
        resultHandler.unZoom();
      });
    document.getElementById("zoom-news-flow").innerHTML = /* HTML */ `<span
      class="icon is-small"
    >
      <i class="fa fa-compress-arrows-alt"></i>
    </span>`;
Alexis POYEN's avatar
Alexis POYEN committed
  }

  zoomResults() {
    let resultHandler = this;
    document.getElementById("results-section").parentElement.className =
      "column is-full";
    document.getElementById("results-section").style.height = "70vh";
    document.getElementById("map-section").parentElement.className = "column";
    document.getElementById("map-section").parentElement.style.display = "none";
    document.getElementById("news-flow-section").style.display = "none";
    document
      .getElementById("zoom-results")
      .addEventListener("click", function () {
        resultHandler.unZoom();
      });
    document.getElementById("zoom-results").innerHTML = /* HTML */ `<span
      class="icon is-small"
    >
      <i class="fa fa-compress-arrows-alt"></i>
    </span>`;
Alexis POYEN's avatar
Alexis POYEN committed
    document.getElementById("zone-detaileds-results").style.display = "block";
  }

  unZoom() {
    document.getElementById("map-section").parentElement.className =
      "column is-half";
    document.getElementById("news-flow-section").style.height = "45vh";
    document.getElementById("results-section").style.height = "25vh";
    document.getElementById("news-flow-section").parentElement.className =
      "column is-half";
    document.getElementById("map-section").parentElement.style.display =
      "block";
    document.getElementById("results-section").style.display = "block";
    document.getElementById("news-flow-section").style.display = "block";
    document.getElementById("zone-detaileds-results").style.display = "none";
    document.getElementById("zoom-map").innerHTML = /* HTML */ `<span
      class="icon is-small"
    >
      <i class="fa fa-expand-arrows-alt"></i>
    </span>`;
    document.getElementById("zoom-news-flow").innerHTML = /* HTML */ `<span
      class="icon is-small"
    >
      <i class="fa fa-expand-arrows-alt"></i>
    </span>`;
    document.getElementById("zoom-results").innerHTML = /* HTML */ `<span
      class="icon is-small"
    >
      <i class="fa fa-expand-arrows-alt"></i>
    </span>`;
Alexis POYEN's avatar
Alexis POYEN committed

    this.handleDom();
  }

Alexis POYEN's avatar
Alexis POYEN committed
  async displayResults() {
Alexis POYEN's avatar
Alexis POYEN committed
    document.getElementById("news-flow").innerHTML = "";
    if (this.parent.zone === "areas") {
Alexis POYEN's avatar
Alexis POYEN committed
      await this.displayFlowAreas();
Alexis POYEN's avatar
Alexis POYEN committed
      this.displayAreasResults();
    } else if (this.parent.zone === "sections") {
Alexis POYEN's avatar
Alexis POYEN committed
      await this.displayFlowSections();
Alexis POYEN's avatar
Alexis POYEN committed
      this.displaySectionsResults();
    }
Alexis POYEN's avatar
Alexis POYEN committed

    if (document.getElementById("auto-scroll").checked) {
      this.scroller.scrollDiv();
    }
Alexis POYEN's avatar
Alexis POYEN committed
    document.getElementById("auto-scroll").addEventListener("change", () => {
Alexis POYEN's avatar
Alexis POYEN committed
      this.scroller.switch();
Alexis POYEN's avatar
Alexis POYEN committed
    });
  }

  async displayFlowAreas() {
    this.parent.results.areasResults.sort(function (a, b) {
      return b.DateCompletion - a.DateCompletion;
    });
    for (let j in this.parent.results.areasResults) {
      let area = this.parent.results.areasResults[j];
      if (area.status === this.parent.filter) {
        document
          .getElementById("news-flow")
          .appendChild(this.resultFlowTemplate(area));

        for (let i in area.candidateLists) {
          let party = await this.PartyModel.getParty(
            area.candidateLists[i].PartyID
          );

          document.getElementById(
            "flow-content-" + area.ID
          ).innerHTML += await this.parent.progressBarTemplate(
            area.candidateLists[i],
            party.Color
          );
        }
      }
    }
  }

  async displayFlowSections() {
    let sections = [];
    this.parent.results.areasResults.forEach((area) => {
      sections = sections.concat(area.Sections);
    });
    sections.sort(function (a, b) {
      return b.DateCompletion - a.DateCompletion;
    });

    for (let j in sections) {
      let section = sections[j];
      if (section.status === this.parent.filter) {
        document
          .getElementById("news-flow")
          .appendChild(this.resultFlowTemplate(section));

        for (let i in section.candidateLists) {
          let party = await this.PartyModel.getParty(
            section.candidateLists[i].PartyID
          );

          document.getElementById(
            "flow-content-" + section.ID
          ).innerHTML += await this.parent.progressBarTemplate(
            section.candidateLists[i],
            party.Color
          );
        }
      }
    }
  }

  displayAreasResults() {
    let selectAreas = document.getElementById("select-areas");
    document.getElementById("select-sections").parentNode.style.display =
      "none";

    for (let i = selectAreas.options.length - 1; i >= 0; i--) {
      selectAreas.remove(i);
    }

    this.parent.results.areasResults.forEach((area) => {
      let el = document.createElement("option");
      el.textContent = area.Name;
      el.value = area.ID;
      selectAreas.appendChild(el);
    });

Alexis POYEN's avatar
Alexis POYEN committed
    if (this.parent.zone == "areas" && this.areaDisplayed != undefined) {
      document.getElementById("select-areas").value = this.areaDisplayed.ID;
    } else this.displayZoneResults(this.parent.results.areasResults[0]);
Alexis POYEN's avatar
Alexis POYEN committed
  }

  displaySectionsResults() {
    let selectAreas = document.getElementById("select-areas");
    document.getElementById("select-sections").parentNode.style.display =
      "block";

    for (let i = selectAreas.options.length - 1; i >= 0; i--) {
      selectAreas.remove(i);
    }

    this.parent.results.areasResults.forEach((area) => {
      let el = document.createElement("option");
      el.textContent = area.Name;
      el.value = area.ID;
      selectAreas.appendChild(el);
    });

Alexis POYEN's avatar
Alexis POYEN committed
    this.refreshSections(this.parent.results.areasResults[0]);
Alexis POYEN's avatar
Alexis POYEN committed
    if (this.parent.zone == "sections" && this.sectionDisplayed != undefined) {
      document.getElementById("select-areas").value = this.areaDisplayed.ID;
      this.refreshSections(this.areaDisplayed);
      document.getElementById(
        "select-sections"
      ).value = this.sectionDisplayed.ID;
    } else {
      this.displayZoneResults(this.parent.results.areasResults[0].Sections[0]);
    }
Alexis POYEN's avatar
Alexis POYEN committed
  }

  async displayZoneResults(zone) {
    if (zone.status !== this.parent.filter) {
      if (zone.status == "no_results") {
        document.getElementById(
          "zone-results"
Alexis POYEN's avatar
Alexis POYEN committed
        ).innerHTML = Common.warningMessage(
          "Pas de résultats",
Alexis POYEN's avatar
Alexis POYEN committed
          "Aucun résultats n'ont étaient saisis sur cette zone"
        );
      } else if (zone.status == "incompleted") {
        document.getElementById(
          "zone-results"
Alexis POYEN's avatar
Alexis POYEN committed
        ).innerHTML = Common.warningMessage(
          "Pas complets",
Alexis POYEN's avatar
Alexis POYEN committed
          "Les résultats pour cette zone ne sont pas complets"
        );
      } else if (zone.status == "not validated") {
        document.getElementById(
          "zone-results"
Alexis POYEN's avatar
Alexis POYEN committed
        ).innerHTML = Common.warningMessage(
          "Non validé",
Alexis POYEN's avatar
Alexis POYEN committed
          "Les résultats pour cette zone n'ont pas étaient validés"
        );
      }
      document.getElementById("zone-detaileds-results").innerHTML = "";
    } else {
      document.getElementById("zone-results").innerHTML =
        '<br/><h5 class="title is-5">Résultats</h5>';
      for (let i in zone.candidateLists) {
        let electedsNumber = null;
        if (
          this.parent.zone === "areas" &&
          zone.candidateLists[i].SeatsAttributed > 0 &&
          zone.stats.PercentageConsiderated == 100
        ) {
          electedsNumber = zone.candidateLists[i].SeatsAttributed;
        }
        let party = await this.PartyModel.getParty(
          zone.candidateLists[i].PartyID
        );
        document.getElementById(
          "zone-results"
        ).innerHTML += this.parent.progressBarTemplate(
          zone.candidateLists[i],
          party.Color,
          electedsNumber
        );
      }
      this.displayZoneDetailedResults(zone);
    }
    document.getElementById(
      "detailed-results"
    ).scrollTop = document.getElementById("zone-results").offsetTop;
  }

  async displayZoneDetailedResults(zone) {
    document.getElementById("zone-detaileds-results").innerHTML =
      '<br/><h5 class="title is-5">Statistiques</h5>';

    if (this.parent.filter === "partial")
      document.getElementById(
        "zone-detaileds-results"
      ).innerHTML += this.parent.progressBarTemplate(
        {
          Name: "Pourcentage de saisie",
          Percentage: zone.stats.PercentageConsiderated,
          VoiceNumber: null,
        },
        "grey",
        null
      );
    document.getElementById(
      "zone-detaileds-results"
    ).innerHTML += this.parent.progressBarTemplate(
      {
        Name: "Abstention",
        Percentage: zone.stats.Abstention,
        VoiceNumber: null,
      },
      "grey",
      null
    );
    document.getElementById(
      "zone-detaileds-results"
    ).innerHTML += this.parent.progressBarTemplate(
      {
        Name: "Votes blancs",
        Percentage: zone.stats.BlankPercentage,
        VoiceNumber: zone.stats.BlankVoiceNumber,
      },
      "grey",
      null
    );
    document.getElementById(
      "zone-detaileds-results"
    ).innerHTML += this.parent.progressBarTemplate(
      {
        Name: "Votes nuls",
        Percentage: zone.stats.NullVotePercentage,
        VoiceNumber: zone.stats.NullVoteVoiceNumber,
      },
      "grey",
      null
    );
    if (
      this.parent.zone === "areas" &&
      zone.stats.PercentageConsiderated == 100
    ) {
      document.getElementById("zone-detaileds-results").innerHTML +=
        '<br/><h5 class="title is-5">Élus</h5>';
      for (let i in zone.Electeds) {
        let candidateList = await this.CandidateListModel.getCandidateList(
          zone.Electeds[i].CandidateListID
        );
        document.getElementById("zone-detaileds-results").innerHTML +=
          zone.Electeds[i].FullName + " (" + candidateList.Name + ")<br/>";
      }
    }
  }
Alexis POYEN's avatar
Alexis POYEN committed

  refreshSections(area) {
    let selectSections = document.getElementById("select-sections");
    selectSections.parentNode.style.display = "block";
    for (let i = selectSections.options.length - 1; i >= 0; i--) {
      selectSections.remove(i);
    }
    for (let i in area.Sections) {
      let el = document.createElement("option");
      el.textContent = area.Sections[i].Name;
      el.value = area.Sections[i].ID;
      selectSections.appendChild(el);
    }
  }