From f485791e3bba6469da117269d8b560b63c16b772 Mon Sep 17 00:00:00 2001 From: Iziram Date: Thu, 16 Nov 2023 14:25:06 +0100 Subject: [PATCH] Assiduites : Gestions couleurs + bugfix calendrier Close #800 --- app/static/css/assiduites.css | 70 +++- app/static/icons/absent.svg | 16 +- app/static/icons/absent_ancien.svg | 11 + app/static/icons/aucun.svg | 2 +- app/static/icons/present.svg | 4 +- app/static/icons/retard.svg | 4 +- app/static/js/assiduites.js | 2 +- app/static/js/date_utils.js | 11 + .../assiduites/pages/ajout_justificatif.j2 | 2 +- app/templates/assiduites/pages/calendrier.j2 | 303 ++++++++++++------ .../pages/signal_assiduites_etud.j2 | 13 +- .../pages/signal_assiduites_group.j2 | 12 +- app/templates/assiduites/widgets/alert.j2 | 2 +- app/templates/assiduites/widgets/conflict.j2 | 16 +- app/templates/assiduites/widgets/differee.j2 | 22 +- .../assiduites/widgets/legende_couleur.j2 | 12 + .../assiduites/widgets/minitimeline.j2 | 18 +- app/templates/assiduites/widgets/prompt.j2 | 2 +- .../assiduites/widgets/tableau_assi.j2 | 6 +- .../assiduites/widgets/tableau_base.j2 | 16 +- .../assiduites/widgets/tableau_justi.j2 | 6 +- app/templates/assiduites/widgets/timeline.j2 | 4 +- app/templates/assiduites/widgets/toast.j2 | 8 +- 23 files changed, 357 insertions(+), 205 deletions(-) mode change 100755 => 100644 app/static/icons/absent.svg create mode 100755 app/static/icons/absent_ancien.svg create mode 100644 app/templates/assiduites/widgets/legende_couleur.j2 diff --git a/app/static/css/assiduites.css b/app/static/css/assiduites.css index c935f4f83..fe429ecfc 100644 --- a/app/static/css/assiduites.css +++ b/app/static/css/assiduites.css @@ -1,3 +1,33 @@ +:root { + --color-present: #6bdb83; + --color-absent: #e62a11; + --color-retard: #f0c865; + --color-justi: #7059FF; + --color-justi-invalide: #a84476; + --color-nonwork: #badfff; + + --color-absent-justi: #e65ab7; + --color-retard-justi: #ffef7a; + + --color-error: #FF0000; + --color-warning: #eec660; + --color-information: #658ef0; + + --color-def: #d61616; + --color-conflit: #ff00009c; + --color-bg-def: #c8c8c8; + --color-primary: #7059FF; + --color-secondary: #6f9fff; + + --color-defaut: #FFF; + --color-defaut-dark: #444; + + + + --motif-justi: repeating-linear-gradient(135deg, transparent, transparent 4px, var(--color-justi) 4px, var(--color-justi) 8px); + --motif-justi-invalide: repeating-linear-gradient(-135deg, transparent, transparent 4px, var(--color-justi-invalide) 4px, var(--color-justi-invalide) 8px); +} + * { box-sizing: border-box; } @@ -87,7 +117,7 @@ } .ui-slider-range.ui-widget-header.ui-corner-all { - background-color: #F9C768; + background-color: var(--color-warning); background-image: none; opacity: 0.50; visibility: visible; @@ -122,7 +152,7 @@ .etud_row.def, .etud_row.dem { - background-color: #c8c8c8; + background-color: var(--color-bg-def); } /* --- Index --- */ @@ -149,7 +179,7 @@ .tr.def .td.sticky span::after { display: block; content: " (Déf.)"; - color: #d61616; + color: var(--color-def); margin-left: 2px; } @@ -157,7 +187,7 @@ .tr.dem .td.sticky span::after { display: block; content: " (Dém.)"; - color: #d61616; + color: var(--color-def); margin-left: 2px; } @@ -213,32 +243,36 @@ } .etud_row.conflit { - background-color: #ff0000c2; + background-color: var(--color-conflit); } .etud_row .assiduites_bar .absent, .demo.absent { - background-color: #F1A69C !important; + background-color: var(--color-absent) !important; } .etud_row .assiduites_bar .present, .demo.present { - background-color: #9CF1AF !important; + background-color: var(--color-present) !important; } .etud_row .assiduites_bar .retard, .demo.retard { - background-color: #F1D99C !important; + background-color: var(--color-retard) !important; +} + +.demo.nonwork { + background-color: var(--color-nonwork) !important; } .etud_row .assiduites_bar .justified, .demo.justified { - background-image: repeating-linear-gradient(135deg, transparent, transparent 4px, #7059FF 4px, #7059FF 8px); + background-image: var(--motif-justi); } .etud_row .assiduites_bar .invalid_justified, .demo.invalid_justified { - background-image: repeating-linear-gradient(225deg, transparent, transparent 4px, #d61616 4px, #d61616 8px); + background-image: var(--motif-justi-invalide); } @@ -273,27 +307,35 @@ height: 35px; background-position: center; background-size: cover; + border-radius: 5px; + border: 1px solid var(--color-defaut-dark); } .rbtn.present::before { background-image: url(../icons/present.svg); + background-color: var(--color-present); + } .rbtn.absent::before { + background-color: var(--color-absent); background-image: url(../icons/absent.svg); } .rbtn.aucun::before { background-image: url(../icons/aucun.svg); + background-color: var(--color-defaut-dark); + } .rbtn.retard::before { + background-color: var(--color-retard); background-image: url(../icons/retard.svg); } .rbtn:checked:before { - outline: 5px solid #7059FF; + outline: 5px solid var(--color-primary); border-radius: 50%; } @@ -486,7 +528,7 @@ .loader { border: 6px solid #f3f3f3; border-radius: 50%; - border-top: 6px solid #3498db; + border-top: 6px solid var(--color-primary); width: 60px; height: 60px; position: absolute; @@ -532,7 +574,7 @@ } .rouge { - color: crimson; + color: var(--color-error); } .legende { @@ -588,7 +630,7 @@ #forcemodule { border-radius: 8px; - background: crimson; + background: var(--color-error); max-width: fit-content; padding: 5px; color: white; diff --git a/app/static/icons/absent.svg b/app/static/icons/absent.svg old mode 100755 new mode 100644 index 697635cd9..5c6385bf5 --- a/app/static/icons/absent.svg +++ b/app/static/icons/absent.svg @@ -1,11 +1,9 @@ - - - - + + + + + + + - - - - - diff --git a/app/static/icons/absent_ancien.svg b/app/static/icons/absent_ancien.svg new file mode 100755 index 000000000..cb82811c4 --- /dev/null +++ b/app/static/icons/absent_ancien.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/app/static/icons/aucun.svg b/app/static/icons/aucun.svg index eaff20043..c23efffc7 100755 --- a/app/static/icons/aucun.svg +++ b/app/static/icons/aucun.svg @@ -1,5 +1,5 @@ - + diff --git a/app/static/icons/present.svg b/app/static/icons/present.svg index e1628c836..4a649b1ca 100755 --- a/app/static/icons/present.svg +++ b/app/static/icons/present.svg @@ -1,7 +1,7 @@ - + - + diff --git a/app/static/icons/retard.svg b/app/static/icons/retard.svg index b8a7f3d25..b41ef3e74 100755 --- a/app/static/icons/retard.svg +++ b/app/static/icons/retard.svg @@ -1,6 +1,6 @@ - - + + diff --git a/app/static/js/assiduites.js b/app/static/js/assiduites.js index fe9ee9d46..caac0c69f 100644 --- a/app/static/js/assiduites.js +++ b/app/static/js/assiduites.js @@ -1696,7 +1696,7 @@ function fastJustify(assiduite) { content, success, () => {}, - "#7059FF" + "var(--color-primary)" ); }; if (assiduite.etudid) { diff --git a/app/static/js/date_utils.js b/app/static/js/date_utils.js index 4a1d21d98..ee9ed1503 100644 --- a/app/static/js/date_utils.js +++ b/app/static/js/date_utils.js @@ -48,6 +48,17 @@ Date.toFRA = function (dateIso) { 7 )}/${dateIso.substring(0, 4)}`; }; +/** + * Vérifie si le début de l'une des périodes est avant la fin de l'autre + * et si la fin de cette période est après le début de l'autre. + * @param {Object} period {deb:Object, fin:Object} + * @param {Object} interval {deb:Object, fin:Object} + * @returns vrai si la periode et l'interval ont une intersection commune + */ +Date.intersect = function (period, interval) { + return period.deb <= interval.fin && period.fin >= interval.deb; +}; + Object.defineProperty(Date.prototype, "isValid", { value: function () { return !Number.isNaN(this.getTime()); diff --git a/app/templates/assiduites/pages/ajout_justificatif.j2 b/app/templates/assiduites/pages/ajout_justificatif.j2 index 0935ed60b..445379ca4 100644 --- a/app/templates/assiduites/pages/ajout_justificatif.j2 +++ b/app/templates/assiduites/pages/ajout_justificatif.j2 @@ -152,7 +152,7 @@ const requests = [] Array.from(in_files.files).forEach((f) => { - pushToast(generateToast(document.createTextNode(`Importation du fichier : ${f.name} commencée`), color = "#f0c865")); + pushToast(generateToast(document.createTextNode(`Importation du fichier : ${f.name} commencée`), color = "var(--color-information)")); const fd = new FormData(); fd.append('file', f); requests.push( diff --git a/app/templates/assiduites/pages/calendrier.j2 b/app/templates/assiduites/pages/calendrier.j2 index 3c6c091d3..c3dcf3e22 100644 --- a/app/templates/assiduites/pages/calendrier.j2 +++ b/app/templates/assiduites/pages/calendrier.j2 @@ -8,7 +8,7 @@
- +
@@ -25,54 +25,98 @@

