From ef63e27aedc6610aabe993a3adb6c0d4b13dcee2 Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Sun, 21 Jan 2024 22:21:10 +0100 Subject: [PATCH] =?UTF-8?q?Page=20assiduit=C3=A9:=20utilisation=20de=20tem?= =?UTF-8?q?plates=20partout.=20Fix=20#816?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/static/css/minitimeline.css | 4 +- app/static/js/scodoc.js | 2 +- app/templates/assiduites/pages/bilan_etud.j2 | 135 ++++--- .../assiduites/pages/liste_assiduites.j2 | 18 + .../pages/signal_assiduites_diff.j2 | 39 ++- .../pages/signal_assiduites_group.j2 | 135 ++++--- app/templates/assiduites/widgets/differee.j2 | 6 +- app/templates/babase.j2 | 6 +- app/templates/base.j2 | 3 +- app/templates/sco_page.j2 | 2 +- app/views/assiduites.py | 331 +++++------------- 11 files changed, 311 insertions(+), 370 deletions(-) diff --git a/app/static/css/minitimeline.css b/app/static/css/minitimeline.css index 04c713c4..bc41337b 100644 --- a/app/static/css/minitimeline.css +++ b/app/static/css/minitimeline.css @@ -174,7 +174,7 @@ text-align: start; top: -40px; transform: translateX(-50%); - z-index: 2; + z-index: 1; } @@ -183,7 +183,7 @@ content: "|"; position: absolute; bottom: -2px; - z-index: 2; + z-index: 1; } .mini-timeline-block.creneau { diff --git a/app/static/js/scodoc.js b/app/static/js/scodoc.js index 0cb83e4c..bb3aafbf 100644 --- a/app/static/js/scodoc.js +++ b/app/static/js/scodoc.js @@ -39,7 +39,7 @@ $(function () { "Avril", "May", "Juin", - "Juilet", + "Juillet", "Août", "Septembre", "Octobre", diff --git a/app/templates/assiduites/pages/bilan_etud.j2 b/app/templates/assiduites/pages/bilan_etud.j2 index 6f9a320f..15fed8aa 100644 --- a/app/templates/assiduites/pages/bilan_etud.j2 +++ b/app/templates/assiduites/pages/bilan_etud.j2 @@ -1,3 +1,70 @@ +{% extends "sco_page.j2" %} + +{% block title %} +Bilan assiduité de {{sco.etud.nomprenom}} +{% endblock title %} + +{% block styles %} + {{ super() }} + + +{% endblock styles %} + {% block app_content %} {% include "assiduites/widgets/tableau_base.j2" %}
@@ -12,9 +79,9 @@

Statistiques d'assiduité

- -
@@ -45,8 +112,13 @@
{% endblock app_content %} - + + + - diff --git a/app/templates/assiduites/pages/liste_assiduites.j2 b/app/templates/assiduites/pages/liste_assiduites.j2 index df630c79..b98a73c3 100644 --- a/app/templates/assiduites/pages/liste_assiduites.j2 +++ b/app/templates/assiduites/pages/liste_assiduites.j2 @@ -1,3 +1,21 @@ +{% extends "sco_page.j2" %} + +{% block title %} +Assiduité de {{etud.nomprenom}} +{% endblock title %} + +{% block styles %} + {{ super() }} + +{% endblock styles %} + +{% block scripts %} + {{ super() }} + + +{% endblock %} + + {% block app_content %}
diff --git a/app/templates/assiduites/pages/signal_assiduites_diff.j2 b/app/templates/assiduites/pages/signal_assiduites_diff.j2 index d6066a4b..b61b538b 100644 --- a/app/templates/assiduites/pages/signal_assiduites_diff.j2 +++ b/app/templates/assiduites/pages/signal_assiduites_diff.j2 @@ -3,6 +3,26 @@ - TODO : revoir le fonctionnement de cette page (trop lente / complexe) - Utiliser majoritairement du python #} + +{% extends "sco_page.j2" %} + +{% block styles %} + {{ super() }} + +{% endblock styles %} + +{% block title %} + {{title}} +{% endblock title %} + +{% block app_content %} + +{% include "assiduites/widgets/alert.j2" %} +{% include "assiduites/widgets/prompt.j2" %} +{% include "assiduites/widgets/conflict.j2" %} +{% include "assiduites/widgets/toast.j2" %} + +

