diff --git a/web/components/management/candidate-lists.js b/web/components/management/candidate-lists.js index c4022618b78a75d1385963017943e468192c3257..f9701a61d5d462f5ff780e14c42c46b12ac545de 100644 --- a/web/components/management/candidate-lists.js +++ b/web/components/management/candidate-lists.js @@ -51,9 +51,65 @@ class CandidateList { </header> <div id="candidate-lists-dropdown-content" class="columns card-content"> <div class="column"> + <h5 class="title is-5"> + Circonscriptions + </h5> + <div class="field"> + <p class="control has-icons-right"> + <input + id="area-search" + class="input" + placeholder="Rechercher une circonscription" + /> + <span class="icon is-small is-right"> + <i class="fas fa-search"></i> + </span> + </p> + </div> <div id="areas-round"></div> </div> <div class="column"> + <nav class="level"> + <div class="level-left"> + <h5 class="title is-5"> + Listes + </h5> + </div> + <div class="level-right"> + <button + id="candidate-list-clone" + class="button large-button is-primary" + title="Importer une liste" + disabled + > + <span class="icon is-small"> + <i class="fas fa-download"></i> + </span> + </button> + <button + id="candidate-list-new" + class="button large-button is-success" + title="Ajouter une liste" + disabled + > + <span class="icon is-small"> + <i class="fas fa-plus"></i> + </span> + </button> + </div> + </nav> + <div class="field"> + <p class="control has-icons-right"> + <input + id="list-search" + class="input" + placeholder="Rechercher une liste" + /> + <span class="icon is-small is-right"> + <i class="fas fa-search"></i> + </span> + </p> + </div> <div id="candidate-lists-list"></div> </div> <div class="column is-two-thirds"> @@ -373,6 +429,17 @@ class CandidateList { handleDom() { let candidateListHandler = this; + document + .getElementById(`candidate-list-new`) + .addEventListener("click", function () { + candidateListHandler.newCandidateList(); + }); + + document + .getElementById(`candidate-list-clone`) + .addEventListener("click", function () { + candidateListHandler.cloneCandidateListModal(); + }); document .getElementById(`candidateList-modal-close`) .addEventListener("click", function () { @@ -402,14 +469,18 @@ class CandidateList { } await candidateListHandler.saveCandidateList(); }); + + document.getElementById("area-search").addEventListener("keyup", (e) => { + this.displayAreas(); + }); + + document.getElementById("list-search").addEventListener("keyup", (e) => { + this.displayCandidateLists(); + }); } async displayAreas() { - document.getElementById("areas-round").innerHTML = /* HTML */ `<h5 - class="title is-5" - > - Circonscriptions - </h5>`; + document.getElementById("areas-round").innerHTML = /* HTML */ ``; let candidateListHandler = this; let areas = await this.updateAreas(); const markup = areas.map((area) => this.areaTemplate(area)).join(""); @@ -431,9 +502,14 @@ class CandidateList { async updateAreas() { let candidateListHandler = this; let areas = await this.AreaModel.getAreas(); - return areas.filter(function (area) { + areas = areas.filter(function (area) { return area.ElectionID == candidateListHandler.round.ElectionID; }); + return areas.filter((area) => + area.Name.toLowerCase().includes( + document.getElementById("area-search").value.toLowerCase() + ) + ); } async activateArea(areaToActivate) { @@ -468,29 +544,7 @@ class CandidateList { async displayCandidateLists() { let candidateListHandler = this; let candidateLists = await this.updateCandidateLists(); - document.getElementById("candidate-lists-list").innerHTML = /* HTML */ `<h5 - class="title is-5" - > - Listes - </h5> - <button - id="candidate-list-new" - class="button large-button is-success" - title="Ajouter une liste" - > - <span class="icon is-small"> - <i class="fas fa-plus"></i> - </span> - </button> - <button - id="candidate-list-clone" - class="button large-button is-primary" - title="Importer une liste" - > - <span class="icon is-small"> - <i class="fas fa-download"></i> - </span> - </button>`; + document.getElementById("candidate-lists-list").innerHTML = /* HTML */ ``; const markup = candidateLists .map((candidateList) => this.candidateListTemplate(candidateList)) .join(""); @@ -522,29 +576,24 @@ class CandidateList { await candidateListHandler.displayCandidates(); }); }); - - document - .getElementById(`candidate-list-new`) - .addEventListener("click", function () { - candidateListHandler.newCandidateList(); - }); - - document - .getElementById(`candidate-list-clone`) - .addEventListener("click", function () { - candidateListHandler.cloneCandidateListModal(); - }); + document.getElementById(`candidate-list-new`).removeAttribute("disabled"); + document.getElementById(`candidate-list-clone`).removeAttribute("disabled"); } async updateCandidateLists() { let candidateListHandler = this; let candidateLists = await this.CandidateListModel.getCandidateLists(); - return candidateLists.filter(function (candidateList) { + candidateLists = candidateLists.filter(function (candidateList) { return ( candidateList.AreaID == candidateListHandler.area.ID && candidateList.RoundID == candidateListHandler.round.ID ); }); + return candidateLists.filter((candidateList) => + candidateList.Name.toLowerCase().includes( + document.getElementById("list-search").value.toLowerCase() + ) + ); } async updateCandidates() { @@ -727,6 +776,12 @@ class CandidateList { this.area = null; document.getElementById("candidate-lists-list").innerHTML = ""; this.emptyCandidate(); + document + .getElementById(`candidate-list-new`) + .setAttribute("disabled", "true"); + document + .getElementById(`candidate-list-clone`) + .setAttribute("disabled", "true"); } emptyCandidate() { diff --git a/web/components/management/party.js b/web/components/management/party.js index 84e54a87e53403d635674d4c148454345a26914f..808c594f08dbfa244dcfcfb2a63e9ba2c270797f 100644 --- a/web/components/management/party.js +++ b/web/components/management/party.js @@ -32,11 +32,34 @@ class Party { > <div id="parties-card" class="card-no-hover"> <header class="card-header"> - <p class="card-header-title"> - Partis - </p> + <nav class="level" style="width:99%"> + <div class="level-left"> + <p class="card-header-title"> + Partis + </p> + </div> + <div class="level-right"> + <div class="field"> + <p class="control has-icons-right"> + <input + id="party-search" + class="input" + placeholder="Rechercher un parti" + /> + <span class="icon is-small is-right"> + <i class="fas fa-search"></i> + </span> + </p> + </div> + </div> + </nav> </header> <div class="card-content"> + <button id="party-new" class="button large-button is-success"> + <span class="icon is-small"> + <i class="fas fa-plus"></i> + </span> + </button> <div id="party-list" class="content auto-overflow-election-management" @@ -70,6 +93,10 @@ class Party { .addEventListener("click", async function () { await partyHandler.saveParty(); }); + + document.getElementById("party-search").addEventListener("keyup", (e) => { + this.displayParties(); + }); } mountModal(where) { @@ -150,16 +177,14 @@ class Party { } async displayParties() { - document.getElementById("party-list").innerHTML = /* HTML */ `<button - id="party-new" - class="button large-button is-success" - > - <span class="icon is-small"> - <i class="fas fa-plus"></i> - </span> - </button>`; + document.getElementById("party-list").innerHTML = /* HTML */ ``; let parties = await this.PartyModel.getParties(); + parties = parties.filter((party) => + party.Name.toLowerCase().includes( + document.getElementById("party-search").value.toLowerCase() + ) + ); const markup = parties.map((party) => this.partyTemplate(party)).join(""); document.getElementById("party-list").innerHTML += markup; @@ -279,7 +304,7 @@ class Party { this.PartyModel.checkInputs( this.method, parseInt(document.getElementById("party-modal-id").value), - document.getElementById("party-modal-name").value, + document.getElementById("party-modal-name").value ) ) { party = await this.PartyModel.saveParty( diff --git a/web/components/management/round-desks.js b/web/components/management/round-desks.js index d9ccedc4f1db2aef42620f7efd89e139a3afc630..e877214d3aa89681bfa0668ce93debced3c475fe 100644 --- a/web/components/management/round-desks.js +++ b/web/components/management/round-desks.js @@ -42,7 +42,22 @@ class RoundDesk { </header> <div id="desk-rounds-dropdown-content" class="columns card-content"> <div class="column"> - <div id="desk-rounds"></div> + <h5 class="title is-5"> + Bureaux de votes + </h5> + <div class="field"> + <p class="control has-icons-right"> + <input + id="desk-search" + class="input" + placeholder="Rechercher un bureau" + /> + <span class="icon is-small is-right"> + <i class="fas fa-search"></i> + </span> + </p> + </div> + <div id="desk-rounds-list"></div> </div> <div class="column"> <div id="desk-round-details"></div> @@ -58,15 +73,15 @@ class RoundDesk { } handleDom() { - document - .getElementById(`round-new`) - .addEventListener("click", function () {}); - document .getElementById(`capturers-modal-close`) .addEventListener("click", function () { Common.toggleModal("capturers-modal", "capturers-modal-card"); }); + + document.getElementById("desk-search").addEventListener("keyup", (e) => { + this.displayDesks(); + }); } mountModal(where) { @@ -126,10 +141,7 @@ class RoundDesk { > <div class="content"> <nav class="level"> - <div - id="deskrounds-deskround-desc-${deskRound.ID}" - class="level-left" - ></div> + ${deskRound.Name} <div class="level-right"> <a id="deskrounds-deskround-capturers-${deskRound.ID}" @@ -215,24 +227,16 @@ class RoundDesk { } async displayDesks() { - document.getElementById("desk-rounds").innerHTML = /* HTML */ `<h5 - class="title is-5" - > - Bureaux de votes - </h5>`; + document.getElementById("desk-rounds-list").innerHTML = /* HTML */ ``; let deskRounds = await this.updateDeskRounds(); const markup = deskRounds .map((deskRound) => this.deskRoundTemplate(deskRound)) .join(""); - document.getElementById("desk-rounds").innerHTML += markup; + document.getElementById("desk-rounds-list").innerHTML += markup; let deskRoundHandler = this; deskRoundHandler.emptyDesksDetails(); - deskRounds.map(async (deskRound) => { - let desk = await this.DeskModel.getDesk(deskRound.DeskID); - document.getElementById( - `deskrounds-deskround-desc-${deskRound.ID}` - ).innerHTML = desk.Name; + deskRounds.map((deskRound) => { document .getElementById(`deskrounds-deskround-${deskRound.ID}`) .addEventListener("click", async function () { @@ -279,9 +283,18 @@ class RoundDesk { async updateDeskRounds() { let deskRoundHandler = this; let deskRounds = await this.DeskRoundModel.getDeskRounds(); - return deskRounds.filter(function (deskRound) { + deskRounds = deskRounds.filter(function (deskRound) { return deskRound.RoundID == deskRoundHandler.round.ID; }); + for (let i in deskRounds) { + let desk = await this.DeskModel.getDesk(deskRounds[i].DeskID); + deskRounds[i].Name = desk.Name; + } + return deskRounds.filter((desk) => + desk.Name.toLowerCase().includes( + document.getElementById("desk-search").value.toLowerCase() + ) + ); } async saveDeskRound() { diff --git a/web/services/election/calculate-election-generic.js b/web/services/election/calculate-election-generic.js index 989cbef8acdf5976ba51ac9c9e313c77c8587a55..36d8c30d2df243d88919a7196b0f8a2f6d097d38 100644 --- a/web/services/election/calculate-election-generic.js +++ b/web/services/election/calculate-election-generic.js @@ -463,7 +463,7 @@ class ElectionCalculator { return electeds; } - getElectedsLocalCounsilDirect(area) { + getElectedsAllForFirst(area) { let electeds = []; // order candidates by rank and remove refused or removed candidates @@ -486,6 +486,8 @@ class ElectionCalculator { area.candidateLists[0].Candidates.splice(0, seatForFirst) ); + area.candidateLists[0].SeatsAttributed += seatForFirst; + return electeds; } } diff --git a/web/style.css b/web/style.css index 56fdee475f424520ebf2464be7bd5878bc89376b..afdce6fffb7cf8c2e38c876fac73bbac8babefdd 100644 --- a/web/style.css +++ b/web/style.css @@ -107,7 +107,7 @@ select { } .card-content .level-left { - flex-basis: 70%; + flex-basis: 65%; } #vote-section .level-left {