diff --git a/app/models/formsemestre.py b/app/models/formsemestre.py index 98ecc093..338b9223 100644 --- a/app/models/formsemestre.py +++ b/app/models/formsemestre.py @@ -208,7 +208,7 @@ class FormSemestre(models.ScoDocModel): return cls.query.filter_by(id=formsemestre_id).first_or_404() def sort_key(self) -> tuple: - """clé pour tris par ordre alphabétique + """clé pour tris par ordre de date_debut, le plus ancien en tête (pour avoir le plus récent d'abord, sort avec reverse=True)""" return (self.date_debut, self.semestre_id) diff --git a/app/scodoc/sco_dept.py b/app/scodoc/sco_dept.py index 1f980c14..fda86ac4 100644 --- a/app/scodoc/sco_dept.py +++ b/app/scodoc/sco_dept.py @@ -79,21 +79,30 @@ def index_html(showcodes=0, showsemtable=0, export_table_formsemestres=False): else: html_table_formsemestres = None + current_formsemestres_by_modalite, modalites = ( + sco_modalites.group_formsemestres_by_modalite(current_formsemestres) + ) + return render_template( "scolar/index.j2", current_user=current_user, + current_formsemestres=current_formsemestres, + current_formsemestres_by_modalite=current_formsemestres_by_modalite, dept_name=sco_preferences.get_preference("DeptName"), - formsemestres=formsemestres, - html_current_formsemestres=_show_current_formsemestres( - current_formsemestres, showcodes + emptygroupicon=scu.icontag( + "emptygroupicon_img", title="Pas d'inscrits", border="0" ), + formsemestres=formsemestres, + groupicon=scu.icontag("groupicon_img", title="Inscrits", border="0"), html_table_formsemestres=html_table_formsemestres, locked_formsemestres=locked_formsemestres, + modalites=modalites, nb_locked=locked_formsemestres.count(), nb_user_accounts=sco_users.get_users_count(dept=g.scodoc_dept), page_title=f"ScoDoc {g.scodoc_dept}", Permission=Permission, scolar_news_summary=ScolarNews.scolar_news_summary_html(), + showcodes=showcodes, showsemtable=showsemtable, sco=ScoData(), ) @@ -116,6 +125,7 @@ def _convert_formsemestres_to_dicts( lockicon = "X" # génère liste de dict sems = [] + formsemestre: FormSemestre for formsemestre in formsemestres: nb_inscrits = len(formsemestre.inscriptions) formation = formsemestre.formation @@ -151,61 +161,6 @@ def _convert_formsemestres_to_dicts( return sems -def _show_current_formsemestres(formsemestres: Query, showcodes: bool) -> str: - """html div avec les formsemestres courants de la page d'accueil""" - - H = [] - if formsemestres.count(): - H.append("""
Sessions en cours
""") - H.append(_sem_table(_convert_formsemestres_to_dicts(formsemestres, showcodes))) - else: - # aucun semestre courant: affiche aide - H.append( - """ -
Aucune session en cours !
-

Pour ajouter une session, aller dans Formations, - choisissez une formation, puis suivez le lien "UE, modules, semestres". -

-

Là, en bas de page, suivez le lien - "Mettre en place un nouveau semestre de formation..." -

""" - ) - return "\n".join(H) - - -def _sem_table(sems: list[dict]) -> str: - """Affiche liste des semestres, utilisée pour semestres en cours""" - tmpl = f"""%(tmpcode)s - %(lockimg)s %(groupicon)s - %(mois_debut)s - %(mois_fin)s - %(titre_num)s - (%(responsable_name)s) - - - """ - - # Liste des semestres, groupés par modalités - sems_by_mod, modalites = sco_modalites.group_sems_by_modalite(sems) - - H = [''] - for modalite in modalites: - if len(modalites) > 1: - H.append('' % modalite["titre"]) - - if sems_by_mod[modalite["modalite"]]: - cur_idx = sems_by_mod[modalite["modalite"]][0]["semestre_id"] - for sem in sems_by_mod[modalite["modalite"]]: - if cur_idx != sem["semestre_id"]: - sem["trclass"] = "firstsem" # separe les groupes de semestres - cur_idx = sem["semestre_id"] - else: - sem["trclass"] = "" - H.append(tmpl % sem) - H.append("
%s
") - return "\n".join(H) - - def _sem_table_gt(formsemestres: Query, showcodes=False, fmt="html") -> GenTable: """Table des semestres Utilise une datatables. diff --git a/app/scodoc/sco_modalites.py b/app/scodoc/sco_modalites.py index 621373f7..075fa447 100644 --- a/app/scodoc/sco_modalites.py +++ b/app/scodoc/sco_modalites.py @@ -36,37 +36,45 @@ Elle n'est pas utilisée pour les parcours, ni pour rien d'autre import collections import app.scodoc.notesdb as ndb from app import log +from app.models import FormSemestre -def list_formsemestres_modalites(sems): +def list_formsemestres_modalites(formsemestres: list[FormSemestre]) -> list[dict]: """Liste ordonnée des modalités présentes dans ces formsemestres""" modalites = {} - for sem in sems: - if sem["modalite"] not in modalites: - m = do_modalite_list(args={"modalite": sem["modalite"]})[0] + for formsemestre in formsemestres: + if formsemestre.modalite not in modalites: + m = do_modalite_list(args={"modalite": formsemestre.modalite})[0] modalites[m["modalite"]] = m modalites = list(modalites.values()) modalites.sort(key=lambda x: x["numero"]) return modalites -def group_sems_by_modalite(sems: list[dict]): +def group_formsemestres_by_modalite( + formsemestres: list[FormSemestre], +) -> dict[str, list[FormSemestre]]: """Given the list of formsemestre, group them by modalite, sorted in each one by semestre id and date """ sems_by_mod = collections.defaultdict(list) - modalites = list_formsemestres_modalites(sems) - for modalite in modalites: - for sem in sems: - if sem["semestre_id"] < 0: # formations en un semestre - sem["sortkey"] = (-100 * sem["semestre_id"], sem["dateord"]) - else: - sem["sortkey"] = (sem["semestre_id"], sem["dateord"]) - if sem["modalite"] == modalite["modalite"]: - sems_by_mod[modalite["modalite"]].append(sem) + modalites = list_formsemestres_modalites(formsemestres) + sems_by_mod = { + modalite["modalite"]: [ + formsemestre + for formsemestre in formsemestres + if formsemestre.modalite == modalite["modalite"] + ] + for modalite in modalites + } # tri dans chaque modalité par indice de semestre et date debut for modalite in modalites: - sems_by_mod[modalite["modalite"]].sort(key=lambda x: x["sortkey"]) + sems_by_mod[modalite["modalite"]].sort( + key=lambda x: ( + x.semestre_id if x.semestre_id > 0 else -1000 * x.semestre_id, + x.date_debut, + ) + ) return sems_by_mod, modalites diff --git a/app/templates/scolar/index.j2 b/app/templates/scolar/index.j2 index 8b93dee0..0e151691 100644 --- a/app/templates/scolar/index.j2 +++ b/app/templates/scolar/index.j2 @@ -83,6 +83,70 @@ table.semlist tbody tr td.modalite { padding-right: 1em; } +div.modalite { + font-size: 16px; + font-weight: bold; +} +span.effectif { + display: inline-block; + min-width: 24px; + text-align: right; +} + +.cur-formsemestres { + width: max-content; /* Fits content, but respects max-width */ + max-width: 1024px; /* Maximum width */ + margin: 0 auto 0 0; /* Centers divs if they are narrower than 1024px */ +} +.cur-formsemestre { + display: flex; + align-items: center; + justify-content: space-between; + border-bottom: 1px solid #ddd; + border-left: 1px solid #ddd; + border-right: 1px solid #ddd;; + background-color: rgb(246, 255, 254); + padding: 0px 8px 0px 8px; + margin: 0px; +} + +.cur-formsemestre.new-sem { + margin-top: 8px; + border-top: 1px solid #ddd;; +} + +.left-section { + display: flex; + align-items: center; +} + +.date { + display: flex; + flex-direction: column; + margin-left: 10px; + font-size: 12px; +} + +.cur-formsemestre .title { + flex-grow: 1; + text-align: left; + margin: 0 20px; + display: flex; + align-items: center; + font-size: 16px; +} + +.right-section { + display: flex; + flex-direction: column; + font-size: 14px; +} +.responsable { + font-weight: bold; + color: navy; +} + + {# News #} @@ -103,7 +167,43 @@ table.semlist tbody tr td.modalite { {# Les semestres courants (cad non verrouillés) #}
- {{html_current_formsemestres|safe}} +{% if current_formsemestres.count() == 0 %} +
Aucune session en cours !
+

Pour ajouter une session, aller dans Formations, + choisissez une formation, puis suivez le lien "UE, modules, semestres". +

+

Là, en bas de page, suivez le lien + "Mettre en place un nouveau semestre de formation..." +

+{% else %} +
Sessions en cours
+
+ {% for modalite in modalites %} + {% if modalites|length > 1 %} +
{{modalite.titre}}
+ {% endif %} + {% for formsemestre in current_formsemestres_by_modalite[modalite.modalite] %} +
+
+ {{groupicon|safe if formsemestre.inscriptions|length else emptygroupicon|safe}} +
+ +
{{formsemestre.mois_fin()}}
+
+
+ +
+
{{formsemestre.responsables_str()}}
+
{{formsemestre.inscriptions|length}} étuds
+
+
+ {% endfor %} + {% endfor %} +
+{% endif %}
{# Table de tous les semestres #} diff --git a/sco_version.py b/sco_version.py index 144fe706..e0361b07 100644 --- a/sco_version.py +++ b/sco_version.py @@ -1,7 +1,7 @@ # -*- mode: python -*- # -*- coding: utf-8 -*- -SCOVERSION = "9.6.954" +SCOVERSION = "9.6.955" SCONAME = "ScoDoc"