diff --git a/app/but/jury_but_pv.py b/app/but/jury_but_pv.py index 1462f1fbf8a9b61f0f758146ac8af47e46b1538f..cdb46acd72bbb0ae49f36e0dfc30cb6ed5fbcfdc 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"]) + return tab.make_page(fmt=fmt) def pvjury_table_but( diff --git a/app/models/events.py b/app/models/events.py index c65ea0ee70a4d7fff7fdf1b530a4276dee68f413..3bc853e16b80561b5ec34d902df210aab8e7a581 100644 --- a/app/models/events.py +++ b/app/models/events.py @@ -271,10 +271,10 @@ class ScolarNews(db.Model): return "" dept_news_url = url_for("scolar.dept_news", scodoc_dept=g.scodoc_dept) H = [ - f"""<div class="scobox news"><div class="scobox-title"><a href="{ + f"""<div class="scobox news"><div class="scobox-title" desktop="true"><a href="{ dept_news_url }">Dernières opérations</a> - </div><ul class="newslist">""" + </div><ul class="newslist" desktop="true">""" ] for news in news_list: @@ -289,11 +289,18 @@ class ScolarNews(db.Model): </li>""" ) - H.append("</ul></div>") + H.append( + """</ul> + <ul class="newslist" mobile="true" style="margin-bottom: 0px;"> + <li><a href="{dept_news_url}" class="stdlink">Dernières opérations</a></li> + </ul> + </div> + """ + ) # Informations générales H.append( - f"""<div> + f"""<div desktop="true"> Pour en savoir plus sur ScoDoc voir <a class="stdlink" href="{scu.SCO_ANNONCES_WEBSITE}">scodoc.org</a> </div> diff --git a/app/scodoc/html_sco_header.py b/app/scodoc/html_sco_header.py index 28d6249b25802534cbdf98d535f65e9f5e5e3781..e152be10eda5d6f00be885230f11a5517477b4b2 100644 --- a/app/scodoc/html_sco_header.py +++ b/app/scodoc/html_sco_header.py @@ -242,18 +242,3 @@ def sco_footer(): + scu.CUSTOM_HTML_FOOTER + """</body></html>""" ) - - -def html_sem_header( - title, with_page_header=True, with_h2=True, page_title=None, **args -): - "Titre d'une page semestre avec lien vers tableau de bord" - # sem now unused and thus optional... - if with_page_header: - h = sco_header(page_title="%s" % (page_title or title), **args) - else: - h = "" - if with_h2: - return h + f"""<h2 class="formsemestre">{title}</h2>""" - else: - return h diff --git a/app/scodoc/sco_archives_formsemestre.py b/app/scodoc/sco_archives_formsemestre.py index cbcbd201bd050864a5805d0e99a4db9e4ab4633b..4498625317eeb8d165f105adb1f31e1ea17b2cef 100644 --- a/app/scodoc/sco_archives_formsemestre.py +++ b/app/scodoc/sco_archives_formsemestre.py @@ -27,7 +27,7 @@ import json import flask -from flask import flash, g, request, url_for +from flask import flash, g, render_template, request, url_for from app import ScoDocJSONEncoder from app.but import jury_but_pv @@ -238,11 +238,6 @@ def formsemestre_archive(formsemestre_id, group_ids: list[int] = None): ) H = [ - html_sco_header.html_sem_header( - "Archiver les PV et résultats du semestre", - javascripts=sco_groups_view.JAVASCRIPTS, - cssstyles=sco_groups_view.CSSSTYLES, - ), """<p class="help">Cette page permet de générer et d'archiver tous les documents résultant de ce semestre: PV de jury, lettres individuelles, tableaux récapitulatifs.</p><p class="help">Les documents archivés sont @@ -311,7 +306,17 @@ enregistrés et non modifiables, on peut les retrouver ultérieurement. html_foot_markup=menu_choix_groupe, ) if tf[0] == 0: - return "\n".join(H) + "\n" + tf[1] + "\n".join(F) + return render_template( + "sco_page.j2", + title="Archiver les PV et résultats", + javascripts=sco_groups_view.JAVASCRIPTS, + cssstyles=sco_groups_view.CSSSTYLES, + content="<h2>Archiver les PV et résultats du semestre</h2>" + + "\n".join(H) + + "\n" + + tf[1] + + "\n".join(F), + ) elif tf[0] == -1: msg = "Opération annulée" else: @@ -371,7 +376,7 @@ def formsemestre_list_archives(formsemestre_id): } archives_descr.append(a) - H = [html_sco_header.html_sem_header("Archive des PV et résultats ")] + H = [] if not archives_descr: H.append("<p>aucune archive enregistrée</p>") else: @@ -399,7 +404,9 @@ def formsemestre_list_archives(formsemestre_id): H.append("</ul></li>") H.append("</ul>") - return "\n".join(H) + html_sco_header.sco_footer() + return render_template( + "sco_page.j2", title="Archive des PV et résultats", content="\n".join(H) + ) def formsemestre_get_archived_file(formsemestre_id, archive_name, filename): diff --git a/app/scodoc/sco_debouche.py b/app/scodoc/sco_debouche.py index a0c9d7a5d39bcd3b6408b07667902fbe1a9814e5..116c815dd1981dc68ae128e49e150f025492b564 100644 --- a/app/scodoc/sco_debouche.py +++ b/app/scodoc/sco_debouche.py @@ -76,7 +76,6 @@ def report_debouche_date(start_year=None, fmt="html"): tab.base_url = f"{request.base_url}?start_year={start_year}" return tab.make_page( title="""<h2 class="formsemestre">Débouchés étudiants </h2>""", - javascripts=["js/etud_info.js"], fmt=fmt, with_html_headers=True, ) diff --git a/app/scodoc/sco_etape_apogee_view.py b/app/scodoc/sco_etape_apogee_view.py index 9a576be8c98d70ef151b2b3c72e6b9e398f7208b..1bf9cdf1b8ecf5beb613e1bf1c6b1f91400f0770 100644 --- a/app/scodoc/sco_etape_apogee_view.py +++ b/app/scodoc/sco_etape_apogee_view.py @@ -597,7 +597,6 @@ def _view_etuds_page( return f""" {html_sco_header.sco_header( page_title=title, - javascripts=["js/etud_info.js"], )} <h2>{title}</h2> @@ -750,7 +749,6 @@ def view_apo_csv(etape_apo="", semset_id="", fmt="html"): H = [ html_sco_header.sco_header( page_title=f"""Maquette Apogée enregistrée pour {etape_apo}""", - javascripts=["js/etud_info.js"], ), f"""<h2>Étudiants dans la maquette Apogée {etape_apo}</h2> <p>Pour l'ensemble <a class="stdlink" href="{ diff --git a/app/scodoc/sco_evaluation_check_abs.py b/app/scodoc/sco_evaluation_check_abs.py index 852309abc444a15cbf24dba11503eabf031f7234..e8865708a9349e4742bf9f12e90eb37ab796871e 100644 --- a/app/scodoc/sco_evaluation_check_abs.py +++ b/app/scodoc/sco_evaluation_check_abs.py @@ -27,7 +27,7 @@ """Vérification des absences à une évaluation """ -from flask import url_for, g +from flask import g, render_template, url_for from flask_sqlalchemy.query import Query from app import db @@ -37,6 +37,7 @@ from app.scodoc import html_sco_header from app.scodoc import sco_evaluations from app.scodoc import sco_evaluation_db from app.scodoc import sco_groups +from app.views import ScoData def evaluation_check_absences(evaluation: Evaluation): @@ -109,8 +110,10 @@ def evaluation_check_absences(evaluation: Evaluation): def evaluation_check_absences_html( evaluation: Evaluation, with_header=True, show_ok=True -): - """Affiche état vérification absences d'une évaluation""" +) -> str: + """Affiche état vérification absences d'une évaluation. + Si with_header, génère page complète, sinon fragment html. + """ ( note_but_abs, # une note alors qu'il était signalé abs abs_non_signalee, # note ABS alors que pas signalé abs @@ -121,10 +124,6 @@ def evaluation_check_absences_html( if with_header: H = [ - html_sco_header.html_sem_header( - "Vérification absences à l'évaluation", - formsemestre_id=evaluation.moduleimpl.formsemestre_id, - ), sco_evaluations.evaluation_describe(evaluation_id=evaluation.id), """<p class="help">Vérification de la cohérence entre les notes saisies et les absences signalées.</p>""", @@ -208,19 +207,19 @@ def evaluation_check_absences_html( etudlist(abs_but_exc) if with_header: - H.append(html_sco_header.sco_footer()) + return render_template( + "sco_page.j2", + title="Vérification absences à l'évaluation", + content="<h2>Vérification absences à l'évaluation</h2>" + "\n".join(H), + sco=ScoData(formsemestre=evaluation.moduleimpl.formsemestre), + ) return "\n".join(H) -def formsemestre_check_absences_html(formsemestre_id): - """Affiche etat verification absences pour toutes les evaluations du semestre !""" - formsemestre: FormSemestre = FormSemestre.query.filter_by( - dept_id=g.scodoc_dept_id, id=formsemestre_id - ).first_or_404() +def formsemestre_check_absences_html(formsemestre_id: int): + """Affiche état vérification absences pour toutes les évaluations du semestre.""" + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) H = [ - html_sco_header.html_sem_header( - "Vérification absences aux évaluations de ce semestre", - ), """<p class="help">Vérification de la cohérence entre les notes saisies et les absences signalées. Sont listés tous les modules avec des évaluations.<br>Aucune action n'est effectuée: @@ -248,5 +247,9 @@ def formsemestre_check_absences_html(formsemestre_id): ) H.append("</div>") - H.append(html_sco_header.sco_footer()) - return "\n".join(H) + return render_template( + "sco_page.j2", + content="<h2>Vérification absences aux évaluations de ce semestre</h2>" + + "\n".join(H), + title="Vérification absences aux évaluations de ce semestre", + ) diff --git a/app/scodoc/sco_evaluation_recap.py b/app/scodoc/sco_evaluation_recap.py index 2648c33d47716e2d8691093eb93c754883101010..e9edd61113ab7d836c11a46dc2750b04916a92d8 100644 --- a/app/scodoc/sco_evaluation_recap.py +++ b/app/scodoc/sco_evaluation_recap.py @@ -10,7 +10,7 @@ avec leur état. Sur une idée de Pascal Bouron, de Lyon. """ import time -from flask import g, url_for +from flask import g, render_template, url_for from app import db from app.models import Evaluation, FormSemestre @@ -23,7 +23,7 @@ import app.scodoc.sco_utils as scu def evaluations_recap(formsemestre_id: int) -> str: """Page récap. de toutes les évaluations d'un semestre""" - formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) rows, titles = evaluations_recap_table(formsemestre) column_ids = titles.keys() filename = scu.sanitize_filename( @@ -32,11 +32,14 @@ def evaluations_recap(formsemestre_id: int) -> str: if not rows: return '<div class="evaluations_recap"><div class="message">aucune évaluation</div></div>' H = [ - html_sco_header.sco_header( - page_title="Évaluations du semestre", - javascripts=["js/evaluations_recap.js"], - ), - f"""<div class="evaluations_recap"><table class="evaluations_recap compact { + f"""<h2>Évaluations du semestre</h2> + <div> + <a class="stdlink" href="{url_for( + 'notes.formsemestre_check_absences_html', + scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre.id, + )}">Vérifier les absences aux évaluations</a> + </div> + <div class="evaluations_recap"><table class="evaluations_recap compact { 'apc' if formsemestre.formation.is_apc() else 'classic' }" data-filename="{filename}">""", @@ -56,13 +59,19 @@ def evaluations_recap(formsemestre_id: int) -> str: H.append( """</tbody></table></div> - <div class="help">Les étudiants démissionnaires ou défaillants ne sont pas pris en compte dans cette table.</div> + <div class="help">Les étudiants démissionnaires ou défaillants ne sont + pas pris en compte dans cette table.</div> """ ) H.append( html_sco_header.sco_footer(), ) - return "".join(H) + return render_template( + "sco_page.j2", + title="Évaluations du semestre", + javascripts=["js/evaluations_recap.js"], + content="".join(H), + ) def evaluations_recap_table(formsemestre: FormSemestre) -> list[dict]: diff --git a/app/scodoc/sco_evaluations.py b/app/scodoc/sco_evaluations.py index 3fdef7e000ea00fa1a2f45a8daa883104f66aa00..a961ecb3331363de2a7384f2e37e96f43ed691c4 100644 --- a/app/scodoc/sco_evaluations.py +++ b/app/scodoc/sco_evaluations.py @@ -31,9 +31,7 @@ import collections import datetime import operator -from flask import url_for -from flask import g -from flask import request +from flask import g, render_template, request, url_for from flask_login import current_user from app import db @@ -45,8 +43,6 @@ from app.models import Evaluation, FormSemestre, ModuleImpl, Module import app.scodoc.sco_utils as scu from app.scodoc.sco_utils import ModuleType from app.scodoc.gen_tables import GenTable -from app.scodoc import html_sco_header -from app.scodoc import sco_cal from app.scodoc import sco_evaluation_db from app.scodoc import sco_formsemestre_inscriptions from app.scodoc import sco_groups @@ -470,7 +466,7 @@ class CalendrierEval(sco_gen_cal.Calendrier): # View def formsemestre_evaluations_cal(formsemestre_id): - """Page avec calendrier de toutes les evaluations de ce semestre""" + """Page avec calendrier de toutes les évaluations de ce semestre""" formsemestre = FormSemestre.get_formsemestre(formsemestre_id) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) @@ -481,13 +477,12 @@ def formsemestre_evaluations_cal(formsemestre_id): cal = CalendrierEval(year, evaluations, nt) cal_html = cal.get_html() - return f""" - { - html_sco_header.html_sem_header( - "Evaluations du semestre", - cssstyles=["css/calabs.css"], - ) - } + return render_template( + "sco_page.j2", + cssstyles=["css/calabs.css"], + title="Évaluations du semestre", + content=f""" + <h2>Évaluations du semestre</h2> <div class="cal_evaluations"> { cal_html } </div> @@ -513,8 +508,8 @@ def formsemestre_evaluations_cal(formsemestre_id): ) }" class="stdlink">voir les délais de correction</a> </p> - { html_sco_header.sco_footer() } - """ + """, + ) def evaluation_date_first_completion(evaluation_id) -> datetime.datetime: @@ -651,7 +646,7 @@ def evaluation_describe(evaluation_id="", edit_in_place=True, link_saisie=True) """HTML description of evaluation, for page headers edit_in_place: allow in-place editing when permitted (not implemented) """ - evaluation: Evaluation = Evaluation.query.get_or_404(evaluation_id) + evaluation = Evaluation.get_evaluation(evaluation_id) modimpl = evaluation.moduleimpl responsable: User = db.session.get(User, modimpl.responsable_id) resp_nomprenom = responsable.get_prenomnom() diff --git a/app/scodoc/sco_export_results.py b/app/scodoc/sco_export_results.py index aaa707ab5bd227178e288ce753c67d4076239750..252e7f169ab5efecdc71c5a26201ce582983052d 100644 --- a/app/scodoc/sco_export_results.py +++ b/app/scodoc/sco_export_results.py @@ -73,7 +73,9 @@ def _build_results_table(start_date=None, end_date=None, types_parcours=[]): formsemestre_ids_parcours = [sem["formsemestre_id"] for sem in semlist_parcours] # Ensemble des étudiants - etuds_infos = {} # etudid : { formsemestre_id d'inscription le plus recent dans les dates considérées, etud } + etuds_infos = ( + {} + ) # etudid : { formsemestre_id d'inscription le plus recent dans les dates considérées, etud } for formsemestre_id in formsemestre_ids_parcours: formsemestre = FormSemestre.get_formsemestre(formsemestre_id) nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) @@ -285,8 +287,7 @@ def scodoc_table_results( H = [ html_sco_header.sco_header( page_title="Export résultats", - javascripts=html_sco_header.BOOTSTRAP_JS - + ["js/etud_info.js", "js/export_results.js"], + javascripts=html_sco_header.BOOTSTRAP_JS + ["js/export_results.js"], cssstyles=html_sco_header.BOOTSTRAP_CSS, ), # XXX diff --git a/app/scodoc/sco_find_etud.py b/app/scodoc/sco_find_etud.py index ecf97dc96973d6211b470ba2fb7dad59f8e4aee4..eb3fb169c6900f4967e9155c1ed5b435658594a5 100644 --- a/app/scodoc/sco_find_etud.py +++ b/app/scodoc/sco_find_etud.py @@ -28,7 +28,7 @@ """Recherche d'étudiants """ import flask -from flask import url_for, g, request +from flask import url_for, g, render_template, request from flask_login import current_user import sqlalchemy as sa @@ -177,13 +177,7 @@ def search_etud_in_dept(expnom=""): url_args["etudid"] = etuds[0].id return flask.redirect(url_for(endpoint, **url_args)) - H = [ - html_sco_header.sco_header( - page_title="Recherche d'un étudiant", - no_sidebar=False, - javascripts=["js/etud_info.js"], - ) - ] + H = [] if len(etuds) == 0 and len(etuds) <= 1: H.append("""<h2>chercher un étudiant:</h2>""") else: @@ -266,7 +260,9 @@ def search_etud_in_dept(expnom=""): """<p class="help">La recherche porte sur tout ou partie du NOM ou du NIP de l'étudiant. Saisir au moins deux caractères.</p>""" ) - return "\n".join(H) + html_sco_header.sco_footer() + return render_template( + "sco_page_dept.j2", title="Recherche d'un étudiant", content="\n".join(H) + ) def search_etuds_infos(expnom=None, code_nip=None) -> list[dict]: diff --git a/app/scodoc/sco_formsemestre_custommenu.py b/app/scodoc/sco_formsemestre_custommenu.py index 3be6383116ef3d144f6d3d03f9a3c41e3a2c0089..d719c42db6b946aca179f4c208b60712eee93b3f 100644 --- a/app/scodoc/sco_formsemestre_custommenu.py +++ b/app/scodoc/sco_formsemestre_custommenu.py @@ -28,7 +28,7 @@ """Menu "custom" (défini par l'utilisateur) dans les semestres """ import flask -from flask import g, url_for, request +from flask import g, url_for, render_template, request from flask_login import current_user from app.models.config import ScoDocSiteConfig, PersonalizedLink @@ -37,9 +37,6 @@ import app.scodoc.sco_utils as scu import app.scodoc.notesdb as ndb from app.scodoc.TrivialFormulator import TrivialFormulator from app.scodoc import html_sco_header -from app.scodoc import htmlutils -from app.scodoc import sco_formsemestre -from app.scodoc import sco_edt_cal _custommenuEditor = ndb.EditableTable( "notes_formsemestre_custommenu", @@ -106,14 +103,13 @@ def formsemestre_custommenu_html(formsemestre_id): def formsemestre_custommenu_edit(formsemestre_id): """Dialog to edit the custom menu""" - formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id) + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) dest_url = url_for( "notes.formsemestre_status", scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre_id, ) H = [ - html_sco_header.html_sem_header("Modification du menu du semestre "), """<div class="help"> <p>Ce menu, spécifique à chaque semestre, peut être utilisé pour placer des liens vers vos applications préférées. @@ -164,7 +160,14 @@ def formsemestre_custommenu_edit(formsemestre_id): name="tf", ) if tf[0] == 0: - return "\n".join(H) + "\n" + tf[1] + html_sco_header.sco_footer() + return render_template( + "sco_page.j2", + title="Modification du menu du semestre", + content="<h2>Modification du menu du semestre</h2>" + + "\n".join(H) + + "\n" + + tf[1], + ) elif tf[0] == -1: return flask.redirect(dest_url) else: diff --git a/app/scodoc/sco_formsemestre_edit.py b/app/scodoc/sco_formsemestre_edit.py index e5744970990951325aa852bc9c03686858399645..d5705b304feebf16ec3ee2f4900ef9564bc0b3c4 100644 --- a/app/scodoc/sco_formsemestre_edit.py +++ b/app/scodoc/sco_formsemestre_edit.py @@ -28,8 +28,7 @@ """Form choix modules / responsables et creation formsemestre """ import flask -from flask import url_for, flash, redirect -from flask import g, request +from flask import flash, g, request, redirect, render_template, url_for from flask_login import current_user import sqlalchemy as sa @@ -97,18 +96,10 @@ def formsemestre_createwithmodules(): return "\n".join(H) + html_sco_header.sco_footer() -def formsemestre_editwithmodules(formsemestre_id): +def formsemestre_editwithmodules(formsemestre_id: int): """Page modification semestre""" - formsemestre: FormSemestre = FormSemestre.query.filter_by( - id=formsemestre_id, dept_id=g.scodoc_dept_id - ).first_or_404() - H = [ - html_sco_header.html_sem_header( - "Modification du semestre", - javascripts=["libjs/AutoSuggest.js", "js/formsemestre_edit.js"], - cssstyles=["css/autosuggest_inquisitor.css"], - ) - ] + formsemestre = FormSemestre.get_formsemestre(formsemestre_id) + H = [] if not formsemestre.etat: H.append( f"""<p>{scu.icontag( @@ -136,7 +127,13 @@ def formsemestre_editwithmodules(formsemestre_id): """ ) - return "\n".join(H) + html_sco_header.sco_footer() + return render_template( + "sco_page.j2", + javascripts=["libjs/AutoSuggest.js", "js/formsemestre_edit.js"], + cssstyles=["css/autosuggest_inquisitor.css"], + title="Modification du semestre", + content="<h2>Modification du semestre</h2>" + "\n".join(H), + ) def can_edit_sem(formsemestre_id: int = None, sem=None): @@ -1162,12 +1159,9 @@ def formsemestre_clone(formsemestre_id): } H = [ - html_sco_header.html_sem_header( - "Copie du semestre", - javascripts=["libjs/AutoSuggest.js"], - cssstyles=["css/autosuggest_inquisitor.css"], - ), - """<p class="help">Cette opération duplique un semestre: on reprend les mêmes modules et responsables. Aucun étudiant n'est inscrit.</p>""", + """<p class="help">Cette opération duplique un semestre: + on reprend les mêmes modules et responsables. + Aucun étudiant n'est inscrit.</p>""", ] descr = [ @@ -1244,7 +1238,13 @@ def formsemestre_clone(formsemestre_id): if ndb.DateDMYtoISO(tf[2]["date_debut"]) > ndb.DateDMYtoISO(tf[2]["date_fin"]): msg = '<ul class="tf-msg"><li class="tf-msg">Dates de début et fin incompatibles !</li></ul>' if tf[0] == 0 or msg: - return "".join(H) + msg + tf[1] + html_sco_header.sco_footer() + return render_template( + "sco_page.j2", + javascripts=["libjs/AutoSuggest.js"], + cssstyles=["css/autosuggest_inquisitor.css"], + title="Copie du semestre", + content="".join(H) + msg + tf[1], + ) elif tf[0] == -1: # cancel return flask.redirect( url_for( @@ -1388,8 +1388,8 @@ def formsemestre_delete(formsemestre_id: int) -> str | flask.Response: """Delete a formsemestre (affiche avertissements)""" formsemestre: FormSemestre = FormSemestre.get_formsemestre(formsemestre_id) H = [ - html_sco_header.html_sem_header("Suppression du semestre"), - """<div class="ue_warning"><span>Attention !</span> + """<h2>Suppression du semestre</h2> +<div class="ue_warning"><span>Attention !</span> <p class="help">A n'utiliser qu'en cas d'erreur lors de la saisie d'une formation. Normalement, <b>un semestre ne doit jamais être supprimé</b> (on perd la mémoire des notes et de tous les événements liés à ce semestre !). @@ -1442,8 +1442,9 @@ Ceci n'est possible que si : ) else: H.append(tf[1]) - - return "\n".join(H) + html_sco_header.sco_footer() + return render_template( + "sco_page.j2", title="Suppression du semestre", content="\n".join(H) + ) if tf[0] == -1: # cancel return flask.redirect( @@ -1743,7 +1744,6 @@ def formsemestre_edit_uecoefs(formsemestre_id, err_ue_id=None): if not ok: return err - footer = html_sco_header.sco_footer() help_msg = """<p class="help"> Seuls les modules ont un coefficient. Cependant, il est nécessaire d'affecter un coefficient aux UE capitalisée pour pouvoir les prendre en compte dans la moyenne générale. </p> @@ -1766,7 +1766,6 @@ def formsemestre_edit_uecoefs(formsemestre_id, err_ue_id=None): </p> """ H = [ - html_sco_header.html_sem_header("Coefficients des UE du semestre"), help_msg, ] # @@ -1809,7 +1808,11 @@ def formsemestre_edit_uecoefs(formsemestre_id, err_ue_id=None): initvalues=initvalues, ) if tf[0] == 0: - return "\n".join(H) + tf[1] + footer + return render_template( + "sco_page.j2", + title="Coefficients des UE du semestre", + content="<h2>Coefficients des UE du semestre</h2>" + "\n".join(H) + tf[1], + ) elif tf[0] == -1: return redirect( url_for( @@ -1846,11 +1849,13 @@ def formsemestre_edit_uecoefs(formsemestre_id, err_ue_id=None): ) if not ok: - return ( - "\n".join(H) + render_template( + "sco_page.j2", + title="Coefficients des UE du semestre", + content="<h2>Coefficients des UE du semestre</h2>" + + "\n".join(H) + "<p><ul><li>%s</li></ul></p>" % "</li><li>".join(msg) - + tf[1] - + footer + + tf[1], ) # apply modifications @@ -1873,20 +1878,25 @@ def formsemestre_edit_uecoefs(formsemestre_id, err_ue_id=None): for ue in ue_deleted: message.append(f"<li>{ue.acronyme}</li>") message.append("</ul>") + sco_cache.invalidate_formsemestre( + formsemestre_id=formsemestre_id + ) # > modif coef UE cap (modifs notes de _certains_ etudiants) else: message = ["""<h3>Aucune modification</h3>"""] - sco_cache.invalidate_formsemestre( - formsemestre_id=formsemestre_id - ) # > modif coef UE cap (modifs notes de _certains_ etudiants) - return f"""{html_sco_header.html_sem_header("Coefficients des UE du semestre")} - {" ".join(message)} - <p><a class="stdlink" href="{url_for("notes.formsemestre_status", + return render_template( + "sco_page.j2", + title="Coefficients des UE du semestre", + content=f""" + <h2>Coefficients des UE du semestre</h2> + {" ".join(message)} + <p><a class="stdlink" href="{url_for( + "notes.formsemestre_status", scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre_id) }">Revenir au tableau de bord</a> </p> - {footer} - """ + """, + ) def _get_sem_ues_modimpls( diff --git a/app/scodoc/sco_formsemestre_inscriptions.py b/app/scodoc/sco_formsemestre_inscriptions.py index 9c234ff5c32adb7b0f3b11a1a4de80709f8d572e..bdd73ebbfb2c7f2c7efb0037602234539f204aa5 100644 --- a/app/scodoc/sco_formsemestre_inscriptions.py +++ b/app/scodoc/sco_formsemestre_inscriptions.py @@ -31,7 +31,7 @@ import collections import time import flask -from flask import flash, url_for, g, request +from flask import flash, url_for, g, render_template, request from app import db from app.comp import res_sem @@ -428,12 +428,7 @@ def formsemestre_inscription_with_modules( etud = Identite.get_etud(etudid) if etud.dept_id != formsemestre.dept_id: raise ScoValueError("l'étudiant n'est pas dans ce département") - H = [ - html_sco_header.html_sem_header( - f"Inscription de {etud.nomprenom} dans ce semestre", - ) - ] - footer = html_sco_header.sco_footer() + H = [] # Check 1: déjà inscrit ici ? inscr = FormSemestreInscription.query.filter_by( etudid=etud.id, formsemestre_id=formsemestre.id @@ -456,7 +451,12 @@ def formsemestre_inscription_with_modules( </ul> """ ) - return "\n".join(H) + footer + return render_template( + "sco_page.j2", + title=f"Inscription de {etud.nomprenom} dans ce semestre", + content=f"<h2>Inscription de {etud.nomprenom} dans ce semestre</h2>" + + "\n".join(H), + ) # Check 2: déjà inscrit dans un semestre recouvrant les même dates ? # Informe et propose dé-inscriptions others = est_inscrit_ailleurs(etudid, formsemestre_id) @@ -494,7 +494,12 @@ def formsemestre_inscription_with_modules( </p>""" # was sco_groups.make_query_groups(group_ids) ) - return "\n".join(H) + footer + return render_template( + "sco_page.j2", + title=f"Inscription de {etud.nomprenom} dans ce semestre", + content=f"<h2>Inscription de {etud.nomprenom} dans ce semestre</h2>" + + "\n".join(H), + ) # if group_ids is not None: # OK, inscription @@ -527,7 +532,12 @@ def formsemestre_inscription_with_modules( </form> """ ) - return "\n".join(H) + footer + return render_template( + "sco_page.j2", + title=f"Inscription de {etud.nomprenom} dans ce semestre", + content=f"<h2>Inscription de {etud.nomprenom} dans ce semestre</h2>" + + "\n".join(H), + ) def formsemestre_inscription_option(etudid, formsemestre_id): @@ -855,12 +865,7 @@ def formsemestre_inscrits_ailleurs(formsemestre_id): """Page listant les étudiants inscrits dans un autre semestre dont les dates recouvrent le semestre indiqué. """ - H = [ - html_sco_header.html_sem_header( - "Inscriptions multiples parmi les étudiants du semestre ", - javascripts=["js/etud_info.js"], - ) - ] + H = [] insd = list_inscrits_ailleurs(formsemestre_id) # liste ordonnée par nom etudlist = [Identite.get_etud(etudid) for etudid, sems in insd.items() if sems] @@ -912,4 +917,9 @@ def formsemestre_inscrits_ailleurs(formsemestre_id): ) else: H.append("""<p>Aucun étudiant en inscription multiple (c'est normal) !</p>""") - return "\n".join(H) + html_sco_header.sco_footer() + return render_template( + "sco_page.j2", + title="Inscriptions multiples parmi les étudiants du semestre", + content="<h2>Inscriptions multiples parmi les étudiants du semestre</h2>" + + "\n".join(H), + ) diff --git a/app/scodoc/sco_formsemestre_status.py b/app/scodoc/sco_formsemestre_status.py index fb0be87215d4c0844bd2fad1135d5e690170cbb0..6b5d1a3a163c53524bdf8e397c83374eacbc5fb6 100755 --- a/app/scodoc/sco_formsemestre_status.py +++ b/app/scodoc/sco_formsemestre_status.py @@ -741,9 +741,7 @@ def formsemestre_description_table( columns_ids=columns_ids, html_caption=title, html_class="table_leftalign formsemestre_description", - html_title=html_sco_header.html_sem_header( - "Description du semestre", with_page_header=False - ), + html_title="<h2>Description du semestre</h2>", origin=f"Généré par {sco_version.SCONAME} le {scu.timedate_human_repr()}", page_title=title, pdf_title=title, @@ -977,9 +975,6 @@ def formsemestre_status_head(formsemestre_id: int = None, page_title: str = None page_title = page_title or "Modules de " H = [ - html_sco_header.html_sem_header( - page_title, with_page_header=False, with_h2=False - ), f"""<table> <tr><td class="fichetitre2">Formation: </td><td> <a href="{url_for('notes.ue_table', diff --git a/app/scodoc/sco_formsemestre_validation.py b/app/scodoc/sco_formsemestre_validation.py index e685fbc7e79adc56e1184f674686f0dff2a0e16f..dfac0461bcd3cb1bc62d92fd64b50bf0af2f96ee 100644 --- a/app/scodoc/sco_formsemestre_validation.py +++ b/app/scodoc/sco_formsemestre_validation.py @@ -30,8 +30,7 @@ import time import flask -from flask import url_for, flash, g, request -from flask.templating import render_template +from flask import flash, g, render_template, request, url_for import sqlalchemy as sa from app.models import Identite, Evaluation @@ -957,11 +956,13 @@ def form_decision_manuelle(Se, formsemestre_id, etudid, desturl="", sortcol=None # ----------- -def formsemestre_validation_auto(formsemestre_id): - "Formulaire saisie automatisee des decisions d'un semestre" - H = [ - html_sco_header.html_sem_header("Saisie automatique des décisions du semestre"), - f""" +def formsemestre_validation_auto(formsemestre_id: int): + "Formulaire saisie automatisée des décisions d'un semestre" + return render_template( + "sco_page.j2", + title="Saisie automatique des décisions", + content=f""" + <h2>Saisie automatique des décisions du semestre</h2> <ul> <li>Seuls les étudiants qui obtiennent le semestre seront affectés (code ADM, moyenne générale et toutes les barres, semestre précédent validé);</li> @@ -978,9 +979,7 @@ def formsemestre_validation_auto(formsemestre_id): <p><em>Le calcul prend quelques minutes, soyez patients !</em></p> </form> """, - html_sco_header.sco_footer(), - ] - return "\n".join(H) + ) def do_formsemestre_validation_auto(formsemestre_id): diff --git a/app/scodoc/sco_groups_view.py b/app/scodoc/sco_groups_view.py index 2988dc3ea13d17439e1a5b9714dd0b67f21efcae..2114f20c78a36a53bf657c1840349dc20d8178e6 100644 --- a/app/scodoc/sco_groups_view.py +++ b/app/scodoc/sco_groups_view.py @@ -57,14 +57,11 @@ from app.scodoc.sco_exceptions import ScoValueError, ScoPermissionDenied from app.scodoc.sco_permissions import Permission JAVASCRIPTS = html_sco_header.BOOTSTRAP_JS + [ - "js/etud_info.js", "js/groups_view.js", "js/multi-select.js", ] -CSSSTYLES = html_sco_header.BOOTSTRAP_CSS + [ - "libjs/bootstrap/css/bootstrap.min.css", -] +CSSSTYLES = html_sco_header.BOOTSTRAP_CSS # view: @@ -615,8 +612,8 @@ def groups_table( etud_info["_nom_disp_order"] = etud_sort_key(etud_info) etud_info["_prenom_target"] = fiche_url - etud_info["_nom_disp_td_attrs"] = ( - 'id="%s" class="etudinfo"' % (etud_info["etudid"]) + etud_info["_nom_disp_td_attrs"] = 'id="%s" class="etudinfo"' % ( + etud_info["etudid"] ) etud_info["bourse_str"] = "oui" if etud_info["boursier"] else "non" if etud_info["etat"] == "D": diff --git a/app/scodoc/sco_inscr_passage.py b/app/scodoc/sco_inscr_passage.py index 347105f5012a93d9fd7397816f141818dd17ee35..28b65a0a8a08c852982f67bbc4034c7dd587e032 100644 --- a/app/scodoc/sco_inscr_passage.py +++ b/app/scodoc/sco_inscr_passage.py @@ -36,8 +36,6 @@ from flask import url_for, g, request import app.scodoc.notesdb as ndb import app.scodoc.sco_utils as scu from app import db, log -from app.comp import res_sem -from app.comp.res_compat import NotesTableCompat from app.models import Formation, FormSemestre, GroupDescr, Identite from app.scodoc.gen_tables import GenTable from app.scodoc import html_sco_header @@ -315,7 +313,6 @@ def formsemestre_inscr_passage( H = [ html_sco_header.sco_header( page_title="Passage des étudiants", - javascripts=["js/etud_info.js"], ) ] footer = html_sco_header.sco_footer() @@ -487,10 +484,9 @@ def _build_page( else: ignore_jury_checked = "" H = [ - html_sco_header.html_sem_header( - "Passages dans le semestre", with_page_header=False - ), - f"""<form name="f" method="post" action="{request.base_url}"> + f""" + <h2 class="formsemestre">Passages dans le semestre</h2> + <form name="f" method="post" action="{request.base_url}"> <input type="hidden" name="formsemestre_id" value="{formsemestre.id}"/> @@ -589,7 +585,7 @@ def formsemestre_inscr_passage_help(formsemestre: FormSemestre): def etuds_select_boxes( auth_etuds_by_cat, - inscrits_ailleurs={}, + inscrits_ailleurs: dict = None, sel_inscrits=True, show_empty_boxes=False, export_cat_xls=None, @@ -602,6 +598,7 @@ def etuds_select_boxes( sel_inscrits= export_cat_xls = """ + inscrits_ailleurs = inscrits_ailleurs or {} if export_cat_xls: return etuds_select_box_xls(auth_etuds_by_cat[export_cat_xls]) @@ -633,7 +630,7 @@ def etuds_select_boxes( for src_cat in auth_etuds_by_cat.keys(): infos = auth_etuds_by_cat[src_cat]["infos"] infos["comment"] = infos.get("comment", "") # commentaire dans sous-titre boite - help = infos.get("help", "") + help_txt = infos.get("help", "") etuds = auth_etuds_by_cat[src_cat]["etuds"] etuds.sort(key=itemgetter("nom")) with_checkbox = (not read_only) and auth_etuds_by_cat[src_cat]["infos"].get( @@ -650,8 +647,8 @@ def etuds_select_boxes( <div class="pas_sembox_title"><a href="%(title_target)s" """ % infos ) - if help: # bubble - H.append('title="%s"' % help) + if help_txt: # bubble + H.append('title="%s"' % help_txt) H.append( """>%(title)s</a></div> <div class="pas_sembox_subtitle">(%(nbetuds)d étudiants%(comment)s)""" diff --git a/app/scodoc/sco_lycee.py b/app/scodoc/sco_lycee.py index 79273e1675d7a56164904f3fb7f1db05a0f44a0c..4b2f262ea75a1db54f68dbb07e3651dfd6268463 100644 --- a/app/scodoc/sco_lycee.py +++ b/app/scodoc/sco_lycee.py @@ -98,7 +98,7 @@ def scodoc_table_etuds_lycees(fmt="html"): html_sco_header.sco_header( page_title=tab.page_title, init_google_maps=True, - javascripts=["js/etud_info.js", "js/map_lycees.js"], + javascripts=["js/map_lycees.js"], ), """<h2 class="formsemestre">Lycées d'origine des %d étudiants (%d semestres)</h2>""" % (len(etuds), len(semdepts)), @@ -219,8 +219,7 @@ def formsemestre_etuds_lycees( page_title=tab.page_title, init_google_maps=True, cssstyles=sco_groups_view.CSSSTYLES, - javascripts=sco_groups_view.JAVASCRIPTS - + ["js/etud_info.js", "js/map_lycees.js"], + javascripts=sco_groups_view.JAVASCRIPTS + ["js/map_lycees.js"], ), """<h2 class="formsemestre">Lycées d'origine des étudiants</h2>""", "\n".join(F), diff --git a/app/scodoc/sco_moduleimpl_inscriptions.py b/app/scodoc/sco_moduleimpl_inscriptions.py index cbd77ff96130dc209f5ce387fb480bec432e3bd6..4e2e86741d614b7bcffbd62c6d90dfc9437f8ddf 100644 --- a/app/scodoc/sco_moduleimpl_inscriptions.py +++ b/app/scodoc/sco_moduleimpl_inscriptions.py @@ -31,7 +31,7 @@ import collections from operator import attrgetter import flask -from flask import url_for, g, request +from flask import url_for, g, render_template, request from flask_login import current_user from app import db, log @@ -84,7 +84,6 @@ def moduleimpl_inscriptions_edit( return # can_change_inscriptions raises exception header = html_sco_header.sco_header( page_title="Inscription au module", - javascripts=["js/etud_info.js"], ) footer = html_sco_header.sco_footer() H = [ @@ -301,14 +300,12 @@ def moduleimpl_inscriptions_stats(formsemestre_id): # Page HTML: H = [ - html_sco_header.html_sem_header( - "Inscriptions aux modules et UE du semestre", - javascripts=["js/etud_info.js", "js/moduleimpl_inscriptions_stats.js"], - ) + f""" + <h2 class="formsemestre">Inscriptions aux modules et UE du semestre</h2> + <h3>Inscrits au semestre: {len(inscrits)} étudiants</h3> + """ ] - H.append(f"<h3>Inscrits au semestre: {len(inscrits)} étudiants</h3>") - if options: H.append("<h3>Modules auxquels tous les étudiants ne sont pas inscrits:</h3>") H.append( @@ -495,8 +492,12 @@ def moduleimpl_inscriptions_stats(formsemestre_id): """ ) - H.append(html_sco_header.sco_footer()) - return "\n".join(H) + return render_template( + "sco_page.j2", + title="Inscriptions aux modules et UE du semestre", + javascripts=["js/moduleimpl_inscriptions_stats.js"], + content="\n".join(H), + ) def _list_but_ue_inscriptions(res: NotesTableCompat, read_only: bool = True) -> str: diff --git a/app/scodoc/sco_poursuite_dut.py b/app/scodoc/sco_poursuite_dut.py index 628608a59b0148e2142f1f7f3a938fa575564e50..42fcd31012994cb403f9f2444ab1b0d9aae11fc9 100644 --- a/app/scodoc/sco_poursuite_dut.py +++ b/app/scodoc/sco_poursuite_dut.py @@ -233,7 +233,6 @@ def formsemestre_poursuite_report(formsemestre_id, fmt="html"): tab.base_url = "%s?formsemestre_id=%s" % (request.base_url, formsemestre_id) return tab.make_page( title="""<h2 class="formsemestre">Poursuite d'études</h2>""", - javascripts=["js/etud_info.js"], fmt=fmt, with_html_headers=True, ) diff --git a/app/scodoc/sco_preferences.py b/app/scodoc/sco_preferences.py index 6b940076daf6b6f890929a3e03e6ad79ebc2bed2..b7083eea169b63e7ac20bf91ca56fefe66024d27 100644 --- a/app/scodoc/sco_preferences.py +++ b/app/scodoc/sco_preferences.py @@ -112,7 +112,7 @@ get_base_preferences(formsemestre_id) """ import flask -from flask import current_app, flash, g, request, url_for +from flask import current_app, flash, g, render_template, request, url_for from app import db, log from app.models import Departement @@ -2243,14 +2243,8 @@ class BasePreferences: def edit(self): """HTML dialog: edit global preferences""" - from app.scodoc import html_sco_header - self.load() H = [ - html_sco_header.sco_header( - page_title=f"Préférences {g.scodoc_dept}", - javascripts=["js/detail_summary_persistence.js"], - ), f"<h2>Préférences globales pour le département {g.scodoc_dept}</h2>", # f"""<p><a href="{url_for("scodoc.configure_logos", scodoc_dept=g.scodoc_dept) # }">modification des logos du département (pour documents pdf)</a></p>""" @@ -2277,7 +2271,12 @@ class BasePreferences: ) dest_url = url_for("scolar.index_html", scodoc_dept=g.scodoc_dept) if tf[0] == 0: - return "\n".join(H) + tf[1] + html_sco_header.sco_footer() + return render_template( + "sco_page_dept.j2", + content="\n".join(H) + tf[1], + title=f"Préférences {g.scodoc_dept}", + javascripts=["js/detail_summary_persistence.js"], + ) if tf[0] == -1: return flask.redirect(dest_url) # cancel # @@ -2384,18 +2383,11 @@ class SemPreferences: # The dialog def edit(self, categories=[]): """Dialog to edit semestre preferences in given categories""" - from app.scodoc import html_sco_header - from app.scodoc import sco_formsemestre - if not self.formsemestre_id: raise ScoValueError( "sem_preferences.edit doit etre appele sur un semestre !" ) # a bug ! H = [ - html_sco_header.html_sem_header( - "Préférences du semestre", - javascripts=["js/detail_summary_persistence.js"], - ), """ <p class="help">Les paramètres définis ici ne s'appliqueront qu'à ce semestre.</p> <p class="msg">Attention: cliquez sur "Enregistrer les modifications" en bas de page pour appliquer vos changements !</p> @@ -2456,7 +2448,12 @@ function set_global_pref(el, pref_name) { ) if tf[0] == 0: - return "\n".join(H) + tf[1] + html_sco_header.sco_footer() + return render_template( + "sco_page.j2", + content="\n".join(H) + tf[1], + title="Préférences du semestre", + javascripts=["js/detail_summary_persistence.js"], + ) elif tf[0] == -1: flash("Annulé") return flask.redirect(dest_url) diff --git a/app/scodoc/sco_pv_forms.py b/app/scodoc/sco_pv_forms.py index d90363aa6ed0a30f7accf52fcf932fab947e805f..fa651942bfac36a35128ed80b6e9816d51cd62a8 100644 --- a/app/scodoc/sco_pv_forms.py +++ b/app/scodoc/sco_pv_forms.py @@ -35,8 +35,7 @@ from reportlab.platypus import Paragraph from reportlab.lib import styles import flask -from flask import flash, redirect, url_for -from flask import g, request +from flask import flash, g, redirect, render_template, request, url_for from app.models import FormSemestre, Identite @@ -223,15 +222,13 @@ def formsemestre_pvjury(formsemestre_id, fmt="html", publish=True): ) ) - footer = html_sco_header.sco_footer() - dpv = sco_pv_dict.dict_pvjury(formsemestre_id, with_prev=True) if not dpv: if fmt == "html": - return ( - html_sco_header.sco_header() - + "<h2>Aucune information disponible !</h2>" - + footer + return render_template( + "sco_page.j2", + title="PV Jury", + content="<h2>Aucune information disponible !</h2>", ) else: return None @@ -262,11 +259,10 @@ def formsemestre_pvjury(formsemestre_id, fmt="html", publish=True): ) tab.base_url = "%s?formsemestre_id=%s" % (request.base_url, formsemestre_id) H = [ - html_sco_header.html_sem_header( - "Décisions du jury pour le semestre", - javascripts=["js/etud_info.js"], - ), - """<p>(dernière modif le %s)</p>""" % dpv["date"], + f""" + <h2 class="formsemestre">Décisions du jury pour le semestre</h2> + <p>(dernière modif le {dpv["date"]})</p> + """, ] H.append( @@ -333,7 +329,9 @@ def formsemestre_pvjury(formsemestre_id, fmt="html", publish=True): """ ) H.append("</div>") # /codes - return "\n".join(H) + footer + return render_template( + "sco_page.j2", title="Décisions du jury pour le semestre", content="\n".join(H) + ) # --------------------------------------------------------------------------- @@ -351,9 +349,6 @@ def formsemestre_pvjury_pdf(formsemestre_id, group_ids: list[int] = None, etudid if etudid: # PV pour ce seul étudiant: etud = Identite.get_etud(etudid) - etuddescr = f"""<a class="discretelink" href="{ - url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid) - }">{etud.nomprenom}</a>""" etudids = [etudid] else: etuddescr = "" @@ -367,11 +362,6 @@ def formsemestre_pvjury_pdf(formsemestre_id, group_ids: list[int] = None, etudid etudids = [m["etudid"] for m in groups_infos.members] H = [ - html_sco_header.html_sem_header( - f"Édition du PV de jury {etuddescr}", - javascripts=sco_groups_view.JAVASCRIPTS, - cssstyles=sco_groups_view.CSSSTYLES, - ), f"""<div class="help">Utiliser cette page pour éditer des versions provisoires des PV. <span class="fontred">Il est recommandé d'archiver les versions définitives: <a class="stdlink" href="{url_for( @@ -384,7 +374,6 @@ def formsemestre_pvjury_pdf(formsemestre_id, group_ids: list[int] = None, etudid """<p><em>Voir aussi si besoin les réglages sur la page "Paramétrage" (accessible à l'administrateur du département).</em> </p>""", - html_sco_header.sco_footer(), ] descr = descrform_pvjury(formsemestre) if etudid: @@ -409,7 +398,20 @@ def formsemestre_pvjury_pdf(formsemestre_id, group_ids: list[int] = None, etudid html_foot_markup=menu_choix_groupe, ) if tf[0] == 0: - return "\n".join(H) + "\n" + tf[1] + "\n".join(F) + return render_template( + "sco_page.j2", + title=f"Édition du PV de jury de {etud.nom_prenom()}", + content=f"""<h2 class="formsemestre">Édition du PV de jury + de <a class="discretelink" href="{ + url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid) + }">{etud.nomprenom}</a></h2>""" + + "\n".join(H) + + "\n" + + tf[1] + + "\n".join(F), + javascripts=sco_groups_view.JAVASCRIPTS, + cssstyles=sco_groups_view.CSSSTYLES, + ) elif tf[0] == -1: return flask.redirect( url_for( @@ -541,7 +543,7 @@ def descrform_pvjury(formsemestre: FormSemestre): ] -def formsemestre_lettres_individuelles(formsemestre_id, group_ids=[]): +def formsemestre_lettres_individuelles(formsemestre_id, group_ids=()): "Lettres avis jury en PDF" formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id) if not group_ids: @@ -553,12 +555,9 @@ def formsemestre_lettres_individuelles(formsemestre_id, group_ids=[]): etudids = [m["etudid"] for m in groups_infos.members] H = [ - html_sco_header.html_sem_header( - "Édition des lettres individuelles", - javascripts=sco_groups_view.JAVASCRIPTS, - cssstyles=sco_groups_view.CSSSTYLES, - ), - f"""<p class="help">Utiliser cette page pour éditer des versions provisoires des PV. + f""" + <h2 class="formsemestre">Édition des lettres individuelles</h2> + <p class="help">Utiliser cette page pour éditer des versions provisoires des PV. <span class="fontred">Il est recommandé d'archiver les versions définitives: <a href="{url_for( "notes.formsemestre_archive", @@ -568,7 +567,6 @@ def formsemestre_lettres_individuelles(formsemestre_id, group_ids=[]): >voir cette page</a></span></p> """, ] - F = html_sco_header.sco_footer() descr = descrform_lettres_individuelles() menu_choix_groupe = ( """<div class="group_ids_sel_menu">Groupes d'étudiants à lister: """ @@ -587,7 +585,13 @@ def formsemestre_lettres_individuelles(formsemestre_id, group_ids=[]): html_foot_markup=menu_choix_groupe, ) if tf[0] == 0: - return "\n".join(H) + "\n" + tf[1] + F + return render_template( + "sco_page.j2", + title="Édition des lettres individuelles", + content="\n".join(H) + "\n" + tf[1], + javascripts=sco_groups_view.JAVASCRIPTS, + cssstyles=sco_groups_view.CSSSTYLES, + ) elif tf[0] == -1: return flask.redirect( url_for( diff --git a/app/scodoc/sco_recapcomplet.py b/app/scodoc/sco_recapcomplet.py index 35eb2f81645012db4a2eb246f52b2dfa7a96c0d1..33b8bb17da2035522e0a3c652b01ca8427567f7f 100644 --- a/app/scodoc/sco_recapcomplet.py +++ b/app/scodoc/sco_recapcomplet.py @@ -123,7 +123,7 @@ def formsemestre_recapcomplet( page_title=f"{formsemestre.sem_modalite()}: " + ("jury" if mode_jury else "moyennes"), no_sidebar=True, - javascripts=["js/etud_info.js", "js/table_recap.js"], + javascripts=["js/table_recap.js"], ), sco_formsemestre_status.formsemestre_status_head( formsemestre_id=formsemestre_id diff --git a/app/scodoc/sco_report.py b/app/scodoc/sco_report.py index 5fa740c60f7311bca0897d8a8b0fe978ce73c686..2f316bd6ca1ccbe8c5d2d387399a63af88233282 100644 --- a/app/scodoc/sco_report.py +++ b/app/scodoc/sco_report.py @@ -1367,7 +1367,6 @@ def formsemestre_suivi_cursus( H = [ html_sco_header.sco_header( page_title=tab.page_title, - javascripts=["js/etud_info.js"], ), """<h2 class="formsemestre">Cursus suivis par les étudiants de ce semestre</h2>""", "\n".join(F), diff --git a/app/scodoc/sco_synchro_etuds.py b/app/scodoc/sco_synchro_etuds.py index f92c9a38aa474a842ff3ed18270c79122f771baf..869444ef24e9072063eff65eab2591d48ae27d35 100644 --- a/app/scodoc/sco_synchro_etuds.py +++ b/app/scodoc/sco_synchro_etuds.py @@ -168,12 +168,7 @@ def formsemestre_synchro_etuds( suffix=scu.XLSX_SUFFIX, ) - H = [ - html_sco_header.sco_header( - page_title="Synchronisation étudiants", - javascripts=["js/etud_info.js"], - ) - ] + H = [html_sco_header.sco_header(page_title="Synchronisation étudiants")] if not submitted: H += _build_page( sem, diff --git a/app/scodoc/sco_ue_external.py b/app/scodoc/sco_ue_external.py index 2ad5b53ae218001328656cff5d3a0b1978e1822a..6d529b28279569374a214fa7bbad5517297ab791 100644 --- a/app/scodoc/sco_ue_external.py +++ b/app/scodoc/sco_ue_external.py @@ -54,14 +54,13 @@ Solution proposée (nov 2014): """ import flask -from flask import flash, g, request, url_for +from flask import flash, g, request, render_template, url_for from flask_login import current_user from app.models.formsemestre import FormSemestre from app import db, log from app.models import Evaluation, Identite, ModuleImpl, UniteEns -from app.scodoc import html_sco_header from app.scodoc import codes_cursus from app.scodoc import sco_edit_matiere from app.scodoc import sco_edit_module @@ -240,11 +239,9 @@ def external_ue_create_form(formsemestre_id: int, etudid: int): existing_external_ue = get_existing_external_ue(formation_id) H = [ - html_sco_header.html_sem_header( - f"Ajout d'une UE externe pour {etud.nomprenom}", - javascripts=["js/sco_ue_external.js"], - ), - """<p class="help">Cette page permet d'indiquer que l'étudiant a suivi une UE + f""" + <h2 class="formsemestre">Ajout d'une UE externe pour {etud.nomprenom}</h2> + <p class="help">Cette page permet d'indiquer que l'étudiant a suivi une UE dans un autre établissement et qu'elle doit être intégrée dans le semestre courant.<br> La note (/20) obtenue par l'étudiant doit toujours être spécifiée.</br> On peut choisir une UE externe existante (dans le menu), ou bien en créer une, qui sera @@ -252,7 +249,6 @@ def external_ue_create_form(formsemestre_id: int, etudid: int): </p> """, ] - html_footer = html_sco_header.sco_footer() parcours = formsemestre.formation.get_cursus() ue_types = [ typ for typ in parcours.ALLOWED_UE_TYPES if typ != codes_cursus.UE_SPORT @@ -349,7 +345,12 @@ def external_ue_create_form(formsemestre_id: int, etudid: int): etudid=etudid, ) if tf[0] == 0: - return "\n".join(H) + "\n" + tf[1] + html_footer + return render_template( + "sco_page.j2", + title=f"Ajout d'une UE externe pour {etud.nomprenom}", + javascripts=["js/sco_ue_external.js"], + content="\n".join(H) + "\n" + tf[1], + ) elif tf[0] == -1: return flask.redirect(bull_url) else: @@ -358,12 +359,14 @@ def external_ue_create_form(formsemestre_id: int, etudid: int): note, 20.0, etudid=etudid, absents=[], invalids=[] ) if invalid: - return ( - "\n".join(H) + return render_template( + "sco_page.j2", + title=f"Ajout d'une UE externe pour {etud.nomprenom}", + javascripts=["js/sco_ue_external.js"], + content="\n".join(H) + "\n" + tf_error_message("valeur note invalide") - + tf[1] - + html_footer + + tf[1], ) if tf[2]["existing_ue"]: ue_id = int(tf[2]["existing_ue"]) @@ -371,12 +374,14 @@ def external_ue_create_form(formsemestre_id: int, etudid: int): else: acronyme = tf[2]["acronyme"].strip() if not acronyme: - return ( - "\n".join(H) + return render_template( + "sco_page.j2", + title=f"Ajout d'une UE externe pour {etud.nomprenom}", + javascripts=["js/sco_ue_external.js"], + content="\n".join(H) + "\n" + tf_error_message("spécifier acronyme d'UE") - + tf[1] - + html_footer + + tf[1], ) modimpl = external_ue_create( formsemestre_id, diff --git a/app/scodoc/sco_users.py b/app/scodoc/sco_users.py index f1ab31917c4f9b8bdfd8eb8705972e2c4bf7614b..90d1688e1f9865353ed46413f8ec71569d8004bc 100644 --- a/app/scodoc/sco_users.py +++ b/app/scodoc/sco_users.py @@ -31,7 +31,7 @@ # Anciennement ZScoUsers.py, fonctions de gestion des données réécrites avec flask/SQLAlchemy import re -from flask import url_for, g, request +from flask import url_for, g, render_template, request from flask_login import current_user @@ -54,7 +54,7 @@ def index_html( all_depts = int(all_depts) with_inactives = int(with_inactives) - H = [html_sco_header.html_sem_header("Gestion des utilisateurs")] + H = ["<h2>Gestion des utilisateurs</h2>"] if current_user.has_permission(Permission.UsersAdmin, g.scodoc_dept): H.append( @@ -112,6 +112,7 @@ def index_html( raise ScoValueError("nom de rôle invalide") else: having_role = None + content = list_users( g.scodoc_dept, all_depts=all_depts, @@ -122,10 +123,12 @@ def index_html( ) if fmt != "html": return content + H.append(content) - F = html_sco_header.sco_footer() - return "\n".join(H) + F + return render_template( + "sco_page.j2", content="\n".join(H), title="Gestion des utilisateurs" + ) def list_users( diff --git a/app/static/css/scodoc.css b/app/static/css/scodoc.css index 24e4d1e614c9a3be83f14c9b8567784456254582..e147f51eaee1242f833199535da66f204e768c8a 100644 --- a/app/static/css/scodoc.css +++ b/app/static/css/scodoc.css @@ -686,11 +686,6 @@ div.scobox.news { background-color: rgb(255, 235, 170); } -div.news a, -div.news a.stdlink { - color: black; - text-decoration: none; -} div.news a:hover { color: rgb(153, 51, 51); diff --git a/app/templates/sco_page.j2 b/app/templates/sco_page.j2 index 9c57af97a4c26f06da91bb397b2d70a682abf7c2..792042003830faa8fd061747bb328b306cbb8b1c 100644 --- a/app/templates/sco_page.j2 +++ b/app/templates/sco_page.j2 @@ -43,14 +43,18 @@ <img id="toggle-sidebar-img" src="{{scu.STATIC_DIR}}/icons/back.svg" width="12px" alt="toggle sidebar"/> </div> </div> - <div class="formsemestre-page-header"> + {% if sco.formsemestre %} + <div class="formsemestre-page-header"> + {% include "flashed_messages.j2" %} + {% if sco.formsemestre %} + {% block formsemestre_header %} + {% include "formsemestre_header.j2" %} + {% endblock %} + {% endif %} + </div> + {% else %} {% include "flashed_messages.j2" %} - {% if sco.formsemestre %} - {% block formsemestre_header %} - {% include "formsemestre_header.j2" %} - {% endblock %} - {% endif %} - </div> + {% endif %} <div id="sidebar"> {% include "sidebar.j2" %} </div> @@ -73,6 +77,7 @@ <script src="{{scu.STATIC_DIR}}/libjs/menu.js"></script> <script src="{{scu.STATIC_DIR}}/libjs/bubble.js"></script> <script src="{{scu.STATIC_DIR}}/js/scodoc.js"></script> +<script src="{{scu.STATIC_DIR}}/js/etud_info.js"></script> <script src="{{scu.STATIC_DIR}}/DataTables/datatables.min.js"></script> <script> window.onload = function () { diff --git a/app/views/absences.py b/app/views/absences.py index ad10908eae2a9fad87df196fb73d927936193a0b..d3f26ebbdd9b9a743f3a65db78cef2240104f90e 100644 --- a/app/views/absences.py +++ b/app/views/absences.py @@ -246,7 +246,6 @@ def list_billets(): H = [ html_sco_header.sco_header( page_title="Billet d'absence non traités", - javascripts=["js/etud_info.js"], ), f"<h2>Billets d'absence en attente de traitement ({table.get_nb_rows()})</h2>", ] diff --git a/app/views/notes.py b/app/views/notes.py index 587132cd1e3cb5c54ce0c93ccf706dcbf9acee4b..3d8746a152505953a91b84e0efb6b26200600ff8 100644 --- a/app/views/notes.py +++ b/app/views/notes.py @@ -942,18 +942,12 @@ def edit_enseignants_form(moduleimpl_id): "modif liste enseignants/moduleimpl" modimpl = ModuleImpl.get_modimpl(moduleimpl_id) modimpl.can_change_ens(raise_exc=True) - # -- - header = html_sco_header.html_sem_header( - f"""Enseignants du <a href="{ + # + page_title = f"Enseignants du module {modimpl.module.titre or modimpl.module.code}" + title = f"""Enseignants du <a href="{ url_for("notes.moduleimpl_status", scodoc_dept=g.scodoc_dept, moduleimpl_id=modimpl.id) - }">module {modimpl.module.titre or modimpl.module.code}</a>""", - page_title=f"Enseignants du module {modimpl.module.titre or modimpl.module.code}", - javascripts=["libjs/AutoSuggest.js"], - cssstyles=["css/autosuggest_inquisitor.css"], - ) - footer = html_sco_header.sco_footer() - + }">module {modimpl.module.titre or modimpl.module.code}</a>""" # Liste des enseignants avec forme pour affichage / saisie avec suggestion userlist = sco_users.get_user_list() uid2display = {} # uid : forme pour affichage = "NOM Prenom (login)"(login)" @@ -1021,7 +1015,13 @@ def edit_enseignants_form(moduleimpl_id): cancelbutton="Annuler", ) if tf[0] == 0: - return header + "\n".join(H) + tf[1] + F + footer + return render_template( + "sco_page.j2", + title=page_title, + content=title + "\n".join(H) + tf[1], + javascripts=["libjs/AutoSuggest.js"], + cssstyles=["css/autosuggest_inquisitor.css"], + ) elif tf[0] == -1: return flask.redirect( url_for( @@ -1058,7 +1058,13 @@ def edit_enseignants_form(moduleimpl_id): moduleimpl_id=moduleimpl_id, ) ) - return header + "\n".join(H) + tf[1] + F + footer + return render_template( + "sco_page.j2", + title=page_title, + content=title + "\n".join(H) + tf[1], + javascripts=["libjs/AutoSuggest.js"], + cssstyles=["css/autosuggest_inquisitor.css"], + ) @bp.route("/edit_moduleimpl_resp", methods=["GET", "POST"]) @@ -1072,15 +1078,13 @@ def edit_moduleimpl_resp(moduleimpl_id: int): modimpl: ModuleImpl = ModuleImpl.query.get_or_404(moduleimpl_id) modimpl.can_change_responsable(current_user, raise_exc=True) # access control H = [ - html_sco_header.html_sem_header( - f"""Modification du responsable du <a class="stdlink" href="{ + f"""<h2 class="formsemestre">Modification du responsable du + <a class="stdlink" href="{ url_for("notes.moduleimpl_status", scodoc_dept=g.scodoc_dept, moduleimpl_id=moduleimpl_id) - }">module {modimpl.module.titre or ""}</a>""", - javascripts=["libjs/AutoSuggest.js"], - cssstyles=["css/autosuggest_inquisitor.css"], - ) + }">module {modimpl.module.titre or ""}</a></h2>""" ] + help_str = """<p class="help">Taper le début du nom de l'enseignant.</p>""" # Liste des enseignants avec forme pour affichage / saisie avec suggestion userlist = [sco_users.user_info(user=u) for u in sco_users.get_user_list()] @@ -1125,7 +1129,13 @@ def edit_moduleimpl_resp(moduleimpl_id: int): initvalues=initvalues, ) if tf[0] == 0: - return "\n".join(H) + tf[1] + help_str + html_sco_header.sco_footer() + return render_template( + "sco_page.j2", + content="\n".join(H) + tf[1] + help_str, + title="Modification responsable module", + javascripts=["libjs/AutoSuggest.js"], + cssstyles=["css/autosuggest_inquisitor.css"], + ) elif tf[0] == -1: return flask.redirect( url_for( @@ -1198,21 +1208,13 @@ def view_module_abs(moduleimpl_id, fmt="html"): } ) - H = [ - html_sco_header.html_sem_header( - f"""Absences du <a href="{ - url_for("notes.moduleimpl_status", - scodoc_dept=g.scodoc_dept, moduleimpl_id=moduleimpl_id - )}">module {modimpl.module.titre_str()}</a>""", - page_title=f"Absences du module {modimpl.module.titre_str()}", - ) - ] + content = f""" + <h2>Absences du <a href="{ + url_for("notes.moduleimpl_status", + scodoc_dept=g.scodoc_dept, moduleimpl_id=moduleimpl_id + )}">module {modimpl.module.titre_str()}</a></h2>""" if not rows and fmt == "html": - return ( - "\n".join(H) - + "<p>Aucune absence signalée</p>" - + html_sco_header.sco_footer() - ) + content += "<p>Aucune absence signalée</p>" tab = GenTable( titles={ @@ -1236,7 +1238,14 @@ def view_module_abs(moduleimpl_id, fmt="html"): if fmt != "html": return tab.make_page(fmt=fmt) - return "\n".join(H) + tab.html() + html_sco_header.sco_footer() + if not tab.is_empty(): + content += tab.html() + + return render_template( + "sco_page.j2", + content=content, + title=f"Absences du module {modimpl.module.titre_str()}", + ) @bp.route("/delete_ue_expr/<int:formsemestre_id>/<int:ue_id>", methods=["GET", "POST"]) @@ -1337,9 +1346,7 @@ def formsemestre_enseignants_list(formsemestre_id, fmt="html"): html_class="table_leftalign formsemestre_enseignants_list", html_with_td_classes=True, filename=scu.make_filename(f"Enseignants-{formsemestre.titre_annee()}"), - html_title=html_sco_header.html_sem_header( - "Enseignants du semestre", with_page_header=False - ), + html_title="""<h2 class="formsemestre">Enseignants du semestre</h2>""", base_url=f"{request.base_url}?formsemestre_id={formsemestre_id}", caption="""Tous les enseignants (responsables ou associés aux modules de ce semestre) apparaissent. Le nombre de saisies d'absences est indicatif.""", @@ -1646,7 +1653,6 @@ def evaluation_delete(evaluation_id): etat = sco_evaluations.do_evaluation_etat(evaluation.id) H = [ f""" - {html_sco_header.html_sem_header(tit, with_h2=False)} <h2 class="formsemestre">Module <tt>{evaluation.moduleimpl.module.code}</tt> {evaluation.moduleimpl.module.titre_str()}</h2> <h3>{tit}</h3> @@ -1682,7 +1688,7 @@ def evaluation_delete(evaluation_id): </p> </div>""" ) - return "\n".join(H) + html_sco_header.sco_footer() + return render_template("sco_page.j2", title=tit, content="\n".join(H)) if warning: H.append("""</div>""") @@ -1695,7 +1701,7 @@ def evaluation_delete(evaluation_id): cancelbutton="Annuler", ) if tf[0] == 0: - return "\n".join(H) + tf[1] + html_sco_header.sco_footer() + return render_template("sco_page.j2", title=tit, content="\n".join(H) + tf[1]) elif tf[0] == -1: return flask.redirect( url_for( @@ -1706,14 +1712,15 @@ def evaluation_delete(evaluation_id): ) else: evaluation.delete() - return ( - "\n".join(H) + return render_template( + "sco_page.j2", + title=tit, + content="\n".join(H) + f"""<p>OK, évaluation supprimée.</p> <p><a class="stdlink" href="{ url_for("notes.moduleimpl_status", scodoc_dept=g.scodoc_dept, moduleimpl_id=evaluation.moduleimpl_id) - }">Continuer</a></p>""" - + html_sco_header.sco_footer() + }">Continuer</a></p>""", ) @@ -1771,7 +1778,6 @@ def evaluation_listenotes(): content=content, title=page_title, cssstyles=["css/verticalhisto.css"], - javascripts=["js/etud_info.js"], ) return content diff --git a/app/views/scolar.py b/app/views/scolar.py index 6cf569affc6431c12a79bb5666e7536ebffec89c..60e89d4dd741d252f89da9362164d52c1cdcfb0a 100644 --- a/app/views/scolar.py +++ b/app/views/scolar.py @@ -1961,14 +1961,15 @@ def check_group_apogee(group_id, etat=None, fix=False, fixmail=False): etat = etat or None members, group, _, sem, _ = sco_groups.get_group_infos(group_id, etat=etat) formsemestre_id = group["formsemestre_id"] - + title = f"""Étudiants du {group["group_name"] or "semestre"}""" cnx = ndb.GetDBConnexion() H = [ - html_sco_header.html_sem_header( - "Étudiants du %s" % (group["group_name"] or "semestre") - ), - '<table class="sortable" id="listegroupe">', - "<tr><th>Nom</th><th>Nom usuel</th><th>Prénom</th><th>Mail</th><th>NIP (ScoDoc)</th><th>Apogée</th></tr>", + f"""<h2 class="formsemestre">{title}</h2> + <table class="sortable" id="listegroupe"> + <tr> + <th>Nom</th><th>Nom usuel</th><th>Prénom</th><th>Mail</th> + <th>NIP (ScoDoc)</th><th>Apogée</th> + </tr>""" ] nerrs = 0 # nombre d'anomalies détectées nfix = 0 # nb codes changes @@ -2090,8 +2091,7 @@ def check_group_apogee(group_id, etat=None, fix=False, fixmail=False): formsemestre_id, ) ) - - return "\n".join(H) + html_sco_header.sco_footer() + return render_template("sco_page.j2", title=title, content="\n".join(H)) @bp.route("/export_etudiants_courants") @@ -2483,8 +2483,11 @@ def formsemestre_import_etud_admission( diag += "</ul>" diag_by_sem[formsemestre.id] = diag - return f""" - { html_sco_header.html_sem_header("Ré-import données admission") } + return render_template( + "sco_page.j2", + title="Ré-import données admission", + content=f""" + <h2>Ré-import données admission</h2> <h3>Opération effectuée</h3> <p>Sur le(s) semestres(s):</p> <ul> @@ -2492,8 +2495,8 @@ def formsemestre_import_etud_admission( { '</li><li>'.join( [(s.html_link_status() + diag_by_sem[s.id]) for s in formsemestres ]) } </li> </ul> - { html_sco_header.sco_footer() } - """ + """, + ) sco_publish(