diff --git a/app/models/etudiants.py b/app/models/etudiants.py index 30e42d25b..87ce6163e 100644 --- a/app/models/etudiants.py +++ b/app/models/etudiants.py @@ -405,6 +405,18 @@ class Identite(models.ScoDocModel): modimpls_by_formsemestre[formsemestre.id] = modimpls_sem return modimpls_by_formsemestre + def get_modimpls_from_formsemestre( + self, formsemestre: "FormSemestre" + ) -> list["ModuleImpl"]: + """ + Liste des ModuleImpl auxquels l'étudiant est inscrit dans le formsemestre. + """ + modimpls = ModuleImpl.query.join(ModuleImplInscription).filter( + ModuleImplInscription.etudid == self.id, + ModuleImpl.formsemestre_id == formsemestre.id, + ) + return modimpls.all() + @classmethod def convert_dict_fields(cls, args: dict) -> dict: """Convert fields in the given dict. No other side effect. diff --git a/app/static/css/assiduites.css b/app/static/css/assiduites.css index 8ccd607c4..ff04a8019 100644 --- a/app/static/css/assiduites.css +++ b/app/static/css/assiduites.css @@ -754,4 +754,86 @@ tr.row-justificatif.non_valide td.assi-type { #gtrcontent[data-pdp="true"] .pdp { display: block; +} + +.sco-drop { + border: 1px solid #e1e1e1; + /* Couleur de bordure plus douce */ + border-radius: 8px; + /* Coins plus arrondis */ + background-color: #fafafa; + /* Couleur de fond légère */ + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); + /* Ombre douce pour de la profondeur */ + width: 100%; + /* Adaptation à la largeur de son conteneur */ + max-width: 600px; + /* Largeur maximale pour une meilleure apparence sur grands écrans */ + margin: 10px auto; + /* Centrage avec une marge */ + position: relative; + z-index: 1; +} + +.sco-drop[open] { + z-index: 2; + /* Empilement au-dessus des autres détails */ +} + +.sco-drop summary { + font-weight: 600; + /* Texte plus épais */ + color: #333; + /* Couleur de texte plus foncée pour le contraste */ + padding: 7px 10px; + /* Plus de padding pour une meilleure ergonomie */ + cursor: pointer; + list-style: none; + /* Enlève les puces */ + outline: none; + /* Supprime la bordure de focus par défaut pour un look plus net */ + user-select: none; + /* Empêche la sélection du texte */ + text-align: center; +} + +.sco-drop summary::-webkit-details-marker { + display: none; + /* Cache le triangle par défaut sur Chrome/Safari */ +} + +.sco-drop summary:focus { + outline: none; + /* Plus propre sans contour lors du focus */ +} + +.sco-drop ul { + list-style: none; + /* Enlève les puces */ + margin: 5px 0; + padding: 0; + background-color: #fff; + /* Arrière-plan blanc pour le contenu */ + position: absolute; + border-radius: 8px; + z-index: 1000; + border: 1px solid #e1e1e1; + /* Bordure plus douce */ + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2); + /* Ombre douce pour de la profondeur */ + overflow-y: scroll; + max-height: 150px; + /* Hauteur maximale pour une meilleure apparence sur grands écrans */ +} + +.sco-drop li { + padding: 10px 20px; + /* Espacement intérieur pour les éléments de liste */ + border-top: 1px solid #e1e1e1; + /* Séparateur subtil entre les éléments */ +} + +.sco-drop li:first-child { + border-top: none; + /* Pas de bordure en haut du premier élément */ } \ No newline at end of file diff --git a/app/templates/assiduites/pages/signal_assiduites_hebdo.j2 b/app/templates/assiduites/pages/signal_assiduites_hebdo.j2 index ed5e4983e..36985a8de 100644 --- a/app/templates/assiduites/pages/signal_assiduites_hebdo.j2 +++ b/app/templates/assiduites/pages/signal_assiduites_hebdo.j2 @@ -335,17 +335,36 @@ ); } + function generateConflitDetails(assiduites){ + let html = '
Assiduités en conflit
" + } + function updateTable(assiduites) { - - const img_conflit = ` - 📅` - // Suppression existant document.querySelectorAll("td.btns").forEach((el) => { el.remove(); @@ -454,8 +473,7 @@ tdMatin.setAttribute("data-tooltip", ""); } else { - tdMatin.innerHTML = img_conflit; - tdMatin.querySelector(".conflit_calendar").href = `calendrier_assi_etud?etudid=${etudid}`; + tdMatin.innerHTML = generateConflitDetails(etudAssiMorning); tdMatin.classList.add("conflit"); } } @@ -485,8 +503,7 @@ tdApresmidi.setAttribute("title", text); tdApresmidi.setAttribute("data-tooltip", ""); } else { - tdApresmidi.innerHTML = img_conflit; - tdApresmidi.querySelector(".conflit_calendar").href = `calendrier_assi_etud?etudid=${etudid}`; + tdApresmidi.innerHTML = generateConflitDetails(etudAssiAfternoon); tdApresmidi.classList.add("conflit"); } } @@ -560,7 +577,6 @@ // coche tous les boutons de la colonne function allPresent(day, time) { // Version naive : coche tous les boutons de la colonne - // TODO - Optimiser avec une seule requête API let tds = document.querySelectorAll(`td[day="${day}"][time="${time}"]`); const real_time = time == "am" ? "matin" : "apresmidi"; const assi = { diff --git a/app/templates/assiduites/pages/traitement_justificatifs.j2 b/app/templates/assiduites/pages/traitement_justificatifs.j2 index ea2ae094c..5833a7f2b 100644 --- a/app/templates/assiduites/pages/traitement_justificatifs.j2 +++ b/app/templates/assiduites/pages/traitement_justificatifs.j2 @@ -86,87 +86,7 @@ } - .sco-drop { - border: 1px solid #e1e1e1; - /* Couleur de bordure plus douce */ - border-radius: 8px; - /* Coins plus arrondis */ - background-color: #fafafa; - /* Couleur de fond légère */ - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); - /* Ombre douce pour de la profondeur */ - width: 100%; - /* Adaptation à la largeur de son conteneur */ - max-width: 600px; - /* Largeur maximale pour une meilleure apparence sur grands écrans */ - margin: 10px auto; - /* Centrage avec une marge */ - position: relative; - z-index: 1; - } - - .sco-drop[open] { - z-index: 2; - /* Empilement au-dessus des autres détails */ - } - - .sco-drop summary { - font-weight: 600; - /* Texte plus épais */ - color: #333; - /* Couleur de texte plus foncée pour le contraste */ - padding: 7px 10px; - /* Plus de padding pour une meilleure ergonomie */ - cursor: pointer; - list-style: none; - /* Enlève les puces */ - outline: none; - /* Supprime la bordure de focus par défaut pour un look plus net */ - user-select: none; - /* Empêche la sélection du texte */ - text-align: center; - } - - .sco-drop summary::-webkit-details-marker { - display: none; - /* Cache le triangle par défaut sur Chrome/Safari */ - } - - .sco-drop summary:focus { - outline: none; - /* Plus propre sans contour lors du focus */ - } - - .sco-drop ul { - list-style: none; - /* Enlève les puces */ - margin: 5px 0; - padding: 0; - background-color: #fff; - /* Arrière-plan blanc pour le contenu */ - position: absolute; - border-radius: 8px; - z-index: 1000; - border: 1px solid #e1e1e1; - /* Bordure plus douce */ - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2); - /* Ombre douce pour de la profondeur */ - overflow-y: scroll; - max-height: 150px; - /* Hauteur maximale pour une meilleure apparence sur grands écrans */ - } - - .sco-drop li { - padding: 10px 20px; - /* Espacement intérieur pour les éléments de liste */ - border-top: 1px solid #e1e1e1; - /* Séparateur subtil entre les éléments */ - } - - .sco-drop li:first-child { - border-top: none; - /* Pas de bordure en haut du premier élément */ - } + {% endblock styles %} diff --git a/app/views/assiduites.py b/app/views/assiduites.py index 21f39f8c3..f053a5f5b 100644 --- a/app/views/assiduites.py +++ b/app/views/assiduites.py @@ -2168,17 +2168,19 @@ def edit_assiduite_etud(assiduite_id: int): form.disable_all() # peuplement moduleimpl_select - modimpls_by_formsemestre = etud.get_modimpls_by_formsemestre(scu.annee_scolaire()) choices: OrderedDict = OrderedDict() choices[""] = [("", "Non spécifié"), ("autre", "Autre module (pas dans la liste)")] - # indique le nom du semestre dans le menu (optgroup) - group_name: str = formsemestre.titre_annee() - choices[group_name] = [ - (m.id, f"{m.module.code} {m.module.abbrev or m.module.titre or ''}") - for m in modimpls_by_formsemestre[formsemestre.id] - if m.module.ue.type == UE_STANDARD - ] + # Récupération des modulesimpl du semestre si existant. + if formsemestre: + # indique le nom du semestre dans le menu (optgroup) + modimpls_from_formsemestre = etud.get_modimpls_from_formsemestre(formsemestre) + group_name: str = formsemestre.titre_annee() + choices[group_name] = [ + (m.id, f"{m.module.code} {m.module.abbrev or m.module.titre or ''}") + for m in modimpls_from_formsemestre + if m.module.ue.type == UE_STANDARD + ] choices.move_to_end("", last=False) form.modimpl.choices = choices