Calendrier

-

Les jours non travaillés sont affiché en violet

-

Les jours possèdant une bordure "bleu" sont des jours où des absences/retards ont été justifiées par un - justificatif valide

-

Les jours possèdant une bordure "rouge" sont des jours où des absences/retards ont été justifiées par un - justificatif non valide

-

Le jour sera affiché en :

-
    -
  • Rouge : s'il y a une absence enregistrée
  • -
  • Orange : s'il y a un retard et pas d'absence
  • -
  • Vert : s'il y a une présence enregistrée mais pas d'absence ni de retard
  • -
  • Blanc : s'il n'y a rien d'enregistré
  • +

    Code couleur

    +
      +
    • → présence de l'étudiant lors de la période +
    • +
    • → la période n'est pas travaillée +
    • +
    • → absence de l'étudiant lors de la période +
    • +
    • → absence justifiée +
    • +
    • → retard de l'étudiant lors de la période +
    • +
    • → retard justifié +
    • + +
    • → la période est justifiée par un + justificatif valide
    • +
    • → la période est + justifiée par un justificatif non valide / en attente de validation +
    -

    Vous pouvez passer le curseur sur les jours colorés afin de voir les informations de cette journée.

    +

    Vous pouvez passer le curseur sur les jours colorés afin de voir les informations supplémentaires

