From 37c93c8524da904a9ecba1f816cc3f726a169f58 Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet <emmanuel.viennet@gmail.com> Date: Sat, 24 Aug 2024 08:06:46 +0200 Subject: [PATCH] Cosmetic / templatification --- app/scodoc/gen_tables.py | 3 +- app/scodoc/sco_archives_formsemestre.py | 24 +++--- app/scodoc/sco_debouche.py | 16 ++-- app/scodoc/sco_edit_formation.py | 9 ++- app/scodoc/sco_edit_module.py | 49 +++++------ app/scodoc/sco_edit_ue.py | 12 +-- app/scodoc/sco_evaluations.py | 4 +- app/scodoc/sco_excel.py | 2 +- app/scodoc/sco_formation_recap.py | 4 +- app/scodoc/sco_formation_versions.py | 1 + app/scodoc/sco_formsemestre_edit.py | 25 +++--- app/scodoc/sco_formsemestre_status.py | 81 ++++++++++++------- app/scodoc/sco_formsemestre_validation.py | 12 ++- app/scodoc/sco_groups_exports.py | 2 +- app/scodoc/sco_groups_view.py | 25 +++--- app/scodoc/sco_moduleimpl_status.py | 2 +- app/scodoc/sco_utils.py | 7 +- app/static/css/scodoc.css | 20 ++++- .../pages/feuille_abs_formsemestre.j2 | 30 +++---- app/templates/bul_head.j2 | 2 +- app/templates/but/bulletin_court_page.j2 | 2 +- app/templates/but/parcour_formation.j2 | 2 +- app/templates/but/refcomp_load.j2 | 2 +- app/templates/but/refcomp_show.j2 | 2 +- app/templates/but/refcomp_table.j2 | 2 +- app/templates/but/validate_dut120.j2 | 2 +- .../formation/ue_assoc_parcours_ects.j2 | 20 ++--- .../formsemestre/bulletins_choice.j2 | 2 + app/templates/pn/form_modules_ue_coefs.j2 | 28 ++++++- app/views/pn_modules.py | 74 +++++------------ sco_version.py | 2 +- 31 files changed, 260 insertions(+), 208 deletions(-) diff --git a/app/scodoc/gen_tables.py b/app/scodoc/gen_tables.py index f37a55f68..e9368f071 100644 --- a/app/scodoc/gen_tables.py +++ b/app/scodoc/gen_tables.py @@ -685,6 +685,7 @@ class GenTable: javascripts=(), with_html_headers=True, publish=True, + template="sco_page.j2", ): """ Build page at given format @@ -703,7 +704,7 @@ class GenTable: H.append(self.html()) if with_html_headers: return render_template( - "sco_page.j2", + template, content="\n".join(H), title=page_title, javascripts=javascripts, diff --git a/app/scodoc/sco_archives_formsemestre.py b/app/scodoc/sco_archives_formsemestre.py index 449862531..2365e1b77 100644 --- a/app/scodoc/sco_archives_formsemestre.py +++ b/app/scodoc/sco_archives_formsemestre.py @@ -36,7 +36,6 @@ from app.comp.res_compat import NotesTableCompat from app.models import FormSemestre from app.scodoc.TrivialFormulator import TrivialFormulator from app.scodoc.sco_exceptions import ScoPermissionDenied -from app.scodoc import html_sco_header from app.scodoc import sco_bulletins_pdf from app.scodoc import sco_groups from app.scodoc import sco_groups_view @@ -123,18 +122,18 @@ def do_formsemestre_archive( ) if table_html: flash(f"Moyennes archivées le {date}", category="info") - data = "\n".join( - [ - html_sco_header.sco_header( - page_title=f"Moyennes archivées le {date}", - no_sidebar=True, - ), - f'<h2 class="fontorange">Valeurs archivées le {date}</h2>', - """<style type="text/css">table.notes_recapcomplet tr { color: rgb(185,70,0); } + data = render_template( + "sco_page.j2", + no_sidebar=True, + title=f"Moyennes archivées le {date}", + content="\n".join( + [ + f'<h2 class="fontorange">Valeurs archivées le {date}</h2>', + """<style type="text/css">table.notes_recapcomplet tr { color: rgb(185,70,0); } </style>""", - table_html, - html_sco_header.sco_footer(), - ] + table_html, + ] + ), ) PV_ARCHIVER.store( archive_id, "Tableau_moyennes.html", data, dept_id=formsemestre.dept_id @@ -254,7 +253,6 @@ enregistrés et non modifiables, on peut les retrouver ultérieurement. }">Paramétrage</a>" (accessible à l'administrateur du département).</em> </p>""", - html_sco_header.sco_footer(), ] descr = [ diff --git a/app/scodoc/sco_debouche.py b/app/scodoc/sco_debouche.py index 116c815dd..a5c97ab93 100644 --- a/app/scodoc/sco_debouche.py +++ b/app/scodoc/sco_debouche.py @@ -29,7 +29,7 @@ Rapport (table) avec dernier semestre fréquenté et débouché de chaque étudiant """ import http -from flask import url_for, g, request +from flask import g, render_template, request, url_for from app import log from app.comp import res_sem @@ -40,7 +40,6 @@ import app.scodoc.notesdb as ndb from app.scodoc.sco_exceptions import AccessDenied, ScoValueError from app.scodoc.gen_tables import GenTable from app.scodoc import safehtml -from app.scodoc import html_sco_header from app.scodoc import sco_permissions_check from app.scodoc import sco_preferences from app.scodoc import sco_tag_module @@ -78,6 +77,7 @@ def report_debouche_date(start_year=None, fmt="html"): title="""<h2 class="formsemestre">Débouchés étudiants </h2>""", fmt=fmt, with_html_headers=True, + template="sco_page_dept.j2", ) @@ -226,14 +226,16 @@ def table_debouche_etudids(etudids, keep_numeric=True): def report_debouche_ask_date(msg: str) -> str: """Formulaire demande date départ""" - return f"""{html_sco_header.sco_header()} + return render_template( + "sco_page_dept.j2", + content=f""" <h2>Table des débouchés des étudiants</h2> <form method="GET"> {msg} <input type="text" name="start_year" value="" size=10/> </form> - {html_sco_header.sco_footer()} - """ + """, + ) # ---------------------------------------------------------------------------- @@ -323,11 +325,11 @@ def itemsuivi_set_date(itemsuivi_id, item_date): return ("", 204) -def itemsuivi_set_situation(object, value): +def itemsuivi_set_situation(obj, value): """set situation""" if not sco_permissions_check.can_edit_suivi(): raise AccessDenied("Vous n'avez pas le droit d'effectuer cette opération !") - itemsuivi_id = object + itemsuivi_id = obj situation = value.strip("-_ \t") # log('itemsuivi_set_situation %s : %s' % (itemsuivi_id, situation)) cnx = ndb.GetDBConnexion() diff --git a/app/scodoc/sco_edit_formation.py b/app/scodoc/sco_edit_formation.py index 82d7d8d4e..151f83d5b 100644 --- a/app/scodoc/sco_edit_formation.py +++ b/app/scodoc/sco_edit_formation.py @@ -29,7 +29,7 @@ (portage from DTML) """ import flask -from flask import flash, g, url_for, request +from flask import flash, g, url_for, render_template, request import sqlalchemy from app import db @@ -54,7 +54,6 @@ def formation_delete(formation_id=None, dialog_confirmed=False): formation: Formation = Formation.query.get_or_404(formation_id) H = [ - html_sco_header.sco_header(page_title="Suppression d'une formation"), f"""<h2>Suppression de la formation {formation.titre} ({formation.acronyme})</h2>""", ] formsemestres = formation.formsemestres.all() @@ -85,6 +84,7 @@ def formation_delete(formation_id=None, dialog_confirmed=False): OK="Supprimer cette formation", cancel_url=url_for("notes.index_html", scodoc_dept=g.scodoc_dept), parameters={"formation_id": formation_id}, + template="sco_page_dept.j2", ) else: do_formation_delete(formation_id) @@ -95,8 +95,9 @@ def formation_delete(formation_id=None, dialog_confirmed=False): }">continuer</a></p>""" ) - H.append(html_sco_header.sco_footer()) - return "\n".join(H) + return render_template( + "sco_page-dept.j2", content="\n".join(H), title="Suppression d'une formation" + ) def do_formation_delete(formation_id): diff --git a/app/scodoc/sco_edit_module.py b/app/scodoc/sco_edit_module.py index eef881a1d..4b2c0bd66 100644 --- a/app/scodoc/sco_edit_module.py +++ b/app/scodoc/sco_edit_module.py @@ -51,7 +51,6 @@ from app.scodoc.sco_exceptions import ( ScoGenError, ScoNonEmptyFormationObject, ) -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_moduleimpl @@ -208,8 +207,8 @@ def module_delete(module_id=None): ) H = [ - html_sco_header.sco_header(page_title="Suppression d'un module"), - f"""<h2>Suppression du module {module.titre or "<em>sans titre</em>"} ({module.code})</h2>""", + f"""<h2>Suppression du module {module.titre or "<em>sans titre</em>"} + ({module.code})</h2>""", ] dest_url = url_for( @@ -227,7 +226,11 @@ def module_delete(module_id=None): cancelbutton="Annuler", ) if tf[0] == 0: - return "\n".join(H) + tf[1] + html_sco_header.sco_footer() + return render_template( + "sco_page_dept.j2", + title="Suppression d'un module", + content="\n".join(H) + tf[1], + ) elif tf[0] == -1: return flask.redirect(dest_url) else: @@ -372,16 +375,6 @@ def module_edit( """ H = [ - html_sco_header.sco_header( - page_title=page_title, - cssstyles=["libjs/jQuery-tagEditor/jquery.tag-editor.css"], - javascripts=[ - "libjs/jQuery-tagEditor/jquery.tag-editor.min.js", - "libjs/jQuery-tagEditor/jquery.caret.min.js", - "js/module_tag_editor.js", - "js/module_edit.js", - ], - ), f"""<h2>{title}</h2>""", render_template( "scodoc/help/modules.j2", @@ -780,7 +773,7 @@ def module_edit( scu.get_request_args(), descr, html_foot_markup=( - f"""<div class="sco_tag_module_edit"><span + f"""<div class="scobox sco_tag_module_edit"><span class="sco_tag_edit"><textarea data-module_id="{module_id}" class="module_tag_editor" >{','.join(sco_tag_module.module_tag_list(module_id))}</textarea></span></div> """ @@ -793,8 +786,17 @@ def module_edit( ) # if tf[0] == 0: - return ( - "\n".join(H) + return render_template( + "sco_page_dept.j2", + title=page_title, + cssstyles=["libjs/jQuery-tagEditor/jquery.tag-editor.css"], + javascripts=[ + "libjs/jQuery-tagEditor/jquery.tag-editor.min.js", + "libjs/jQuery-tagEditor/jquery.caret.min.js", + "js/module_tag_editor.js", + "js/module_edit.js", + ], + content="\n".join(H) + tf[1] + ( f""" @@ -805,8 +807,7 @@ def module_edit( """ if not create else "" - ) - + html_sco_header.sco_footer() + ), ) elif tf[0] == -1: return flask.redirect( @@ -904,9 +905,6 @@ def module_table(formation_id): raise ScoValueError("invalid formation !") formation: Formation = Formation.query.get_or_404(formation_id) H = [ - html_sco_header.sco_header( - page_title=f"Liste des modules de {formation.titre}" - ), f"""<h2>Listes des modules dans la formation {formation.titre} ({formation.acronyme}</h2> <ul class="notes_module_list"> """, @@ -926,8 +924,11 @@ def module_table(formation_id): ) H.append("</li>") H.append("</ul>") - H.append(html_sco_header.sco_footer()) - return "\n".join(H) + return render_template( + "sco_page_dept.j2", + title=f"Liste des modules de {formation.titre}", + content="\n".join(H), + ) def module_is_locked(module_id): diff --git a/app/scodoc/sco_edit_ue.py b/app/scodoc/sco_edit_ue.py index 9414a26bf..e24affef9 100644 --- a/app/scodoc/sco_edit_ue.py +++ b/app/scodoc/sco_edit_ue.py @@ -505,8 +505,11 @@ def ue_edit(ue_id=None, create=False, formation_id=None, default_semestre_idx=No else: clone_form = "" - return f""" - {html_sco_header.sco_header(page_title=title, javascripts=["js/edit_ue.js"])} + return render_template( + "sco_page_dept.j2", + title=title, + javascripts=["js/edit_ue.js"], + content=f""" <h2>{title}, (formation {formation.acronyme}, version {formation.version})</h2> <p class="help">Les UEs sont des groupes de modules dans une formation donnée, utilisés pour la validation (on calcule des moyennes par UE et applique des @@ -529,9 +532,8 @@ def ue_edit(ue_id=None, create=False, formation_id=None, default_semestre_idx=No <div id="bonus_description" class="scobox"></div> <div id="ue_list_code" class="sco_box sco_green_bg"></div> - - {html_sco_header.sco_footer()} - """ + """, + ) elif tf[0] == 1: if create: if not tf[2]["ue_code"]: diff --git a/app/scodoc/sco_evaluations.py b/app/scodoc/sco_evaluations.py index a961ecb33..400729705 100644 --- a/app/scodoc/sco_evaluations.py +++ b/app/scodoc/sco_evaluations.py @@ -486,7 +486,8 @@ def formsemestre_evaluations_cal(formsemestre_id): <div class="cal_evaluations"> { cal_html } </div> - <p>soit {nb_evals} évaluations planifiées; + <div class="scobox maxwidth"> + <p>soit {nb_evals} évaluations planifiées : </p> <ul> <li>en <span style= @@ -508,6 +509,7 @@ def formsemestre_evaluations_cal(formsemestre_id): ) }" class="stdlink">voir les délais de correction</a> </p> + </div> """, ) diff --git a/app/scodoc/sco_excel.py b/app/scodoc/sco_excel.py index 8a30e92e3..acd4293c2 100644 --- a/app/scodoc/sco_excel.py +++ b/app/scodoc/sco_excel.py @@ -825,7 +825,7 @@ def excel_feuille_listeappel( ws.append_blank_row() # bas de page (date, serveur) - dt = time.strftime("%d/%m/%Y à %Hh%M") + dt = time.strftime(scu.DATEATIME_FMT) if server_name: dt += " sur " + server_name cell_2 = ws.make_cell(("Liste éditée le " + dt), style1i) diff --git a/app/scodoc/sco_formation_recap.py b/app/scodoc/sco_formation_recap.py index 0cc10c306..71c08c9c1 100644 --- a/app/scodoc/sco_formation_recap.py +++ b/app/scodoc/sco_formation_recap.py @@ -174,7 +174,9 @@ def formation_table_recap(formation: Formation, fmt="html") -> Response: preferences=sco_preferences.SemPreferences(), table_id="formation_table_recap", ) - return tab.make_page(fmt=fmt, javascripts=["js/formation_recap.js"]) + return tab.make_page( + fmt=fmt, javascripts=["js/formation_recap.js"], template="sco_page_dept.j2" + ) def export_recap_formations_annee_scolaire(annee_scolaire): diff --git a/app/scodoc/sco_formation_versions.py b/app/scodoc/sco_formation_versions.py index 8fbf3931f..b532146c4 100644 --- a/app/scodoc/sco_formation_versions.py +++ b/app/scodoc/sco_formation_versions.py @@ -149,6 +149,7 @@ def formsemestre_associate_new_version( "formation_id": formation_id, "formsemestre_id": formsemestre_id, }, + template="sco_page_dept.j2", ) elif request.method == "POST": if formsemestre_id is not None: # pas dans le form car checkbox disabled diff --git a/app/scodoc/sco_formsemestre_edit.py b/app/scodoc/sco_formsemestre_edit.py index 1058cf7af..e607b2cd0 100644 --- a/app/scodoc/sco_formsemestre_edit.py +++ b/app/scodoc/sco_formsemestre_edit.py @@ -60,7 +60,6 @@ from app.scodoc.TrivialFormulator import TrivialFormulator from app.scodoc.sco_exceptions import AccessDenied, ScoValueError from app.scodoc.sco_permissions import Permission from app.scodoc.sco_vdi import ApoEtapeVDI -from app.scodoc import html_sco_header from app.scodoc import codes_cursus from app.scodoc import sco_edit_module from app.scodoc import sco_formsemestre @@ -80,20 +79,20 @@ def _default_sem_title(formation): def formsemestre_createwithmodules(): """Page création d'un semestre""" - H = [ - html_sco_header.sco_header( - page_title="Création d'un semestre", - javascripts=["libjs/AutoSuggest.js", "js/formsemestre_edit.js"], - cssstyles=["css/autosuggest_inquisitor.css"], - ), - """<h2>Mise en place d'un semestre de formation</h2>""", - ] + H = ["""<h2>Mise en place d'un semestre de formation</h2>"""] r = do_formsemestre_createwithmodules() - if isinstance(r, str): - H.append(r) - else: + if not isinstance(r, str): return r # response redirect - return "\n".join(H) + html_sco_header.sco_footer() + + H.append(r) + + return render_template( + "sco_page_dept.j2", + title="Création d'un semestre", + content="\n".join(H), + javascripts=["libjs/AutoSuggest.js", "js/formsemestre_edit.js"], + cssstyles=["css/autosuggest_inquisitor.css"], + ) def formsemestre_editwithmodules(formsemestre_id: int): diff --git a/app/scodoc/sco_formsemestre_status.py b/app/scodoc/sco_formsemestre_status.py index a6a0d7f32..154a55978 100755 --- a/app/scodoc/sco_formsemestre_status.py +++ b/app/scodoc/sco_formsemestre_status.py @@ -802,7 +802,7 @@ def _make_listes_sem(formsemestre: FormSemestre) -> str: })</span></h3>""" ) # - H.append('<div class="sem-groups-abs">') + H.append('<div class="sem-groups-abs space-before-18">') disable_abs: str | bool = scass.has_assiduites_disable_pref(formsemestre) show_abs: str = "hidden" if disable_abs else "" @@ -812,6 +812,8 @@ def _make_listes_sem(formsemestre: FormSemestre) -> str: groups = partition.groups.all() effectifs = {g.id: g.get_nb_inscrits() for g in groups} partition_is_empty = sum(effectifs.values()) == 0 + if partition_is_empty and (partition.is_default() or partition.is_parcours()): + continue # inutile de montrer des partitions vides non éditables H.append( f""" <div class="sem-groups-partition"> @@ -909,7 +911,9 @@ def _make_listes_sem(formsemestre: FormSemestre) -> str: ) H.append("</div>") # /sem-groups-assi - if partition_is_empty and not partition.is_default(): + if partition_is_empty and not ( + partition.is_default() or partition.is_parcours() + ): H.append( '<div class="help sem-groups-none">Aucun groupe peuplé dans cette partition' ) @@ -924,41 +928,72 @@ def _make_listes_sem(formsemestre: FormSemestre) -> str: H.append("</div>") H.append("</div>") # /sem-groups-partition + # Boite avec liens divers + autres_liens = [] if formsemestre.can_change_groups(): - H.append( - f"""<h4><a class="stdlink" + autres_liens.append( + f"""<a class="stdlink" + title="une partition est un ensemble de groupes: TD, TP, ..." href="{url_for("scolar.partition_editor", scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre.id, edit_partition=1) - }">Ajouter une partition</a></h4>""" + }">Ajouter une partition</a>""" ) # --- Formulaire importation Assiduité excel (si autorisé) if current_user.has_permission(Permission.AbsChange) and not disable_abs: - H.append( - f"""<p> + autres_liens.append( + f""" <a class="stdlink" href="{url_for('assiduites.feuille_abs_formsemestre', scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre.id)}"> Importation de l'assiduité depuis un fichier excel</a> - </p>""" + """ ) # --- Lien Traitement Justificatifs: - if ( current_user.has_permission(Permission.AbsJustifView) and current_user.has_permission(Permission.JustifValidate) and not disable_abs ): - H.append( - f"""<p> + autres_liens.append( + f""" <a class="stdlink" href="{url_for('assiduites.traitement_justificatifs', scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre.id)}"> Traitement des justificatifs d'absence</a> - </p>""" + """ + ) + + # --- Lien pour mail aux enseignants + # Construit la liste de tous les enseignants de ce semestre: + mails_enseignants = set(u.email for u in formsemestre.responsables) + for modimpl in formsemestre.modimpls_sorted: + mails_enseignants.add(sco_users.user_info(modimpl.responsable_id)["email"]) + mails_enseignants |= {u.email for u in modimpl.enseignants if u.email} + adrlist = list(mails_enseignants - {None, ""}) + if adrlist: + autres_liens.append( + f""" + <a class="stdlink" href="mailto:?cc={','.join(adrlist)}">Courrier aux { + len(adrlist)} enseignants du semestre</a> + """ + ) + + # Met le tout en boite + if autres_liens: + H.append( + f""" + <div class="sem-groups-partition sem-groups-autres-liens"> + <div class="sem-groups-none"> + <ul> + <li>{'</li><li>'.join(autres_liens)}</li> + </ul> + </div> + </div> + """ ) H.append("</div>") @@ -1033,8 +1068,9 @@ def formsemestre_status_head(formsemestre_id: int = None, page_title: str = None ) if evals["last_modif"]: H.append( - " <em>(dernière note saisie le %s)</em>" - % evals["last_modif"].strftime("%d/%m/%Y à %Hh%M") + f""" <em>(dernière note saisie le { + evals["last_modif"].strftime(scu.DATEATIME_FMT) + })</em>""" ) H.append("</td></tr>") H.append("</table>") @@ -1073,12 +1109,6 @@ def formsemestre_status(formsemestre_id=None, check_parcours=True): modimpls = formsemestre.modimpls_sorted nt = res_sem.load_formsemestre_results(formsemestre) - # Construit la liste de tous les enseignants de ce semestre: - mails_enseignants = set(u.email for u in formsemestre.responsables) - for modimpl in modimpls: - mails_enseignants.add(sco_users.user_info(modimpl.responsable_id)["email"]) - mails_enseignants |= {u.email for u in modimpl.enseignants if u.email} - can_edit = formsemestre.can_be_edited_by(current_user) can_change_all_notes = current_user.has_permission(Permission.EditAllNotes) or ( current_user.id in [resp.id for resp in formsemestre.responsables] @@ -1206,20 +1236,11 @@ def formsemestre_status(formsemestre_id=None, check_parcours=True): ) # --- LISTE DES ETUDIANTS H += [ - '<div class="formsemestre-groupes">', + '<div class="formsemestre-groupes space-before-24">', _make_listes_sem(formsemestre), "</div>", ] - # --- Lien mail enseignants: - adrlist = list(mails_enseignants - {None, ""}) - if adrlist: - H.append( - f"""<p> - <a class="stdlink" href="mailto:?cc={','.join(adrlist)}">Courrier aux { - len(adrlist)} enseignants du semestre</a> - </p>""" - ) return render_template( "sco_page.j2", content="".join(H), diff --git a/app/scodoc/sco_formsemestre_validation.py b/app/scodoc/sco_formsemestre_validation.py index dfac0461b..f211a9da6 100644 --- a/app/scodoc/sco_formsemestre_validation.py +++ b/app/scodoc/sco_formsemestre_validation.py @@ -583,6 +583,11 @@ def formsemestre_recap_parcours_table( ) is_cur = situation_etud_cursus.formsemestre_id == formsemestre.id num_sem += 1 + url_status = url_for( + "notes.formsemestre_status", + scodoc_dept=g.scodoc_dept, + formsemestre_id=formsemestre.id, + ) dpv = sco_pv_dict.dict_pvjury(formsemestre.id, etudids=[etudid]) pv = dpv["decisions"][0] @@ -642,7 +647,7 @@ def formsemestre_recap_parcours_table( H.append( f""" <td class="rcp_type_sem" style="background-color:{bgcolor};">{num_sem}{pm}</td> - <td class="datedebut">{formsemestre.mois_debut()}</td> + <td class="datedebut"><a href="{url_status}">{formsemestre.mois_debut()}</a></td> <td class="rcp_titre_sem"><a class="formsemestre_status_link" href="{ url_for("notes.formsemestre_bulletinetud", scodoc_dept=g.scodoc_dept, @@ -724,8 +729,9 @@ def formsemestre_recap_parcours_table( f"""Autre formation: {formsemestre.formation.formation_code}""" ) H.append( - '<td class="datefin">%s</td><td class="sem_info">%s</td>' - % (formsemestre.mois_fin(), sem_info.get(formsemestre.id, default_sem_info)) + f"""<td class="datefin"><a href="{url_status}">{formsemestre.mois_fin()}</a></td> + <td class="sem_info">{sem_info.get(formsemestre.id, default_sem_info)}</td> + """ ) # Moy Gen (sous le code decision) H.append( diff --git a/app/scodoc/sco_groups_exports.py b/app/scodoc/sco_groups_exports.py index ddf02d1a8..4bce85126 100644 --- a/app/scodoc/sco_groups_exports.py +++ b/app/scodoc/sco_groups_exports.py @@ -65,7 +65,7 @@ def groups_export_annotations(group_ids, formsemestre_id=None, fmt="html"): ) annotations = groups_list_annotation(groups_infos.group_ids) for annotation in annotations: - annotation["date_str"] = annotation["date"].strftime("%d/%m/%Y à %Hh%M") + annotation["date_str"] = annotation["date"].strftime(scu.DATEATIME_FMT) if fmt == "xls": columns_ids = ("etudid", "nom", "prenom", "date", "comment") else: diff --git a/app/scodoc/sco_groups_view.py b/app/scodoc/sco_groups_view.py index 598ede762..26b30918f 100644 --- a/app/scodoc/sco_groups_view.py +++ b/app/scodoc/sco_groups_view.py @@ -782,16 +782,21 @@ def groups_table( [ tab.html(), f""" - <ul> - <li><a class="stdlink" href="{tab.base_url}&fmt=xls">Table Excel</a> - </li> - <li><a class="stdlink" href="{tab.base_url}&fmt=moodlecsv">Fichier CSV pour Moodle (groupe sélectionné)</a> - </li> - <li> - <a class="stdlink" href="export_groups_as_moodle_csv?formsemestre_id={groups_infos.formsemestre_id}"> - Fichier CSV pour Moodle (tous les groupes)</a> - <em>(voir le paramétrage pour modifier le format des fichiers Moodle exportés)</em> - </li>""", + <ul> + <li><a class="stdlink" href="{tab.base_url}&fmt=xls">Table Excel + groupe(s) {groups_infos.groups_titles}</a> + </li> + <li><a class="stdlink" href="{tab.base_url}&fmt=moodlecsv">Fichier CSV pour + Moodle groupe(s) {groups_infos.groups_titles}</a> + </li> + <li> + <a class="stdlink" href="{{ + url_for('notes.export_groups_as_moodle_csv', + scodoc_dept=g.scodoc_dept, formsemestre_id=groups_infos.formsemestre_id) + }}"> + Fichier CSV pour Moodle (tous les groupes)</a> + <em>(voir le paramétrage pour modifier le format des fichiers Moodle exportés)</em> + </li>""", ] ) if amail_inst: diff --git a/app/scodoc/sco_moduleimpl_status.py b/app/scodoc/sco_moduleimpl_status.py index 2fa11e28a..139081f19 100644 --- a/app/scodoc/sco_moduleimpl_status.py +++ b/app/scodoc/sco_moduleimpl_status.py @@ -656,7 +656,7 @@ def _ligne_evaluation( if etat["last_modif"]: H.append( f"""<span class="mievr_lastmodif">(dernière modif le { - etat["last_modif"].strftime("%d/%m/%Y à %Hh%M")})</span>""" + etat["last_modif"].strftime(scu.DATEATIME_FMT)})</span>""" ) # H.append( diff --git a/app/scodoc/sco_utils.py b/app/scodoc/sco_utils.py index d189a0ffd..f75090cd6 100644 --- a/app/scodoc/sco_utils.py +++ b/app/scodoc/sco_utils.py @@ -556,7 +556,7 @@ MONTH_NAMES = ( ) DAY_NAMES = ("lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi", "dimanche") -TIME_FMT = "%H:%M" # affichage des heures +TIME_FMT = "%Hh%M" # affichage des heures DATE_FMT = "%d/%m/%Y" # affichage des dates DATEATIME_FMT = DATE_FMT + " à " + TIME_FMT DATETIME_FMT = DATE_FMT + " " + TIME_FMT @@ -1339,7 +1339,7 @@ def format_telephone(n: str | None) -> str: # def timedate_human_repr(): "representation du temps courant pour utilisateur" - return time.strftime("%d/%m/%Y à %Hh%M") + return time.strftime(DATEATIME_FMT) def annee_scolaire_repr(year, month): @@ -1525,6 +1525,7 @@ def confirm_dialog( help_msg=None, parameters: dict = None, target_variable="dialog_confirmed", + template="sco_page.j2", ): """HTML confirmation dialog: submit (POST) to same page or dest_url if given.""" parameters = parameters or {} @@ -1565,7 +1566,7 @@ def confirm_dialog( if help_msg: H.append('<p class="help">' + help_msg + "</p>") if add_headers: - return render_template("sco_page.j2", content="\n".join(H)) + return render_template(template, content="\n".join(H)) else: return "\n".join(H) diff --git a/app/static/css/scodoc.css b/app/static/css/scodoc.css index 927eebd2d..cbfba50e9 100644 --- a/app/static/css/scodoc.css +++ b/app/static/css/scodoc.css @@ -55,13 +55,21 @@ div.container { div.sco-app-content { display: flex; flex-direction: column; - margin-right: 8px; + margin-right: 12px; } .space-before-18 { margin-top: 18px; } +.space-before-24 { + margin-top: 24px; +} + +div.scobox.maxwidth { + max-width: none; +} + div.scobox { flex: 1 0 0; /* Equal width for all boxes */ @@ -748,14 +756,14 @@ div.fiche_etud { /* rgb(255,240,128); */ border: 1px solid gray; width: 910px; - padding: 10px; + padding: 24px 10px 10px 10px; margin-top: 10px; } div.menus_etud { position: absolute; - margin-left: 1px; - margin-top: 1px; + margin-left: 10px; + margin-top: 16px; } div.fiche_etud h2 { @@ -2059,6 +2067,10 @@ ul.ue_inscr_list li.etud { text-underline-offset: 3px; } +.sem-groups-autres-liens { + background-color: var(--sco-color-box-bg); +} + .sem-groups-list .stdlink, .sem-groups-list .stdlink:visited { color: rgb(0, 0, 192); diff --git a/app/templates/assiduites/pages/feuille_abs_formsemestre.j2 b/app/templates/assiduites/pages/feuille_abs_formsemestre.j2 index 236154200..c3424d54f 100644 --- a/app/templates/assiduites/pages/feuille_abs_formsemestre.j2 +++ b/app/templates/assiduites/pages/feuille_abs_formsemestre.j2 @@ -45,7 +45,7 @@ <h2 style="color: crimson;">{{titre_form}}</h2> <div class="scobox"> <div id="excel-content"> - <p class="hint">Avertissement : le fichier doit respecter le format suivant</p> + <p class="hint">Le fichier importé doit respecter le format suivant</p> <ul> <li> @@ -53,12 +53,12 @@ </li> <li class="star">colonne B : Date de début</li> <li class="star">colonne C : Date de fin</li> - <li class="opt">colonne D : État (ABS,RET,PRE, ABS si vide)</li> + <li class="opt">colonne D : État (ABS, RET, PRE), considéré ABSent si vide</li> <li class="opt">colonne E : code du module</li> </ul> <p class="hint"><span class="opt"></span> : Colonne optionnelle, les cases peuvent être vides</p> - <p class="hint"><span class="star"></span> : Formats autorisés : + <p class="hint"><span class="star"></span> : Formats de dates autorisés : <ul> <li> <pre>aaaa-mm-jjThh:mm:ss</pre> @@ -73,21 +73,23 @@ <form action="" method="post" enctype="multipart/form-data"> - <label for="type_identifiant">Type d'identifiant d'étudiant (etudid, ine, nip)</label> + <label for="type_identifiant">Type d'identifiant d'étudiant (etudid, INE, NIP)</label> <select name="type_identifiant" id="type_identifiant"> - <option value="etudid">ETUDID</option> + <option value="etudid">etudid</option> <option value="ine">INE</option> <option value="nip">NIP</option> </select> - <br> - <label for="file"> - Sélectionnez un fichier: - - </label> - <input id="file" type="file" name="file" - accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel" /> - <br> - <button type="submit">Importer</button> + <div class="space-before-18"> + <label for="file"> + Sélectionnez un fichier: + + </label> + <input id="file" type="file" name="file" + accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel" /> + </div> + <div class="space-before-18"> + <button type="submit">Importer</button> + </div> </form> </div> </div> diff --git a/app/templates/bul_head.j2 b/app/templates/bul_head.j2 index 639a72ceb..3d338fabe 100644 --- a/app/templates/bul_head.j2 +++ b/app/templates/bul_head.j2 @@ -27,7 +27,7 @@ </span> </div> <div> - <em>établi le {{time.strftime("%d/%m/%Y à %Hh%M")}} (notes sur 20)</em> + <em>établi le {{time.strftime(scu.DATEATIME_FMT)}} (notes sur 20)</em> <span class="rightjust"> <select name="version" onchange="self.location.href='{{ url_for('notes.formsemestre_bulletinetud', diff --git a/app/templates/but/bulletin_court_page.j2 b/app/templates/but/bulletin_court_page.j2 index 95180ff83..222efc499 100644 --- a/app/templates/but/bulletin_court_page.j2 +++ b/app/templates/but/bulletin_court_page.j2 @@ -158,7 +158,7 @@ </div> <div id="footer"> - Bulletin généré par ScoDoc le {{time.strftime("%d/%m/%Y à %Hh%M")}}. Explication des codes sur + Bulletin généré par ScoDoc le {{time.strftime(scu.DATEATIME_FMT)}}. Explication des codes sur <a href="https://scodoc.org/BUTCodesJury">https://scodoc.org/BUTCodesJury</a> </div> </div> diff --git a/app/templates/but/parcour_formation.j2 b/app/templates/but/parcour_formation.j2 index 91f57b4e0..ce8614e41 100644 --- a/app/templates/but/parcour_formation.j2 +++ b/app/templates/but/parcour_formation.j2 @@ -1,4 +1,4 @@ -{% extends "sco_page.j2" %} +{% extends "sco_page_dept.j2" %} {% block styles %} {{super()}} diff --git a/app/templates/but/refcomp_load.j2 b/app/templates/but/refcomp_load.j2 index b6c88cefa..b1e2ea567 100644 --- a/app/templates/but/refcomp_load.j2 +++ b/app/templates/but/refcomp_load.j2 @@ -1,5 +1,5 @@ {# -*- mode: jinja-html -*- #} -{% extends "base.j2" %} +{% extends "sco_page_dept.j2" %} {% import 'wtf.j2' as wtf %} {% block app_content %} diff --git a/app/templates/but/refcomp_show.j2 b/app/templates/but/refcomp_show.j2 index f2a460f2c..4ddfa2ce0 100644 --- a/app/templates/but/refcomp_show.j2 +++ b/app/templates/but/refcomp_show.j2 @@ -1,5 +1,5 @@ {# -*- mode: jinja-html -*- #} -{% extends "sco_page.j2" %} +{% extends "sco_page_dept.j2" %} {% block styles %} {{super()}} <link href="{{scu.STATIC_DIR}}/css/refcomp_parcours_niveaux.css" rel="stylesheet" type="text/css" /> diff --git a/app/templates/but/refcomp_table.j2 b/app/templates/but/refcomp_table.j2 index 0c7585dc0..ee956c394 100644 --- a/app/templates/but/refcomp_table.j2 +++ b/app/templates/but/refcomp_table.j2 @@ -1,5 +1,5 @@ {# -*- mode: jinja-html -*- #} -{% extends "sco_page.j2" %} +{% extends "sco_page_dept.j2" %} {% import 'wtf.j2' as wtf %} {% block app_content %} diff --git a/app/templates/but/validate_dut120.j2 b/app/templates/but/validate_dut120.j2 index 3cfe91899..fd13de8ad 100644 --- a/app/templates/but/validate_dut120.j2 +++ b/app/templates/but/validate_dut120.j2 @@ -51,7 +51,7 @@ une formation utilisant une autre version de référentiel, pensez à revalider pour l'étudiant{{etud.ne}} {{etud.html_link_fiche()|safe}} <ul> <li>DUT 120 spécialité {{formsemestre.formation.referentiel_competence.specialite_long}} - enregistré le {{time.strftime("%d/%m/%Y à %Hh%M")}} + enregistré le {{time.strftime(scu.DATEATIME_FMT)}} </li> </ul> diff --git a/app/templates/formation/ue_assoc_parcours_ects.j2 b/app/templates/formation/ue_assoc_parcours_ects.j2 index 290d0d169..c4ee778fa 100644 --- a/app/templates/formation/ue_assoc_parcours_ects.j2 +++ b/app/templates/formation/ue_assoc_parcours_ects.j2 @@ -1,5 +1,5 @@ {# Association d'ECTS à une UE par parcours #} -{% extends "sco_page.j2" %} +{% extends "sco_page_dept.j2" %} {% import 'wtf.j2' as wtf %} {% block styles %} @@ -23,18 +23,20 @@ <form method="POST"> {% for field in form %} {% if field.name != 'csrf_token' %} - <div> - <label for="{{ field.id }}">{{ field.label }}</label> - {{ field }} - {% for error in field.errors %} - <div class="error-message">{{ error }}</div> - {% endfor %} + <div class="space-before-18"> + <label for="{{ field.id }}">{{ field.label }}</label> + {{ field }} + {% for error in field.errors %} + <div class="error-message">{{ error }}</div> + {% endfor %} </div> {% endif %} {% endfor %} {{ form.csrf_token }} - <input type="submit" name="submit" value="Enregistrer"> - <input type="submit" name="cancel" value="Annuler"> + <div class="space-before-24"> + <input type="submit" name="submit" value="Enregistrer"> + <input type="submit" name="cancel" value="Annuler"> + </div> </form> {% endblock %} diff --git a/app/templates/formsemestre/bulletins_choice.j2 b/app/templates/formsemestre/bulletins_choice.j2 index db38985b1..20d5f81cf 100644 --- a/app/templates/formsemestre/bulletins_choice.j2 +++ b/app/templates/formsemestre/bulletins_choice.j2 @@ -20,6 +20,7 @@ <div class="tab-content"> <h2>{{ title }}</h2> + <div class="scobox"> <p class="help"> {{ explanation|safe }} </p> @@ -46,5 +47,6 @@ <input type="submit" value="Générer"> </div> </form> + </div> </div> {% endblock %} diff --git a/app/templates/pn/form_modules_ue_coefs.j2 b/app/templates/pn/form_modules_ue_coefs.j2 index 66ba286fc..92d316b1f 100644 --- a/app/templates/pn/form_modules_ue_coefs.j2 +++ b/app/templates/pn/form_modules_ue_coefs.j2 @@ -1,4 +1,26 @@ {# -*- mode: jinja-html -*- #} +{% extends "sco_page_dept.j2" %} + + +{% block styles %} +{{super()}} +<link rel="stylesheet" href="{{scu.STATIC_DIR}}/css/table_editor.css"> +{% endblock %} + +{% block app_content %} +<h2>Formation {{formation.titre}} ({{formation.acronyme}}) + [version {{formation.version}}] code {{formation.formation_code}} + {% if read_only %} + {{scu.icontag("lock32_img", title="verrouillé")|safe}} + {% endif %} +</h2> + +{% if read_only %} +<span class="warning"> +Formation verrouilée car un ou plusieurs semestres verrouillés l'utilisent. +</span> +{% endif %} + <h2>{% if not read_only %}Édition des c{% else %}C{%endif%}oefficients des modules vers les UEs</h2> <div class="help"> {% if not read_only %} @@ -59,8 +81,11 @@ <div class="champs_coef_hors_parcours champs_legende"></div> <div class="help">module non associé au parcours de cette UE, le coef devrait être nul.</div> </div> +{% endblock %} - +{% block scripts %} +{{super()}} +<script src="{{scu.STATIC_DIR}}/js/table_editor.js"></script> <script> var read_only = {{ "true" if read_only else "false"}}; $(function () { @@ -113,3 +138,4 @@ return true; } </script> +{% endblock %} \ No newline at end of file diff --git a/app/views/pn_modules.py b/app/views/pn_modules.py index cd9ec4db8..01f06ac87 100644 --- a/app/views/pn_modules.py +++ b/app/views/pn_modules.py @@ -31,24 +31,18 @@ PN / Edition des coefs Emmanuel Viennet, 2021 """ -from flask import url_for -from flask import g, request +from flask import g, render_template, request, url_for from flask_json import as_json from flask_login import current_user -from flask.templating import render_template -from app.scodoc.codes_cursus import UE_SPORT - from app import db, models - from app.comp import moy_ue from app.decorators import scodoc, permission_required from app.models import ApcParcours, Formation, Module -from app.views import notes_bp as bp - -from app.scodoc import html_sco_header +from app.scodoc.codes_cursus import UE_SPORT from app.scodoc import sco_utils as scu from app.scodoc.sco_permissions import Permission +from app.views import notes_bp as bp @bp.route("/table_modules_ue_coefs/<int:formation_id>") @@ -197,51 +191,23 @@ def edit_modules_ue_coefs(): formation_id=formation_id ).first_or_404() locked = formation.has_locked_sems(semestre_idx) - if locked: - lockicon = scu.icontag("lock32_img", title="verrouillé") - else: - lockicon = "" - H = [ - html_sco_header.sco_header( - cssstyles=["css/table_editor.css"], - javascripts=[ - "js/table_editor.js", - ], - page_title=f"Coefs programme {formation.acronyme}", - ), - f"""<h2>Formation {formation.titre} ({formation.acronyme}) - [version {formation.version}] code {formation.formation_code} - {lockicon} - </h2> - """, - ( - """<span class="warning">Formation verrouilée car un ou plusieurs - semestres verrouillés l'utilisent. - </span>""" - if locked - else "" - ), - render_template( - "pn/form_modules_ue_coefs.j2", - formation=formation, - data_source=url_for( - "notes.table_modules_ue_coefs", - scodoc_dept=g.scodoc_dept, - formation_id=formation_id, - semestre_idx=semestre_idx, - parcours_id=parcours_id, - ), - data_save=url_for( - "notes.set_module_ue_coef", - scodoc_dept=g.scodoc_dept, - ), - read_only=locked - or not current_user.has_permission(Permission.EditFormation), + return render_template( + "pn/form_modules_ue_coefs.j2", + formation=formation, + data_source=url_for( + "notes.table_modules_ue_coefs", + scodoc_dept=g.scodoc_dept, + formation_id=formation_id, semestre_idx=semestre_idx, - semestre_ids=range(1, formation.get_cursus().NB_SEM + 1), parcours_id=parcours_id, ), - html_sco_header.sco_footer(), - ] - - return "\n".join(H) + data_save=url_for( + "notes.set_module_ue_coef", + scodoc_dept=g.scodoc_dept, + ), + read_only=locked or not current_user.has_permission(Permission.EditFormation), + semestre_idx=semestre_idx, + semestre_ids=range(1, formation.get_cursus().NB_SEM + 1), + parcours_id=parcours_id, + title=f"Coefs programme {formation.acronyme}", + ) diff --git a/sco_version.py b/sco_version.py index b5372319f..42dab1159 100644 --- a/sco_version.py +++ b/sco_version.py @@ -1,7 +1,7 @@ # -*- mode: python -*- # -*- coding: utf-8 -*- -SCOVERSION = "9.7.6" +SCOVERSION = "9.7.7" SCONAME = "ScoDoc" -- GitLab