diff --git a/app/but/cursus_but.py b/app/but/cursus_but.py index f3c19925e..fc1ee3cfd 100644 --- a/app/but/cursus_but.py +++ b/app/but/cursus_but.py @@ -632,17 +632,23 @@ def formation_semestre_niveaux_warning(formation: Formation, semestre_idx: int) def ue_associee_au_niveau_du_parcours( ues_possibles: list[UniteEns], niveau: ApcNiveau, sem_name: str = "S" -) -> UniteEns: - "L'UE associée à ce niveau, ou None" +) -> tuple[UniteEns, str]: + """L'UE associée à ce niveau, ou None. + Renvoie aussi un message d'avertissement en cas d'associations multiples + (en principe un niveau ne doit être associé qu'à une seule UE) + """ ues = [ue for ue in ues_possibles if ue.niveau_competence_id == niveau.id] + msg = "" if len(ues) > 1: + msg = f"""{' et '.join(ue.acronyme for ue in ues)} + associées au niveau {niveau} / {sem_name}. Utilisez le cas échéant l'item "Désassocier".""" # plusieurs UEs associées à ce niveau: élimine celles sans parcours - ues_pair_avec_parcours = [ue for ue in ues if ue.parcours] - if ues_pair_avec_parcours: - ues = ues_pair_avec_parcours + ues_avec_parcours = [ue for ue in ues if ue.parcours] + if ues_avec_parcours: + ues = ues_avec_parcours if len(ues) > 1: log(f"_niveau_ues: {len(ues)} associées au niveau {niveau} / {sem_name}") - return ues[0] if ues else None + return ues[0] if ues else None, msg def parcour_formation_competences( @@ -700,6 +706,7 @@ def parcour_formation_competences( "ue_impair": None, "ues_pair": [], "ues_impair": [], + "warning": "", } # Toutes les UEs de la formation dans ce parcours ou tronc commun ues = [ @@ -715,10 +722,10 @@ def parcour_formation_competences( ues_impair_possibles = [ue for ue in ues if ue.semestre_idx == (2 * annee - 1)] # UE associée au niveau dans ce parcours - ue_pair = ue_associee_au_niveau_du_parcours( + ue_pair, warning_pair = ue_associee_au_niveau_du_parcours( ues_pair_possibles, niveau, f"S{2*annee}" ) - ue_impair = ue_associee_au_niveau_du_parcours( + ue_impair, warning_impair = ue_associee_au_niveau_du_parcours( ues_impair_possibles, niveau, f"S{2*annee-1}" ) @@ -736,6 +743,7 @@ def parcour_formation_competences( for ue in ues_impair_possibles if (not ue.niveau_competence) or ue.niveau_competence.id == niveau.id ], + "warning": ", ".join(filter(None, [warning_pair, warning_impair])), } competences = [ diff --git a/app/but/jury_but_pv.py b/app/but/jury_but_pv.py index c0b07ba24..cdb46acd7 100644 --- a/app/but/jury_but_pv.py +++ b/app/but/jury_but_pv.py @@ -105,7 +105,7 @@ def pvjury_page_but(formsemestre_id: int, fmt="html"): }, xls_style_base=xls_style_base, ) - return tab.make_page(fmt=fmt, javascripts=["js/etud_info.js"], init_qtip=True) + return tab.make_page(fmt=fmt) def pvjury_table_but( diff --git a/app/forms/main/config_logos.py b/app/forms/main/config_logos.py index fcea427cc..31f8bc6ff 100644 --- a/app/forms/main/config_logos.py +++ b/app/forms/main/config_logos.py @@ -46,10 +46,8 @@ from app.scodoc.sco_config_actions import LogoInsert from app.scodoc.sco_exceptions import ScoValueError from app.scodoc.sco_logos import find_logo - -JAVASCRIPTS = html_sco_header.BOOTSTRAP_MULTISELECT_JS + [] - -CSSSTYLES = html_sco_header.BOOTSTRAP_MULTISELECT_CSS +CSSSTYLES = html_sco_header.BOOTSTRAP_CSS +JAVASCRIPTS = html_sco_header.BOOTSTRAP_JS # class ItemForm(FlaskForm): # """Unused Generic class to document common behavior for classes diff --git a/app/forms/multiselect.py b/app/forms/multiselect.py new file mode 100644 index 000000000..77b13626b --- /dev/null +++ b/app/forms/multiselect.py @@ -0,0 +1,118 @@ +""" +Simplification des multiselect HTML/JS +""" + + +class MultiSelect: + """ + Classe pour faciliter l'utilisation du multi-select HTML/JS + + Les values sont représentées en dict { + value: "...", + label:"...", + selected: True/False (default to False), + single: True/False (default to False) + } + + Args: + values (dict[str, list[dict]]): Dictionnaire des valeurs + génère des pour chaque clef du dictionnaire + génère des