Signalement différé de l'assiduité {{gr |safe}}

Attention, cette page utilise des couleurs et conventions différentes @@ -27,8 +47,14 @@

Vous pouvez supprimer une colonne en appuyant sur la croix qui se situe dans le coin haut droit de la colonne.

+{% endblock app_content %} - + + - - - -{% include "assiduites/widgets/alert.j2" %} -{% include "assiduites/widgets/prompt.j2" %} -{% include "assiduites/widgets/conflict.j2" %} -{% include "assiduites/widgets/toast.j2" %} \ No newline at end of file +{% endblock scripts %} diff --git a/app/templates/assiduites/pages/signal_assiduites_group.j2 b/app/templates/assiduites/pages/signal_assiduites_group.j2 index 2ce3672e..1d66a3c3 100644 --- a/app/templates/assiduites/pages/signal_assiduites_group.j2 +++ b/app/templates/assiduites/pages/signal_assiduites_group.j2 @@ -1,4 +1,86 @@ +{% extends "sco_page.j2" %} + +{% block title %} + {{title}} +{% endblock title %} + + +{% block scripts %} + {{ super() }} + + + + + + + + +{% endblock scripts %} + +{% block styles %} + {{ super() }} + + + + + +{% endblock styles %} + + +{% block app_content %} {% include "assiduites/widgets/toast.j2" %} + +{{ minitimeline|safe }} +
@@ -78,55 +160,6 @@ {% include "assiduites/widgets/prompt.j2" %} {% include "assiduites/widgets/conflict.j2" %} - -
\ No newline at end of file +{% endblock app_content %} diff --git a/app/templates/assiduites/widgets/differee.j2 b/app/templates/assiduites/widgets/differee.j2 index 250545c2..aebf1b98 100644 --- a/app/templates/assiduites/widgets/differee.j2 +++ b/app/templates/assiduites/widgets/differee.j2 @@ -270,6 +270,10 @@ -webkit-box-sizing: border-box; border: 10px solid white; } + + .mini-form { + color: black; + } - + + {%- endblock scripts %} {%- endblock body %} diff --git a/app/templates/base.j2 b/app/templates/base.j2 index 70462e26..a75325e5 100644 --- a/app/templates/base.j2 +++ b/app/templates/base.j2 @@ -1,4 +1,4 @@ -{# -*- mode: jinja-html -*- #} +{# base des pages hors départements (accueil, configuration, ...) #} {% extends 'babase.j2' %} {% block styles %} @@ -103,6 +103,5 @@ {% endblock %} \ No newline at end of file diff --git a/app/templates/sco_page.j2 b/app/templates/sco_page.j2 index f2bc9425..f50bd4cb 100644 --- a/app/templates/sco_page.j2 +++ b/app/templates/sco_page.j2 @@ -1,4 +1,4 @@ -{# -*- mode: jinja-html -*- #} +{# -*- Base des pages ordinaires, dans départements -*- #} {% extends 'babase.j2' %} {% block styles %} diff --git a/app/views/assiduites.py b/app/views/assiduites.py index 5a72ebf0..8e58de88 100644 --- a/app/views/assiduites.py +++ b/app/views/assiduites.py @@ -85,85 +85,6 @@ from app.scodoc.sco_archives_justificatifs import JustificatifArchiver CSSSTYLES = html_sco_header.BOOTSTRAP_MULTISELECT_CSS -# --- UTILS --- - - -class HTMLElement: - """Représentation d'un HTMLElement version Python""" - - def __init__(self, tag: str, *attr, **kattr) -> None: - self.tag: str = tag - self.children: list["HTMLElement"] = [] - self.self_close: bool = kattr.get("self_close", False) - self.text_content: str = kattr.get("text_content", "") - self.key_attributes: dict[str, Any] = kattr - self.attributes: list[str] = list(attr) - - def add(self, *child: "HTMLElement") -> None: - """add child element to self""" - for kid in child: - self.children.append(kid) - - def remove(self, child: "HTMLElement") -> None: - """Remove child element from self""" - if child in self.children: - self.children.remove(child) - - def __str__(self) -> str: - attr: list[str] = self.attributes - - for att, val in self.key_attributes.items(): - if att in ("self_close", "text_content"): - continue - - if att != "cls": - attr.append(f'{att}="{val}"') - else: - attr.append(f'class="{val}"') - - if not self.self_close: - head: str = f"<{self.tag} {' '.join(attr)}>{self.text_content}" - body: str = "\n".join(map(str, self.children)) - foot: str = f"" - return head + body + foot - return f"<{self.tag} {' '.join(attr)}/>" - - def __add__(self, other: str): - return str(self) + other - - def __radd__(self, other: str): - return other + str(self) - - -class HTMLStringElement(HTMLElement): - """Utilisation d'une chaine de caracètres pour représenter un element""" - - def __init__(self, text: str) -> None: - self.text: str = text - HTMLElement.__init__(self, "textnode") - - def __str__(self) -> str: - return self.text - - -class HTMLBuilder: - def __init__(self, *content: HTMLElement | str) -> None: - self.content: list[HTMLElement | str] = list(content) - - def add(self, *element: HTMLElement | str): - self.content.extend(element) - - def remove(self, element: HTMLElement | str): - if element in self.content: - self.content.remove(element) - - def __str__(self) -> str: - return "\n".join(map(str, self.content)) - - def build(self) -> str: - return self.__str__() - - # -------------------------------------------------------------------- # # Assiduité (/ScoDoc//Scolarite/Assiduites/...) @@ -539,18 +460,6 @@ def liste_assiduites_etud(): assiduite_id: int = request.args.get("assiduite_id", -1) # Préparation de la page - header: str = html_sco_header.sco_header( - page_title=f"Assiduité de {etud.nomprenom}", - init_qtip=True, - javascripts=[ - "js/assiduites.js", - "js/date_utils.js", - ], - cssstyles=CSSSTYLES - + [ - "css/assiduites.css", - ], - ) tableau = _prepare_tableau( liste_assi.AssiJustifData.from_etudiants( etud, @@ -563,16 +472,14 @@ def liste_assiduites_etud(): ) if not tableau[0]: return tableau[1] - # Peuplement du template jinja - return HTMLBuilder( - header, - render_template( - "assiduites/pages/liste_assiduites.j2", - sco=ScoData(etud), - assi_id=assiduite_id, - tableau=tableau[1], - ), - ).build() + # Page HTML: + return render_template( + "assiduites/pages/liste_assiduites.j2", + assi_id=assiduite_id, + etud=etud, + tableau=tableau[1], + sco=ScoData(etud), + ) @bp.route("/bilan_etud") @@ -593,20 +500,6 @@ def bilan_etud(): if etud.dept_id != g.scodoc_dept_id: abort(404, "étudiant inexistant dans ce département") - # Préparation de la page (header) - header: str = html_sco_header.sco_header( - page_title=f"Bilan de l'assiduité de {etud.nomprenom}", - init_qtip=True, - javascripts=[ - "js/assiduites.js", - "js/date_utils.js", - ], - cssstyles=CSSSTYLES - + [ - "css/assiduites.css", - ], - ) - # Gestion des dates du bilan (par défaut l'année scolaire) date_debut = scu.date_debut_annee_scolaire().strftime("%d/%m/%Y") date_fin: str = scu.date_fin_annee_scolaire().strftime("%d/%m/%Y") @@ -639,23 +532,20 @@ def bilan_etud(): if not table[0]: return table[1] - # Génération de la page - return HTMLBuilder( - header, - render_template( - "assiduites/pages/bilan_etud.j2", - sco=ScoData(etud), - date_debut=date_debut, - date_fin=date_fin, - assi_metric=assi_metric, - assi_seuil=_get_seuil(), - assi_limit_annee=sco_preferences.get_preference( - "assi_limit_annee", - dept_id=g.scodoc_dept_id, - ), - tableau=table[1], + # Génération de la page HTML + return render_template( + "assiduites/pages/bilan_etud.j2", + assi_limit_annee=sco_preferences.get_preference( + "assi_limit_annee", + dept_id=g.scodoc_dept_id, ), - ).build() + assi_metric=assi_metric, + assi_seuil=_get_seuil(), + date_debut=date_debut, + date_fin=date_fin, + sco=ScoData(etud), + tableau=table[1], + ) @bp.route("/edit_justificatif_etud/", methods=["GET", "POST"]) @@ -1105,55 +995,33 @@ def signal_assiduites_group(): grp + ' ' + groups_infos.groups_titles + "" ) - # --- Génération de l'HTML --- - - header: str = html_sco_header.sco_header( - page_title="Saisie journalière des assiduités", - init_qtip=True, - javascripts=html_sco_header.BOOTSTRAP_MULTISELECT_JS - + [ - # Voir fonctionnement JS - "js/etud_info.js", - "js/groups_view.js", - "js/assiduites.js", - "js/date_utils.js", - ], - cssstyles=CSSSTYLES - + [ - "css/assiduites.css", - "css/minitimeline.css", - ], - ) - # Récupération du semestre en dictionnaire sem = formsemestre.to_dict() - # Peuplement du template jinja - return HTMLBuilder( - header, - _mini_timeline(), - render_template( - "assiduites/pages/signal_assiduites_group.j2", - gr_tit=gr_tit, - sem=sem["titre_num"], - date=_dateiso_to_datefr(date), + # Page HTML + return render_template( + "assiduites/pages/signal_assiduites_group.j2", + date=_dateiso_to_datefr(date), + defdem=_get_etuds_dem_def(formsemestre), + forcer_module=sco_preferences.get_preference( + "forcer_module", formsemestre_id=formsemestre_id, - grp=sco_groups_view.menu_groups_choice(groups_infos), - moduleimpl_select=_module_selector(formsemestre, moduleimpl_id), - timeline=_timeline(heures=",".join([f"'{s}'" for s in heures])), - nonworkdays=_non_work_days(), - formsemestre_date_debut=str(formsemestre.date_debut), - formsemestre_date_fin=str(formsemestre.date_fin), - forcer_module=sco_preferences.get_preference( - "forcer_module", - formsemestre_id=formsemestre_id, - dept_id=g.scodoc_dept_id, - ), - defdem=_get_etuds_dem_def(formsemestre), - readonly="false", + dept_id=g.scodoc_dept_id, ), - html_sco_header.sco_footer(), - ).build() + formsemestre_date_debut=str(formsemestre.date_debut), + formsemestre_date_fin=str(formsemestre.date_fin), + formsemestre_id=formsemestre_id, + gr_tit=gr_tit, + grp=sco_groups_view.menu_groups_choice(groups_infos), + minitimeline=_mini_timeline(), + moduleimpl_select=_module_selector(formsemestre, moduleimpl_id), + nonworkdays=_non_work_days(), + readonly="false", + sco=ScoData(formsemestre=formsemestre), + sem=sem["titre_num"], + timeline=_timeline(heures=",".join([f"'{s}'" for s in heures])), + title="Saisie journalière des assiduités", + ) @bp.route("/visu_assiduites_group") @@ -1248,7 +1116,7 @@ def visu_assiduites_group(): # Si aucun etudiant n'est inscrit au module choisi... moduleimpl_id = None - # --- Génération de l'HTML --- + # --- Génération du HTML --- if groups_infos.tous_les_etuds_du_sem: gr_tit = "en" @@ -1261,52 +1129,32 @@ def visu_assiduites_group(): grp + ' ' + groups_infos.groups_titles + "" ) - header: str = html_sco_header.sco_header( - page_title="Saisie journalière de l'assiduité", - init_qtip=True, - javascripts=html_sco_header.BOOTSTRAP_MULTISELECT_JS - + [ - # Voir fonctionnement JS - "js/etud_info.js", - "js/groups_view.js", - "js/assiduites.js", - "js/date_utils.js", - ], - cssstyles=CSSSTYLES - + [ - "css/assiduites.css", - "css/minitimeline.css", - ], - ) - # Récupération du semestre en dictionnaire sem = formsemestre.to_dict() - return HTMLBuilder( - header, - _mini_timeline(), - render_template( - "assiduites/pages/signal_assiduites_group.j2", - gr_tit=gr_tit, - sem=sem["titre_num"], - date=_dateiso_to_datefr(date), + return render_template( + "assiduites/pages/signal_assiduites_group.j2", + date=_dateiso_to_datefr(date), + defdem=_get_etuds_dem_def(formsemestre), + forcer_module=sco_preferences.get_preference( + "forcer_module", formsemestre_id=formsemestre_id, - grp=sco_groups_view.menu_groups_choice(groups_infos), - moduleimpl_select=_module_selector(formsemestre, moduleimpl_id), - timeline=_timeline(), - nonworkdays=_non_work_days(), - formsemestre_date_debut=str(formsemestre.date_debut), - formsemestre_date_fin=str(formsemestre.date_fin), - forcer_module=sco_preferences.get_preference( - "forcer_module", - formsemestre_id=formsemestre_id, - dept_id=g.scodoc_dept_id, - ), - defdem=_get_etuds_dem_def(formsemestre), - readonly="true", + dept_id=g.scodoc_dept_id, ), - html_sco_header.sco_footer(), - ).build() + formsemestre_date_debut=str(formsemestre.date_debut), + formsemestre_date_fin=str(formsemestre.date_fin), + formsemestre_id=formsemestre_id, + gr_tit=gr_tit, + grp=sco_groups_view.menu_groups_choice(groups_infos), + minitimeline=_mini_timeline(), + moduleimpl_select=_module_selector(formsemestre, moduleimpl_id), + nonworkdays=_non_work_days(), + sem=sem["titre_num"], + timeline=_timeline(), + readonly="true", + sco=ScoData(formsemestre=formsemestre), + title="Saisie journalière de l'assiduité", + ) class RowEtudWithAssi(RowEtud): @@ -1828,7 +1676,9 @@ def _preparer_objet( @scodoc @permission_required(Permission.AbsChange) def signal_assiduites_diff(): - """TODO documenter""" + """TODO documenter + Utilisé notamment par "Saisie différée" sur tableau de bord semetstre" + """ # Récupération des paramètres de la requête group_ids: list[int] = request.args.get("group_ids", None) formsemestre_id: int = request.args.get("formsemestre_id", -1) @@ -1910,32 +1760,29 @@ def signal_assiduites_diff(): grp + ' ' + groups_infos.groups_titles + "" ) - return HTMLBuilder( - header, - render_template( - "assiduites/pages/signal_assiduites_diff.j2", - diff=_differee( - etudiants=etudiants, - moduleimpl_select=_module_selector( - formsemestre, request.args.get("moduleimpl_id", None) - ), - date=date, - periode={ - "deb": formsemestre.date_debut.isoformat(), - "fin": formsemestre.date_fin.isoformat(), - }, + return render_template( + "assiduites/pages/signal_assiduites_diff.j2", + defaultDates=_get_days_between_dates(date_deb, date_fin), + defdem=_get_etuds_dem_def(formsemestre), + diff=_differee( + etudiants=etudiants, + moduleimpl_select=_module_selector( + formsemestre, request.args.get("moduleimpl_id", None) ), - gr=gr_tit, - sem=formsemestre.titre_num(), - defdem=_get_etuds_dem_def(formsemestre), - timeMorning=ScoDocSiteConfig.get("assi_morning_time", "08:00:00"), - timeNoon=ScoDocSiteConfig.get("assi_lunch_time", "13:00:00"), - timeEvening=ScoDocSiteConfig.get("assi_afternoon_time", "18:00:00"), - defaultDates=_get_days_between_dates(date_deb, date_fin), - nonworkdays=_non_work_days(), + date=date, + periode={ + "deb": formsemestre.date_debut.isoformat(), + "fin": formsemestre.date_fin.isoformat(), + }, ), - html_sco_header.sco_footer(), - ).build() + gr=gr_tit, + nonworkdays=_non_work_days(), + sco=ScoData(formsemestre=formsemestre), + sem=formsemestre.titre_num(), + timeEvening=ScoDocSiteConfig.get("assi_afternoon_time", "18:00:00"), + timeMorning=ScoDocSiteConfig.get("assi_morning_time", "08:00:00"), + timeNoon=ScoDocSiteConfig.get("assi_lunch_time", "13:00:00"), + ) @bp.route("/signale_evaluation_abs//")