diff --git a/app/scodoc/html_sidebar.py b/app/scodoc/html_sidebar.py index 153e8f6f4d..820bf8987f 100755 --- a/app/scodoc/html_sidebar.py +++ b/app/scodoc/html_sidebar.py @@ -54,9 +54,12 @@ def sidebar_common():

Scolarité

Semestres
Programmes
- Assiduités
""" ] + if current_user.has_permission(Permission.ScoAbsChange): + H.append( + f""" Assiduités
""" + ) if current_user.has_permission( Permission.ScoUsersAdmin ) or current_user.has_permission(Permission.ScoUsersView): diff --git a/app/static/css/assiduites.css b/app/static/css/assiduites.css index 72b6518885..f3d1c9d75d 100644 --- a/app/static/css/assiduites.css +++ b/app/static/css/assiduites.css @@ -97,7 +97,7 @@ .etud_row { display: grid; - grid-template-columns: auto auto 1fr auto; + grid-template-columns: 2% 20% 55% auto; gap: 16px; background-color: white; border-radius: 15px; @@ -118,6 +118,11 @@ } +.etud_row.def, +.etud_row.dem { + background-color: #c8c8c8; +} + /* --- Index --- */ .etud_row .index_field { grid-column: 1; @@ -127,6 +132,7 @@ .etud_row .name_field { grid-column: 2; height: 100%; + justify-content: start; } .etud_row .name_field .name_set { @@ -135,6 +141,22 @@ margin: 0 5%; } +.etud_row.def .nom::after, +.tr.def .td.sticky span::after { + display: block; + content: " (Déf.)"; + color: #d61616; + margin-left: 2px; +} + +.etud_row.dem .nom::after, +.tr.dem .td.sticky span::after { + display: block; + content: " (Dém.)"; + color: #d61616; + margin-left: 2px; +} + .etud_row .name_field .name_set * { padding: 0; margin: 0; @@ -190,24 +212,29 @@ background-color: #ff0000c2; } -.etud_row .assiduites_bar .absent { +.etud_row .assiduites_bar .absent, +.demo.absent { background-color: #F1A69C !important; } -.etud_row .assiduites_bar .present { +.etud_row .assiduites_bar .present, +.demo.present { background-color: #9CF1AF !important; } -.etud_row .assiduites_bar .retard { +.etud_row .assiduites_bar .retard, +.demo.retard { background-color: #F1D99C !important; } -.etud_row .assiduites_bar .justified { +.etud_row .assiduites_bar .justified, +.demo.justified { background-image: repeating-linear-gradient(135deg, transparent, transparent 4px, #7059FF 4px, #7059FF 8px); } -.etud_row .assiduites_bar .invalid_justified { - background-image: repeating-linear-gradient(135deg, transparent, transparent 4px, #d61616 4px, #d61616 8px); +.etud_row .assiduites_bar .invalid_justified, +.demo.invalid_justified { + background-image: repeating-linear-gradient(225deg, transparent, transparent 4px, #d61616 4px, #d61616 8px); } @@ -549,4 +576,11 @@ max-width: fit-content; padding: 5px; color: white; +} + +.demo { + width: 23px; + height: 13px; + display: inline-block; + border: solid 1px #333; } \ No newline at end of file diff --git a/app/static/js/assiduites.js b/app/static/js/assiduites.js index 2b7fa53956..c5b7ac9b8f 100644 --- a/app/static/js/assiduites.js +++ b/app/static/js/assiduites.js @@ -297,6 +297,7 @@ function executeMassActionQueue() { (data, status) => { //error console.error(data, status); + errorAlert(); } ); return createQueue.length; @@ -320,6 +321,7 @@ function executeMassActionQueue() { (data, status) => { //error console.error(data, status); + errorAlert(); } ); return editQueue.length; @@ -337,6 +339,7 @@ function executeMassActionQueue() { (data, status) => { //error console.error(data, status); + errorAlert(); } ); return toDelete.length; @@ -859,6 +862,7 @@ function createAssiduite(etat, etudid) { (data, status) => { //error console.error(data, status); + errorAlert(); } ); } @@ -882,6 +886,7 @@ function deleteAssiduite(assiduite_id) { (data, status) => { //error console.error(data, status); + errorAlert(); } ); } @@ -911,6 +916,7 @@ function editAssiduite(assiduite_id, etat) { (data, status) => { //error console.error(data, status); + errorAlert(); } ); @@ -1159,14 +1165,25 @@ function generateEtudRow( let assi = ""; ["present", "retard", "absent"].forEach((abs) => { if (abs.toLowerCase() === assiduite.etatAssiduite.toLowerCase()) { - assi += ``; + assi += ``; } else { - assi += ``; + assi += ``; } }); const conflit = assiduite.type == "conflit" ? "conflit" : ""; const pdp_url = `${getUrl()}/api/etudiant/etudid/${etud.id}/photo?size=small`; - const HTML = `
+ + let defdem = ""; + + try { + if (etud.id in etudsDefDem) { + defdem = etudsDefDem[etud.id] == "D" ? "dem" : "def"; + } + } catch (_) {} + + const HTML = `
${index}
@@ -1539,6 +1556,7 @@ function justifyAssiduite(assiduite_id, justified) { (data, status) => { //error console.error(data, status); + errorAlert(); } ); @@ -1550,6 +1568,7 @@ function createJustificatif(justif, success = () => {}) { sync_post(path, [justif], success, (data, status) => { //error console.error(data, status); + errorAlert(); }); } @@ -1581,6 +1600,20 @@ function deleteJustificatif(justif_id) { (data, status) => { //error console.error(data, status); + errorAlert(); } ); } + +function errorAlert() { + const html = ` +

Avez vous les droits suffisant pour cette action ?

+

Si c'est bien le cas : veuillez de l'aide sur le canal Assistance de ScoDoc

+
+

pour les développeurs : l'erreur est affichée dans la console JS

+ + `; + const div = document.createElement("div"); + div.innerHTML = html; + openAlertModal("Une erreur s'est déclanchée", div); +} diff --git a/app/templates/assiduites/pages/ajout_justificatif.j2 b/app/templates/assiduites/pages/ajout_justificatif.j2 index 54530f67a1..0d2891c1b2 100644 --- a/app/templates/assiduites/pages/ajout_justificatif.j2 +++ b/app/templates/assiduites/pages/ajout_justificatif.j2 @@ -189,6 +189,7 @@ createJustificatif(justificatif, (data) => { if (Object.keys(data.errors).length > 0) { console.error(data.errors); + errorAlert(); } if (Object.keys(data.success).length > 0) { couverture = data.success[0].couverture diff --git a/app/templates/assiduites/pages/bilan_dept.j2 b/app/templates/assiduites/pages/bilan_dept.j2 index 688427bb51..aea0bb8b06 100644 --- a/app/templates/assiduites/pages/bilan_dept.j2 +++ b/app/templates/assiduites/pages/bilan_dept.j2 @@ -44,6 +44,7 @@ }, (data, status) => { console.error(data, status) + errorAlert(); } ) } diff --git a/app/templates/assiduites/pages/bilan_etud.j2 b/app/templates/assiduites/pages/bilan_etud.j2 index 5fc2a29d90..825844c906 100644 --- a/app/templates/assiduites/pages/bilan_etud.j2 +++ b/app/templates/assiduites/pages/bilan_etud.j2 @@ -227,6 +227,7 @@ (data, status) => { //error console.error(data, status); + errorAlert(); } ); } @@ -245,6 +246,7 @@ (data, status) => { //error console.error(data, status); + errorAlert(); } ); } diff --git a/app/templates/assiduites/pages/signal_assiduites_diff.j2 b/app/templates/assiduites/pages/signal_assiduites_diff.j2 index 8ede0b2e56..ea11796e62 100644 --- a/app/templates/assiduites/pages/signal_assiduites_diff.j2 +++ b/app/templates/assiduites/pages/signal_assiduites_diff.j2 @@ -17,6 +17,21 @@ {{diff | safe}} + + {% include "assiduites/widgets/alert.j2" %} diff --git a/app/templates/assiduites/pages/signal_assiduites_etud.j2 b/app/templates/assiduites/pages/signal_assiduites_etud.j2 index 7811f2c1b5..44a37f2471 100644 --- a/app/templates/assiduites/pages/signal_assiduites_etud.j2 +++ b/app/templates/assiduites/pages/signal_assiduites_etud.j2 @@ -47,11 +47,16 @@ Correspondance des couleurs :

    -
  • Vert -> présence de l'étudiant lors de la période
  • -
  • Orange -> retard de l'étudiant lors de la période
  • -
  • Rouge -> absence de l'étudiant lors de la période
  • -
  • Hachure Bleu -> l'assiduité est justifiée par un justificatif valide
  • -
  • Hachure Rouge -> l'assiduité est justifiée par un justificatif non valide / en attente de validation +
  • → présence de l'étudiant lors de la période +
  • +
  • → retard de l'étudiant lors de la période +
  • +
  • → absence de l'étudiant lors de la période +
  • +
  • → l'assiduité est justifiée par un + justificatif valide
  • +
  • → l'assiduité est + justifiée par un justificatif non valide / en attente de validation

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

diff --git a/app/templates/assiduites/pages/signal_assiduites_group.j2 b/app/templates/assiduites/pages/signal_assiduites_group.j2 index 16d8c00595..d668646ea4 100644 --- a/app/templates/assiduites/pages/signal_assiduites_group.j2 +++ b/app/templates/assiduites/pages/signal_assiduites_group.j2 @@ -49,11 +49,16 @@ Correspondance des couleurs :

    -
  • Vert -> présence de l'étudiant lors de la période
  • -
  • Orange -> retard de l'étudiant lors de la période
  • -
  • Rouge -> absence de l'étudiant lors de la période
  • -
  • Hachure Bleu -> l'assiduité est justifiée par un justificatif valide
  • -
  • Hachure Rouge -> l'assiduité est justifiée par un justificatif non valide / en attente de validation +
  • → présence de l'étudiant lors de la période +
  • +
  • → retard de l'étudiant lors de la période +
  • +
  • → absence de l'étudiant lors de la période +
  • +
  • → l'assiduité est justifiée par un + justificatif valide
  • +
  • → l'assiduité est + justifiée par un justificatif non valide / en attente de validation
@@ -77,6 +82,8 @@ window.forceModule = "{{ forcer_module }}" window.forceModule = window.forceModule == "True" ? true : false + const etudsDefDem = {{ defdem | safe }} + if (window.forceModule) { const btn = document.getElementById("validate_selectors"); diff --git a/app/templates/assiduites/widgets/conflict.j2 b/app/templates/assiduites/widgets/conflict.j2 index 1aefa66851..5642a433d8 100644 --- a/app/templates/assiduites/widgets/conflict.j2 +++ b/app/templates/assiduites/widgets/conflict.j2 @@ -295,6 +295,7 @@ (data, status) => { //error console.error(data, status); + errorAlert(); } ); @@ -378,7 +379,7 @@ //Placement de la période conflictuelle sur la timeline const specialAssiduiteEl = document.querySelector(".assiduite-special"); - console.error("special") + specialAssiduiteEl.style.width = getWidth( this.conflictPeriod.deb, this.conflictPeriod.fin @@ -387,8 +388,8 @@ specialAssiduiteEl.style.top = "0"; specialAssiduiteEl.style.zIndex = "0"; // Place l'assiduité spéciale en arrière-plan assiduitesContainer.appendChild(specialAssiduiteEl); - console.error(this.conflictPeriod) - console.error(specialAssiduiteEl) + + //Placement des assiduités sur la timeline this.list.forEach((assiduite) => { @@ -402,7 +403,7 @@ const el = document.createElement("div"); el.className = "assiduite"; el.style.backgroundColor = getColor(assiduite.etat); - console.error("normal") + el.style.width = getWidth(assiduite.date_debut, assiduite.date_fin); el.style.left = getLeftPosition(assiduite.date_debut); diff --git a/app/templates/assiduites/widgets/differee.j2 b/app/templates/assiduites/widgets/differee.j2 index 92b0bc190c..fcb2c5ffaf 100644 --- a/app/templates/assiduites/widgets/differee.j2 +++ b/app/templates/assiduites/widgets/differee.j2 @@ -774,6 +774,7 @@ (data, status) => { //error console.error(data, status); + errorAlert(); } ); } @@ -787,6 +788,7 @@ (data, status) => { //error console.error(data, status); + errorAlert(); } ); } @@ -800,6 +802,7 @@ (data, status) => { //error console.error(data, status); + errorAlert(); } ); } @@ -813,6 +816,7 @@ (data, status) => { //error console.error(data, status); + errorAlert(); } ); } @@ -825,6 +829,7 @@ callback, (data, status) => { console.error(data, status); + errorAlert(); } ); } @@ -838,6 +843,7 @@ (data, status) => { //error console.error(data, status); + errorAlert(); } ); } diff --git a/app/templates/assiduites/widgets/tableau_assi.j2 b/app/templates/assiduites/widgets/tableau_assi.j2 index 5af5548f33..caf4fda30a 100644 --- a/app/templates/assiduites/widgets/tableau_assi.j2 +++ b/app/templates/assiduites/widgets/tableau_assi.j2 @@ -276,6 +276,7 @@ (data, status) => { //error console.error(data, status); + errorAlert(); } ); } diff --git a/app/templates/assiduites/widgets/tableau_justi.j2 b/app/templates/assiduites/widgets/tableau_justi.j2 index 0ff68b2930..301fcc654e 100644 --- a/app/templates/assiduites/widgets/tableau_justi.j2 +++ b/app/templates/assiduites/widgets/tableau_justi.j2 @@ -401,6 +401,7 @@ (data, status) => { //error console.error(data, status); + errorAlert(); } ); } diff --git a/app/templates/sidebar.j2 b/app/templates/sidebar.j2 index 8b8d559f4c..5fe279d930 100755 --- a/app/templates/sidebar.j2 +++ b/app/templates/sidebar.j2 @@ -24,8 +24,10 @@

Scolarité

Semestres
Programmes
- Assiduités
+ {% if current_user.has_permission(sco.Permission.ScoAbsChange)%} + Assiduités
+ {% endif %} {% if current_user.has_permission(sco.Permission.ScoUsersAdmin) or current_user.has_permission(sco.Permission.ScoUsersView) %} diff --git a/app/views/assiduites.py b/app/views/assiduites.py index 19f1b636c1..628b49b8f4 100644 --- a/app/views/assiduites.py +++ b/app/views/assiduites.py @@ -10,7 +10,14 @@ from app.decorators import ( scodoc, permission_required, ) -from app.models import FormSemestre, Identite, ScoDocSiteConfig, Assiduite, Departement +from app.models import ( + FormSemestre, + Identite, + ScoDocSiteConfig, + Assiduite, + Departement, + FormSemestreInscription, +) from app.views import assiduites_bp as bp from app.views import ScoData @@ -563,6 +570,7 @@ def signal_assiduites_group(): formsemestre_id=formsemestre_id, dept_id=g.scodoc_dept_id, ), + defdem=_get_etuds_dem_def(formsemestre), ), html_sco_header.sco_footer(), ).build() @@ -793,6 +801,7 @@ def signal_assiduites_diff(): ), gr=gr_tit, sem=sem["titre_num"], + defdem=_get_etuds_dem_def(formsemestre), ), html_sco_header.sco_footer(), ).build() @@ -907,3 +916,24 @@ def get_time(label: str, default: str): def _get_seuil(): return sco_preferences.get_preference("assi_seuil", dept_id=g.scodoc_dept_id) + + +def _get_etuds_dem_def(formsemestre): + etuds_dem_def = [ + (f.etudid, f.etat) + for f in FormSemestreInscription.query.filter( + FormSemestreInscription.formsemestre_id == formsemestre.id, + FormSemestreInscription.etat != "I", + ).all() + ] + + template: str = '"£" : "$",' + + json_str: str = "{" + + for etud in etuds_dem_def: + json_str += template.replace("£", str(etud[0])).replace("$", etud[1]) + + json_str = json_str[:-1] + "}" + + return json_str