+
- - - @@ -310,28 +405,6 @@ return assiduitiesByDay; } - function getDayColor(etat) { - let color; - switch (etat.toUpperCase()) { - case "PRESENT": - color = ""; - break; - case "ABSENT": - color = "#F1A69C"; - break; - case "RETARD": - color = "#f0c865"; - break; - case "NONWORK": - color = "#bd81ca" - break; - default: - color = "#FFF"; - break; - } - return color; - } - function generateCalendar(assiduitiesByDay, nonWorkdays = []) { const calendar = document.querySelector('.calendrier') const options = getOptions(); @@ -360,7 +433,7 @@ Object.keys(assiduitiesByDay[month]).forEach((date) => { let dayAssiduities = assiduitiesByDay[month][date].assiduites; let dayJustificatifs = assiduitiesByDay[month][date].justificatifs; - let color = ""; + let color = "sans_etat"; if (dayAssiduities.some((a) => a.etat.toLowerCase() === "absent")) color = "absent"; else if (dayAssiduities.some((a) => a.etat.toLowerCase() === "retard") && options.show_reta) @@ -373,45 +446,49 @@ if (dayJustificatifs.some((j) => j.etat.toLowerCase() === "valide")) { est_just = "est_just"; } else if (dayJustificatifs.some((j) => j.etat.toLowerCase() !== "valide")) { - est_just = "est_just invalide"; + est_just = "invalide"; } const momentDate = new Date(date); let dayOfMonth = momentDate.getDate(); let dayOfWeek = momentDate.getDay(); dayOfWeek = days[dayOfWeek]; - let isWorkDay = nonWorkdays.includes(dayOfWeek.toLowerCase()); + let isNonWorkDay = nonWorkdays.includes(dayOfWeek.toLowerCase()); const day = document.createElement('div'); day.className = `day`; - if (isWorkDay) { + if (isNonWorkDay) { color = "nonwork"; } else if (!options.mode_demi) { day.className = `day ${est_just}`; } - if (options.mode_demi && !isWorkDay) { + + if (options.mode_demi && !isNonWorkDay) { + est_just = [] // affichage n° jour + matin + aprem const span_jour = document.createElement("span") - span_jour.textContent = dayOfMonth + dayOfWeek[0]; + span_jour.textContent = dayOfWeek[0] + dayOfMonth; const span_matin = document.createElement("span"); span_matin.classList.add("color"); const matin = [new Date(date), new Date(date)] - color = "" + color = "sans_etat" matin[0].setHours(0, 0, 0, 0) matin[1].setHours(12, 59, 59) + + const assiduitesMatin = dayAssiduities.filter((el) => { const deb = new Date(el.date_debut); const fin = new Date(el.date_fin); - return deb.isBetween(matin[0], matin[1]) || fin.isBetween(matin[0], matin[1]) + return Date.intersect({ deb: deb, fin: fin }, { deb: matin[0], fin: matin[1] }) }) const justificatifsMatin = dayJustificatifs.filter((el) => { const deb = new Date(el.date_debut); const fin = new Date(el.date_fin); - return deb.isBetween(matin[0], matin[1]) || fin.isBetween(matin[0], matin[1]) + return Date.intersect({ deb: deb, fin: fin }, { deb: matin[0], fin: matin[1] }) }) if (assiduitesMatin.some((a) => a.etat.toLowerCase() === "absent")) color = "absent"; @@ -427,7 +504,7 @@ if (justificatifsMatin.some((j) => j.etat.toLowerCase() === "valide")) { est_just = ["est_just"]; } else if (justificatifsMatin.some((j) => j.etat.toLowerCase() !== "valide")) { - est_just = ["est_just", "invalide"]; + est_just = ["invalide"]; } span_matin.classList.add(...est_just) @@ -437,20 +514,21 @@ const span_aprem = document.createElement("span"); span_aprem.classList.add("color"); const aprem = [new Date(date), new Date(date)] - color = "" + color = "sans_etat" aprem[0].setHours(13, 0, 0, 0) aprem[1].setHours(23, 59, 59) + const assiduitesAprem = dayAssiduities.filter((el) => { const deb = new Date(el.date_debut); const fin = new Date(el.date_fin); - return deb.isBetween(aprem[0], aprem[1]) || fin.isBetween(aprem[0], aprem[1]) + return Date.intersect({ deb: deb, fin: fin }, { deb: aprem[0], fin: aprem[1] }) }) const justificatifsAprem = dayJustificatifs.filter((el) => { const deb = new Date(el.date_debut); const fin = new Date(el.date_fin); - return deb.isBetween(aprem[0], aprem[1]) || fin.isBetween(aprem[0], aprem[1]) + return Date.intersect({ deb: deb, fin: fin }, { deb: aprem[0], fin: aprem[1] }) }) if (assiduitesAprem.some((a) => a.etat.toLowerCase() === "absent")) color = "absent"; @@ -464,34 +542,53 @@ } if (justificatifsAprem.some((j) => j.etat.toLowerCase() === "valide")) { - est_just = ["est_just"];; + est_just = ["est_just"]; } else if (justificatifsAprem.some((j) => j.etat.toLowerCase() !== "valide")) { - est_just = ["est_just", "invalide"];; + est_just = ["invalide"]; } - span_matin.classList.add(...est_just) + span_aprem.classList.add(...est_just) day.appendChild(span_jour) day.appendChild(span_matin) day.appendChild(span_aprem) + } else { day.classList.add("color") if (color != "") { day.classList.add(color); } - day.textContent = `${dayOfWeek} ${dayOfMonth}`; + + if (isNonWorkDay) { + const span_jour = document.createElement("span") + span_jour.textContent = dayOfWeek[0] + dayOfMonth; + day.appendChild(span_jour); + } else { + day.textContent = `${dayOfWeek} ${dayOfMonth}`; + } + + } + console.warn(day.classList, day.classList.length) + if (!nonWorkdays.includes(dayOfWeek.toLowerCase()) && dayAssiduities.length > 0) { const cache = document.createElement('div') cache.classList.add('dayline'); + const title = document.createElement('div') + title.className = "dayline-title"; + + title.innerHTML = "Assiduité du
" + `${formatDate(momentDate)}`; + cache.appendChild(title) cache.appendChild( createMiniTimeline(dayAssiduities, date) ) day.appendChild(cache) } + + daysEl.appendChild(day); }); monthEl.appendChild(daysEl) @@ -586,4 +683,4 @@ function isCalendrier() { return true } -{% endblock pageContent %} +{% endblock pageContent %} \ No newline at end of file diff --git a/app/templates/assiduites/pages/signal_assiduites_etud.j2 b/app/templates/assiduites/pages/signal_assiduites_etud.j2 index f611c3cbe..0fa0a383d 100644 --- a/app/templates/assiduites/pages/signal_assiduites_etud.j2 +++ b/app/templates/assiduites/pages/signal_assiduites_etud.j2 @@ -59,18 +59,9 @@ Correspondance des couleurs :

+

Vous pouvez justifier rapidement une assiduité en saisisant l'assiduité puis en appuyant sur "Justifier"

Explication de la saisie différée

diff --git a/app/templates/assiduites/pages/signal_assiduites_group.j2 b/app/templates/assiduites/pages/signal_assiduites_group.j2 index 9ce818293..6e761c3a1 100644 --- a/app/templates/assiduites/pages/signal_assiduites_group.j2 +++ b/app/templates/assiduites/pages/signal_assiduites_group.j2 @@ -70,17 +70,7 @@ Correspondance des couleurs :

diff --git a/app/templates/assiduites/widgets/alert.j2 b/app/templates/assiduites/widgets/alert.j2 index 4da10c9ea..bf1f0bfec 100644 --- a/app/templates/assiduites/widgets/alert.j2 +++ b/app/templates/assiduites/widgets/alert.j2 @@ -127,7 +127,7 @@