From da8b4167854286378a52f7e4af30b82dd59d1bb8 Mon Sep 17 00:00:00 2001 From: iziram Date: Tue, 13 Jun 2023 16:25:45 +0200 Subject: [PATCH] Assiduites : Modif Live + Toasts + filtre Liste --- app/static/css/assiduites.css | 23 +++ app/static/icons/aucun.svg | 8 + app/static/icons/sort.svg | 1 + app/static/js/assiduites.js | 158 +++++++++++++----- app/templates/assiduites/differee.j2 | 59 ++++++- app/templates/assiduites/liste_assiduites.j2 | 157 ++++++++++++++--- .../assiduites/signal_assiduites_etud.j2 | 8 +- .../assiduites/signal_assiduites_group.j2 | 26 ++- app/templates/assiduites/timeline.j2 | 36 ++++ app/templates/assiduites/toast.j2 | 8 + 10 files changed, 413 insertions(+), 71 deletions(-) create mode 100755 app/static/icons/aucun.svg create mode 100644 app/static/icons/sort.svg diff --git a/app/static/css/assiduites.css b/app/static/css/assiduites.css index d4f129a78..2b8e1d573 100644 --- a/app/static/css/assiduites.css +++ b/app/static/css/assiduites.css @@ -10,6 +10,10 @@ opacity: 0.5; } +#validate_selectors { + margin-top: 5vh; +} + .no-display { display: none !important; } @@ -246,6 +250,10 @@ background-image: url(../icons/absent.svg); } +.rbtn.aucun::before { + background-image: url(../icons/aucun.svg); +} + .rbtn.retard::before { background-image: url(../icons/retard.svg); } @@ -497,4 +505,19 @@ border: 1px dashed #333; width: 75%; padding: 20px; +} + +.order { + display: block; + width: 24px; + height: 24px; + background-image: url(../icons/sort.svg); + outline: none; + border: none; + cursor: pointer; +} + +.order:focus { + outline: none; + border: none; } \ No newline at end of file diff --git a/app/static/icons/aucun.svg b/app/static/icons/aucun.svg new file mode 100755 index 000000000..eaff20043 --- /dev/null +++ b/app/static/icons/aucun.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/app/static/icons/sort.svg b/app/static/icons/sort.svg new file mode 100644 index 000000000..9a5aef00f --- /dev/null +++ b/app/static/icons/sort.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/static/js/assiduites.js b/app/static/js/assiduites.js index 4f736c68d..e543fad6f 100644 --- a/app/static/js/assiduites.js +++ b/app/static/js/assiduites.js @@ -20,17 +20,7 @@ let justificatifs = {}; // Variable qui définit si le processus d'action de masse est lancé let currentMassAction = false; - -/** - * Variable de gestion des conflits - */ -let modal; -let closeBtn; -let timeline; -let deleteBtn; -let splitBtn; -let editBtn; -let selectedAssiduite; +let currentMassActionEtat = undefined; /** * Ajout d'une fonction `capitalize` sur tous les strings @@ -74,7 +64,7 @@ function setupCheckBox(parent = document) { * - Module impl * - Date */ -function validateSelectors() { +function validateSelectors(btn) { const action = () => { const group_ids = getGroupIds(); @@ -113,6 +103,8 @@ function validateSelectors() { document.querySelector(".selectors").disabled = true; generateMassAssiduites(); generateAllEtudRow(); + btn.remove(); + onlyAbs(); }; if (!verifyDateInSemester()) { @@ -133,6 +125,14 @@ function validateSelectors() { action(); } +function onlyAbs() { + if (getDate() > moment()) { + document + .querySelectorAll(".rbtn.present, .rbtn.retard") + .forEach((el) => el.remove()); + } +} + /** * Limite le nombre de checkbox marquée * Vérifie aussi si le cliqué est fait sur des assiduités conflictuelles @@ -287,6 +287,7 @@ function executeMassActionQueue() { console.error(data, status); } ); + return createQueue.length; }; //Fonction qui modifie les assiduités de la queue 'edition' @@ -312,6 +313,7 @@ function executeMassActionQueue() { console.error(data, status); } ); + return editQueue.length; }; //Fonction qui supprime les assiduités de la queue 'supprimer' @@ -328,12 +330,44 @@ function executeMassActionQueue() { console.error(data, status); } ); + return toDelete.length; }; //On exécute les fonctions de queue - create(); - edit(); - supprimer(); + let color; + switch (currentMassActionEtat.toUpperCase()) { + case "PRESENT": + color = "#6bdb83"; + break; + case "ABSENT": + color = "#F1A69C"; + break; + case "RETARD": + color = "#f0c865"; + break; + default: + color = "#AAA"; + break; + } + let count = 0; + if (currentMassActionEtat == "remove") { + count += supprimer(); + const span = document.createElement("span"); + span.innerHTML = `${count} assiduités ont été supprimées.`; + pushToast(generateToast(span, color, 5)); + } else { + count += create(); + count += edit(); + const etat = + currentMassActionEtat.toUpperCase() == "RETARD" + ? "En retard" + : currentMassActionEtat; + const span = document.createElement("span"); + span.innerHTML = `${count} étudiants ont été mis ${etat + .capitalize() + .trim()}`; + pushToast(generateToast(span, color, 5)); + } //On récupère les assiduités puis on regénère les lignes d'étudiants getAssiduitesFromEtuds(true); generateAllEtudRow(); @@ -346,7 +380,10 @@ function massAction() { //On récupère tous les boutons d'assiduités const fields = Array.from(document.querySelectorAll(".btns_field.single")); //On récupère l'état de l'action de masse - const action = getAssiduiteValue(document.querySelector(".btns_field.mass")); + currentMassActionEtat = getAssiduiteValue( + document.querySelector(".btns_field.mass") + ); + //On remet à 0 les queues resetMassActionQueue(); @@ -366,7 +403,11 @@ function massAction() { */ fields.forEach((field) => { if (field.getAttribute("type") != "conflit") { - field.querySelector(`.rbtn.${action}`).click(); + if (currentMassActionEtat != "remove") { + field.querySelector(`.rbtn.${currentMassActionEtat}`).click(); + } else { + field.querySelector(".rbtn.absent").click(); + } } else { const etudid = field.getAttribute("etudid"); conflicts.push(etuds[parseInt(etudid)]); @@ -379,6 +420,7 @@ function massAction() { //Fin du processus, on remet à false currentMassAction = false; + currentMassActionEtat = undefined; //On remet à zero les boutons d'assiduité de masse const boxes = Array.from( @@ -423,6 +465,7 @@ function generateMassAssiduites() { class="rbtn present"> + `; content.insertBefore(mass, content.querySelector(".etud_holder")); @@ -953,7 +996,6 @@ function actualizeEtudAssiduite(etudid, has_formsemestre = true) { getUrl() + `/api/assiduites/${etudid}/query?${formsemestre_id}date_debut=${date_debut}&date_fin=${date_fin}`; sync_get(url_api, (data, status) => { - console.error(data, status); if (status === "success") { assiduites[etudid] = data; } @@ -991,20 +1033,22 @@ function assiduiteAction(element) { // Cas de l'action de masse -> peuplement des queues if (currentMassAction) { - switch (type) { - case "création": - addToMassActionQueue("creer", { etat: etat, etudid: etudid }); - break; - case "édition": - if (etat === "remove") { - addToMassActionQueue("supprimer", assiduite_id); - } else { - addToMassActionQueue("editer", { - etat: etat, - assiduite_id: assiduite_id, - }); - } - break; + if (currentMassActionEtat != "remove") { + switch (type) { + case "création": + addToMassActionQueue("creer", { etat: etat, etudid: etudid }); + break; + case "édition": + if (etat != "remove") { + addToMassActionQueue("editer", { + etat: etat, + assiduite_id: assiduite_id, + }); + } + break; + } + } else if (type == "édition") { + addToMassActionQueue("supprimer", assiduite_id); } } else { // Cas normal -> mise à jour en base @@ -1042,13 +1086,49 @@ function assiduiteAction(element) { } if (type != "conflit") { - document - .querySelector(".toast-holder") - .appendChild( - generateToast( - document.createTextNode("L'assiduité a bien été enregistrée.") - ) - ); + let etatAffiche; + + switch (etat.toUpperCase()) { + case "PRESENT": + etatAffiche = + "%etud% a été noté(e) présent(e)"; + break; + case "RETARD": + etatAffiche = + "%etud% a été noté(e) en retard"; + break; + case "ABSENT": + etatAffiche = + "%etud% a été noté(e) absent(e)"; + break; + case "REMOVE": + etatAffiche = "L'assiduité de %etud% a été retirée."; + } + + let color; + + switch (etat.toUpperCase()) { + case "PRESENT": + color = "#6bdb83"; + break; + case "ABSENT": + color = "#F1A69C"; + break; + case "RETARD": + color = "#f0c865"; + break; + default: + color = "#AAA"; + break; + } + + const nom_prenom = `${etuds[etudid].nom.toUpperCase()} ${etuds[ + etudid + ].prenom.capitalize()}`; + const span = document.createElement("span"); + span.innerHTML = etatAffiche.replace("%etud%", nom_prenom); + + pushToast(generateToast(span, color, 5)); } actualizeEtud(etudid, !isSingleEtud); diff --git a/app/templates/assiduites/differee.j2 b/app/templates/assiduites/differee.j2 index 54745d30d..756bdf88e 100644 --- a/app/templates/assiduites/differee.j2 +++ b/app/templates/assiduites/differee.j2 @@ -692,6 +692,52 @@ }) } + function launchToast(etudid, etat) { + let etatAffiche; + + switch (etat.toUpperCase()) { + case "PRESENT": + etatAffiche = + "%etud% a été noté(e) présent(e)"; + break; + case "RETARD": + etatAffiche = + "%etud% a été noté(e) en retard"; + break; + case "ABSENT": + etatAffiche = + "%etud% a été noté(e) absent(e)"; + break; + case "REMOVE": + etatAffiche = "L'assiduité de %etud% a été retirée."; + } + + let color; + + switch (etat.toUpperCase()) { + case "PRESENT": + color = "#6bdb83"; + break; + case "ABSENT": + color = "#F1A69C"; + break; + case "RETARD": + color = "#f0c865"; + break; + default: + color = "#AAA"; + break; + } + + const nom_prenom = `${etuds[etudid].nom.toUpperCase()} ${etuds[ + etudid + ].prenom.capitalize()}`; + const span = document.createElement("span"); + span.innerHTML = etatAffiche.replace("%etud%", nom_prenom); + + pushToast(generateToast(span, color, 5)); + } + function updateEtudAssiduite(rbtn) { const [_, colid, etudid] = rbtn.name.split("_"); @@ -714,8 +760,8 @@ assiduite["assiduite_id"] = assi_id; assiduites[etudid].push(assiduite); updateAllCol() + launchToast(etudid, etat); - // TODO Envoyer toast } }) break; @@ -761,7 +807,12 @@ } asyncEditAssiduite(edit, (data) => { - console.log(data) + const obj = getAssiduite(etudid, assi); + + obj.moduleimpl = edit.moduleimpl_id; + obj.etat = edit.etat; + + launchToast(etudid, etat); }) break; @@ -769,6 +820,10 @@ } + function getAssiduite(etudid, id) { + return assiduites[etudid].filter((a) => a.assiduite_id == id) + } + function asyncCreateAssiduite(assi, callback = () => { }) { const path = getUrl() + `/api/assiduite/${assi.etudid}/create`; async_post( diff --git a/app/templates/assiduites/liste_assiduites.j2 b/app/templates/assiduites/liste_assiduites.j2 index 0f60c91d4..685e191e5 100644 --- a/app/templates/assiduites/liste_assiduites.j2 +++ b/app/templates/assiduites/liste_assiduites.j2 @@ -10,11 +10,36 @@ - - - - - + + + + + @@ -26,10 +51,30 @@
DébutFinÉtatModuleJustifiée +
+ Début + +
+
+
+ Fin + +
+
+
+ État + +
+
+
+ Module + +
+
+
+ Justifiée + +
+
- - - - + + + + @@ -70,6 +115,7 @@ th { background-color: #f2f2f2; + } tr:hover { @@ -138,6 +184,12 @@ color: #fff; border-color: #007bff; } + + th>div { + display: flex; + justify-content: space-between; + align-items: center; + } diff --git a/app/templates/assiduites/signal_assiduites_group.j2 b/app/templates/assiduites/signal_assiduites_group.j2 index 0bacda8f2..fc80e5fcc 100644 --- a/app/templates/assiduites/signal_assiduites_group.j2 +++ b/app/templates/assiduites/signal_assiduites_group.j2 @@ -22,14 +22,14 @@ Date: - - {{timeline|safe}} + +

Veillez à choisir le groupe concerné par la saisie ainsi que la date de la saisie. @@ -77,5 +77,23 @@ window.forceModule = "{{ forcer_module }}" window.forceModule = window.forceModule == "True" ? true : false + if (window.forceModule) { + const btn = document.getElementById("validate_selectors"); + + const select = document.getElementById("moduleimpl_select"); + + if (select.value == "") { + btn.disabled = true; + } + + select.addEventListener('change', (e) => { + if (e.target.value != "") { + btn.disabled = false; + } else { + btn.disabled = true; + } + }); + } + \ No newline at end of file diff --git a/app/templates/assiduites/timeline.j2 b/app/templates/assiduites/timeline.j2 index ce8e59e72..5a53ce651 100644 --- a/app/templates/assiduites/timeline.j2 +++ b/app/templates/assiduites/timeline.j2 @@ -2,6 +2,7 @@

+
Time
DébutFinÉtatRaison +
+ Début + +
+
+
+ Fin + +
+
+
+ État + +
+
+
+ Raison + +
+