Compare commits

..

No commits in common. "aa9d85f4bd16998768450951159daf91ef083755" and "ef44a71e39dd38148d2499438d12d404eae9b5b7" have entirely different histories.

21 changed files with 259 additions and 241 deletions

View File

@ -56,6 +56,7 @@ from app.models import (
) )
from app.scodoc.sco_permissions import Permission from app.scodoc.sco_permissions import Permission
from app.scodoc.sco_exceptions import AccessDenied, ScoValueError, ScoTemporaryError from app.scodoc.sco_exceptions import AccessDenied, ScoValueError, ScoTemporaryError
from app.scodoc import html_sco_header
from app.scodoc import htmlutils from app.scodoc import htmlutils
from app.scodoc import sco_assiduites from app.scodoc import sco_assiduites
from app.scodoc import sco_bulletins_generator from app.scodoc import sco_bulletins_generator
@ -959,21 +960,7 @@ def formsemestre_bulletinetud(
elif fmt == "pdfmail": elif fmt == "pdfmail":
return "" return ""
H = [ H = [
render_template( _formsemestre_bulletinetud_header_html(etud, formsemestre, fmt, version),
"bul_head.j2",
etud=etud,
fmt=fmt,
formsemestre=formsemestre,
menu_autres_operations=make_menu_autres_operations(
etud=etud,
formsemestre=formsemestre,
endpoint="notes.formsemestre_bulletinetud",
version=version,
),
scu=scu,
time=time,
version=version,
),
bulletin, bulletin,
render_template( render_template(
"bul_foot.j2", "bul_foot.j2",
@ -984,18 +971,10 @@ def formsemestre_bulletinetud(
inscription_courante=etud.inscription_courante(), inscription_courante=etud.inscription_courante(),
inscription_str=etud.inscription_descr()["inscription_str"], inscription_str=etud.inscription_descr()["inscription_str"],
), ),
html_sco_header.sco_footer(),
] ]
return render_template(
"sco_page.j2", return "".join(H)
title=f"Bulletin de {etud.nomprenom}",
content="".join(H),
javascripts=[
"js/bulletin.js",
"libjs/d3.v3.min.js",
"js/radar_bulletin.js",
],
cssstyles=["css/radar_bulletin.css"],
)
def can_send_bulletin_by_mail(formsemestre_id): def can_send_bulletin_by_mail(formsemestre_id):
@ -1333,3 +1312,38 @@ def make_menu_autres_operations(
}, },
] ]
return htmlutils.make_menu("Autres opérations", menu_items, alone=True) return htmlutils.make_menu("Autres opérations", menu_items, alone=True)
def _formsemestre_bulletinetud_header_html(
etud,
formsemestre: FormSemestre,
fmt=None,
version=None,
):
H = [
html_sco_header.sco_header(
page_title=f"Bulletin de {etud.nomprenom}",
javascripts=[
"js/bulletin.js",
"libjs/d3.v3.min.js",
"js/radar_bulletin.js",
],
cssstyles=["css/radar_bulletin.css"],
),
render_template(
"bul_head.j2",
etud=etud,
fmt=fmt,
formsemestre=formsemestre,
menu_autres_operations=make_menu_autres_operations(
etud=etud,
formsemestre=formsemestre,
endpoint="notes.formsemestre_bulletinetud",
version=version,
),
scu=scu,
time=time,
version=version,
),
]
return "\n".join(H)

View File

@ -33,6 +33,7 @@ from flask_sqlalchemy.query import Query
from app import db from app import db
from app.models import Evaluation, FormSemestre, Identite, Assiduite from app.models import Evaluation, FormSemestre, Identite, Assiduite
import app.scodoc.sco_utils as scu import app.scodoc.sco_utils as scu
from app.scodoc import html_sco_header
from app.scodoc import sco_evaluations from app.scodoc import sco_evaluations
from app.scodoc import sco_evaluation_db from app.scodoc import sco_evaluation_db
from app.scodoc import sco_groups from app.scodoc import sco_groups

View File

@ -36,6 +36,7 @@ from app import db
from app.models import Departement, Identite from app.models import Departement, Identite
import app.scodoc.notesdb as ndb import app.scodoc.notesdb as ndb
from app.scodoc.gen_tables import GenTable from app.scodoc.gen_tables import GenTable
from app.scodoc import html_sco_header
from app.scodoc import sco_etud from app.scodoc import sco_etud
from app.scodoc import sco_groups from app.scodoc import sco_groups
from app.scodoc.sco_exceptions import ScoException from app.scodoc.sco_exceptions import ScoException
@ -51,7 +52,7 @@ def form_search_etud(
title="Rechercher un étudiant par nom : ", title="Rechercher un étudiant par nom : ",
add_headers=False, # complete page add_headers=False, # complete page
): ):
"form recherche par nom: utilisé pour choisir un étudiant à inscrire, par exemple" "form recherche par nom"
H = [] H = []
H.append( H.append(
f"""<form action="{ f"""<form action="{
@ -92,8 +93,10 @@ def form_search_etud(
H.append("</form>") H.append("</form>")
if add_headers: if add_headers:
return render_template( return (
"sco_page.j2", title="Choix d'un étudiant", content="\n".join(H) html_sco_header.sco_header(page_title="Choix d'un étudiant")
+ "\n".join(H)
+ html_sco_header.sco_footer()
) )
else: else:
return "\n".join(H) return "\n".join(H)

View File

@ -224,17 +224,23 @@ def menu_groups_choice(
groups_infos, groups_infos,
submit_on_change=False, submit_on_change=False,
default_deselect_others=True, default_deselect_others=True,
html_export=True,
change_event=None, # XXX ???
): ):
"""Menu pour selection groupes """menu pour selection groupes
group_ids est la liste des groupes actuellement sélectionnés group_ids est la liste des groupes actuellement sélectionnés
et doit comporter au moins un élément, sauf si formsemestre_id est spécifié. et doit comporter au moins un élément, sauf si formsemestre_id est spécifié.
(utilisé pour retrouver le semestre et proposer la liste des autres groupes) (utilisé pour retrouver le semestre et proposer la liste des autres groupes)
Si url_export : Si html_export :
selecteur.value = &group_ids=xxx&group_ids=yyy... selecteur.value = &group_ids=xxx&group_ids=yyy...
sinon : sinon :
selecteur.value = [xxx, yyy, ...] selecteur.value = [xxx, yyy, ...]
Si change_event :
met à jour l'événement onchange du selecteur
(attend du js, plus d'informations sur scu.MultiSelect.change_event)
""" """
default_group_id = sco_groups.get_default_group(groups_infos.formsemestre_id) default_group_id = sco_groups.get_default_group(groups_infos.formsemestre_id)
n_members = len(sco_groups.get_group_members(default_group_id)) n_members = len(sco_groups.get_group_members(default_group_id))
@ -272,6 +278,9 @@ def menu_groups_choice(
values=values, name="group_ids", html_id="group_ids_sel" values=values, name="group_ids", html_id="group_ids_sel"
) )
if html_export:
multi_select.export_format('return "&group_ids="+values.join("&group_ids=")')
if submit_on_change: if submit_on_change:
multi_select.change_event("submit_group_selector();") multi_select.change_event("submit_group_selector();")
@ -758,7 +767,7 @@ def groups_table(
name="options", name="options",
html_id="group_list_options", html_id="group_list_options",
) )
multi_select.change_event("change_list_options(values);") multi_select.change_event("change_list_options(event.target.value);")
H.extend( H.extend(
# ; # ;
[ [

View File

@ -31,13 +31,14 @@
import datetime import datetime
from operator import itemgetter from operator import itemgetter
from flask import url_for, g, render_template, request from flask import url_for, g, request
import app.scodoc.notesdb as ndb import app.scodoc.notesdb as ndb
import app.scodoc.sco_utils as scu import app.scodoc.sco_utils as scu
from app import db, log from app import db, log
from app.models import Formation, FormSemestre, GroupDescr, Identite from app.models import Formation, FormSemestre, GroupDescr, Identite
from app.scodoc.gen_tables import GenTable from app.scodoc.gen_tables import GenTable
from app.scodoc import html_sco_header
from app.scodoc import sco_cache from app.scodoc import sco_cache
from app.scodoc import codes_cursus from app.scodoc import codes_cursus
from app.scodoc import sco_etud from app.scodoc import sco_etud
@ -309,7 +310,12 @@ def formsemestre_inscr_passage(
# -- check lock # -- check lock
if not formsemestre.etat: if not formsemestre.etat:
raise ScoValueError("opération impossible: semestre verrouille") raise ScoValueError("opération impossible: semestre verrouille")
H = [] H = [
html_sco_header.sco_header(
page_title="Passage des étudiants",
)
]
footer = html_sco_header.sco_footer()
etuds = [] if etuds is None else etuds etuds = [] if etuds is None else etuds
if isinstance(etuds, str): if isinstance(etuds, str):
# string, vient du form de confirmation # string, vient du form de confirmation
@ -448,9 +454,8 @@ def formsemestre_inscr_passage(
) )
# #
return render_template( H.append(footer)
"sco_page.j2", title="Passage des étudiants", content="\n".join(H) return "\n".join(H)
)
def _build_page( def _build_page(

View File

@ -628,7 +628,7 @@ def fiche_etud(etudid=None):
""" """
) )
return render_template( return render_template(
"sco_page_dept.j2", "sco_page.j2",
content=tmpl % info, content=tmpl % info,
title=f"Fiche étudiant {etud.nomprenom}", title=f"Fiche étudiant {etud.nomprenom}",
cssstyles=[ cssstyles=[

View File

@ -41,6 +41,7 @@ from app.models import FormSemestre, Identite
import app.scodoc.sco_utils as scu import app.scodoc.sco_utils as scu
import app.scodoc.notesdb as ndb import app.scodoc.notesdb as ndb
from app.scodoc import html_sco_header
from app.scodoc import codes_cursus from app.scodoc import codes_cursus
from app.scodoc import sco_pv_dict from app.scodoc import sco_pv_dict
from app.scodoc import sco_etud from app.scodoc import sco_etud

View File

@ -32,7 +32,8 @@ import datetime
import time import time
from xml.etree import ElementTree from xml.etree import ElementTree
from flask import abort, g, render_template, request, url_for from flask import g, request
from flask import abort, url_for
from app import log from app import log
from app.but import bulletin_but from app.but import bulletin_but
@ -43,12 +44,14 @@ from app.models import FormSemestre
from app.models.etudiants import Identite from app.models.etudiants import Identite
import app.scodoc.sco_utils as scu import app.scodoc.sco_utils as scu
from app.scodoc import html_sco_header
from app.scodoc import sco_bulletins_json from app.scodoc import sco_bulletins_json
from app.scodoc import sco_bulletins_xml from app.scodoc import sco_bulletins_xml
from app.scodoc import sco_cache from app.scodoc import sco_cache
from app.scodoc import sco_evaluations from app.scodoc import sco_evaluations
from app.scodoc.sco_exceptions import ScoValueError from app.scodoc.sco_exceptions import ScoValueError
from app.scodoc import sco_formsemestre from app.scodoc import sco_formsemestre
from app.scodoc import sco_formsemestre_status
from app.scodoc import sco_preferences from app.scodoc import sco_preferences
from app.tables.recap import TableRecap from app.tables.recap import TableRecap
from app.tables.jury_recap import TableJury from app.tables.jury_recap import TableJury
@ -116,9 +119,15 @@ def formsemestre_recapcomplet(
) )
H = [ H = [
# sco_formsemestre_status.formsemestre_status_head( html_sco_header.sco_header(
# formsemestre_id=formsemestre_id page_title=f"{formsemestre.sem_modalite()}: "
# ), + ("jury" if mode_jury else "moyennes"),
no_sidebar=True,
javascripts=["js/table_recap.js"],
),
sco_formsemestre_status.formsemestre_status_head(
formsemestre_id=formsemestre_id
),
] ]
if len(formsemestre.inscriptions) > 0: if len(formsemestre.inscriptions) > 0:
H.append( H.append(
@ -264,17 +273,10 @@ def formsemestre_recapcomplet(
</div> </div>
""" """
) )
H.append(html_sco_header.sco_footer())
# HTML or binary data ? # HTML or binary data ?
if len(H) > 1: if len(H) > 1:
return render_template( return "".join(H)
"sco_page.j2",
content="".join(H),
title=f"{formsemestre.sem_modalite()}: "
+ ("jury" if mode_jury else "moyennes"),
javascripts=["js/table_recap.js"],
formsemestre_id=formsemestre_id,
no_sidebar=True,
)
elif len(H) == 1: elif len(H) == 1:
return H[0] return H[0]
else: else:

View File

@ -31,7 +31,7 @@ import time
import flask import flask
from flask import g, render_template, url_for from flask import g, url_for
from flask_login import current_user from flask_login import current_user
from flask_sqlalchemy.query import Query from flask_sqlalchemy.query import Query
import psycopg2 import psycopg2
@ -57,6 +57,7 @@ from app.scodoc.sco_exceptions import (
ScoInvalidParamError, ScoInvalidParamError,
ScoValueError, ScoValueError,
) )
from app.scodoc import html_sco_header
from app.scodoc import htmlutils from app.scodoc import htmlutils
from app.scodoc import sco_cache from app.scodoc import sco_cache
from app.scodoc import sco_etud from app.scodoc import sco_etud
@ -246,15 +247,14 @@ def do_evaluation_set_missing(
if len(invalids) > 0: if len(invalids) > 0:
diag = f"Valeur {value} invalide ou hors barème" diag = f"Valeur {value} invalide ou hors barème"
if diag: if diag:
return render_template( return f"""
"sco_page.j2", {html_sco_header.sco_header()}
content=f"""
<h2>{diag}</h2> <h2>{diag}</h2>
<p><a href="{ dest_url }"> <p><a href="{ dest_url }">
Recommencer</a> Recommencer</a>
</p> </p>
""", {html_sco_header.sco_footer()}
) """
# Confirm action # Confirm action
if not dialog_confirmed: if not dialog_confirmed:
plural = len(valid_notes) > 1 plural = len(valid_notes) > 1
@ -293,9 +293,8 @@ def do_evaluation_set_missing(
url=url, url=url,
max_frequency=30 * 60, max_frequency=30 * 60,
) )
return render_template( return f"""
"sco_page.j2", { html_sco_header.sco_header() }
content=f"""
<h2>{len(etudids_changed)} notes changées</h2> <h2>{len(etudids_changed)} notes changées</h2>
<ul> <ul>
<li><a class="stdlink" href="{dest_url}"> <li><a class="stdlink" href="{dest_url}">
@ -309,8 +308,8 @@ def do_evaluation_set_missing(
)}">Tableau de bord du module</a> )}">Tableau de bord du module</a>
</li> </li>
</ul> </ul>
""", { html_sco_header.sco_footer() }
) """
def evaluation_suppress_alln(evaluation_id, dialog_confirmed=False): def evaluation_suppress_alln(evaluation_id, dialog_confirmed=False):
@ -391,7 +390,7 @@ def evaluation_suppress_alln(evaluation_id, dialog_confirmed=False):
url=status_url, url=status_url,
) )
return render_template("sco_page.j2", content="\n".join(H)) return html_sco_header.sco_header() + "\n".join(H) + html_sco_header.sco_footer()
def _check_inscription( def _check_inscription(
@ -641,17 +640,16 @@ def saisie_notes(evaluation_id: int, group_ids: list = None):
# Check access # Check access
# (admin, respformation, and responsable_id) # (admin, respformation, and responsable_id)
if not evaluation.moduleimpl.can_edit_notes(current_user): if not evaluation.moduleimpl.can_edit_notes(current_user):
return render_template( return f"""
"sco_page.j2", {html_sco_header.sco_header()}
content=f"""
<h2>Modification des notes impossible pour {current_user.user_name}</h2> <h2>Modification des notes impossible pour {current_user.user_name}</h2>
<p>(vérifiez que le semestre n'est pas verrouillé et que vous <p>(vérifiez que le semestre n'est pas verrouillé et que vous
avez l'autorisation d'effectuer cette opération)</p> avez l'autorisation d'effectuer cette opération)</p>
<p><a href="{ moduleimpl_status_url }">Continuer</a> <p><a href="{ moduleimpl_status_url }">Continuer</a>
</p> </p>
""", {html_sco_header.sco_footer()}
) """
# Informations sur les groupes à afficher: # Informations sur les groupes à afficher:
groups_infos = sco_groups_view.DisplayedGroupsInfos( groups_infos = sco_groups_view.DisplayedGroupsInfos(
@ -668,6 +666,11 @@ def saisie_notes(evaluation_id: int, group_ids: list = None):
) )
# HTML page: # HTML page:
H = [ H = [
html_sco_header.sco_header(
page_title=page_title,
javascripts=sco_groups_view.JAVASCRIPTS + ["js/saisie_notes.js"],
cssstyles=sco_groups_view.CSSSTYLES,
),
sco_evaluations.evaluation_describe( sco_evaluations.evaluation_describe(
evaluation_id=evaluation_id, link_saisie=False evaluation_id=evaluation_id, link_saisie=False
), ),
@ -751,13 +754,9 @@ def saisie_notes(evaluation_id: int, group_ids: list = None):
</ul> </ul>
</div>""" </div>"""
) )
return render_template(
"sco_page.j2", H.append(html_sco_header.sco_footer())
content="\n".join(H), return "\n".join(H)
title=page_title,
javascripts=sco_groups_view.JAVASCRIPTS + ["js/saisie_notes.js"],
cssstyles=sco_groups_view.CSSSTYLES,
)
def get_sorted_etuds_notes( def get_sorted_etuds_notes(

View File

@ -31,7 +31,7 @@
import time import time
from operator import itemgetter from operator import itemgetter
from flask import g, render_template, url_for from flask import g, url_for
from flask_login import current_user from flask_login import current_user
from app import db, log from app import db, log
@ -39,6 +39,7 @@ from app.models import Admission, Adresse, FormSemestre, Identite, ScolarNews
import app.scodoc.sco_utils as scu import app.scodoc.sco_utils as scu
import app.scodoc.notesdb as ndb import app.scodoc.notesdb as ndb
from app.scodoc import html_sco_header
from app.scodoc import sco_cache from app.scodoc import sco_cache
from app.scodoc import sco_formsemestre from app.scodoc import sco_formsemestre
from app.scodoc import sco_formsemestre_inscriptions from app.scodoc import sco_formsemestre_inscriptions
@ -117,6 +118,7 @@ def formsemestre_synchro_etuds(
""", """,
safe=True, safe=True,
) )
footer = html_sco_header.sco_footer()
base_url = url_for( base_url = url_for(
"notes.formsemestre_synchro_etuds", "notes.formsemestre_synchro_etuds",
scodoc_dept=g.scodoc_dept, scodoc_dept=g.scodoc_dept,
@ -166,7 +168,7 @@ def formsemestre_synchro_etuds(
suffix=scu.XLSX_SUFFIX, suffix=scu.XLSX_SUFFIX,
) )
H = [] H = [html_sco_header.sco_header(page_title="Synchronisation étudiants")]
if not submitted: if not submitted:
H += _build_page( H += _build_page(
sem, sem,
@ -298,9 +300,8 @@ def formsemestre_synchro_etuds(
""" """
) )
return render_template( H.append(footer)
"sco_page.j2", title="Synchronisation des étudiants", content="\n".join(H) return "\n".join(H)
)
def _build_page( def _build_page(

View File

@ -55,7 +55,7 @@ from pytz import timezone
import flask import flask
from flask import g, render_template, request, Response from flask import g, request, Response
from flask import flash, make_response from flask import flash, make_response
from flask_json import json_response from flask_json import json_response
from werkzeug.http import HTTP_STATUS_CODES from werkzeug.http import HTTP_STATUS_CODES
@ -1527,6 +1527,8 @@ def confirm_dialog(
target_variable="dialog_confirmed", target_variable="dialog_confirmed",
): ):
"""HTML confirmation dialog: submit (POST) to same page or dest_url if given.""" """HTML confirmation dialog: submit (POST) to same page or dest_url if given."""
from app.scodoc import html_sco_header
parameters = parameters or {} parameters = parameters or {}
# dialog de confirmation simple # dialog de confirmation simple
parameters[target_variable] = 1 parameters[target_variable] = 1
@ -1565,7 +1567,9 @@ def confirm_dialog(
if help_msg: if help_msg:
H.append('<p class="help">' + help_msg + "</p>") H.append('<p class="help">' + help_msg + "</p>")
if add_headers: if add_headers:
return render_template("sco_page.j2", content="\n".join(H)) return (
html_sco_header.sco_header() + "\n".join(H) + html_sco_header.sco_footer()
)
else: else:
return "\n".join(H) return "\n".join(H)

View File

@ -58,10 +58,6 @@ div.sco-app-content {
margin-right: 8px; margin-right: 8px;
} }
.space-before-18 {
margin-top: 18px;
}
div.scobox { div.scobox {
flex: 1 0 0; flex: 1 0 0;
/* Equal width for all boxes */ /* Equal width for all boxes */
@ -2367,6 +2363,8 @@ span.eval_coef_ue {
margin-right: 2em; margin-right: 2em;
} }
span.eval_coef_ue_titre {}
/* Inscriptions modules/UE */ /* Inscriptions modules/UE */
div.list_but_ue_inscriptions { div.list_but_ue_inscriptions {
margin-top: 16px; margin-top: 16px;
@ -4260,7 +4258,6 @@ div.apo_csv_status {
.form_apo_export input[type="submit"] { .form_apo_export input[type="submit"] {
-webkit-appearance: button; -webkit-appearance: button;
appearance: button;
font-size: 150%; font-size: 150%;
font-weight: bold; font-weight: bold;
color: green; color: green;

View File

@ -23,14 +23,7 @@ function groups_view_url() {
urlParams.delete("group_ids"); urlParams.delete("group_ids");
// ajout des groupes selectionnes // ajout des groupes selectionnes
var selected_groups = document.getElementById("group_ids_sel").value; var selected_groups = document.getElementById("group_ids_sel").value;
if (Array.isArray(selected_groups)) { url.search = urlParams.toString() + selected_groups;
selected_groups.forEach((value) => {
urlParams.append("group_ids", value);
});
} else {
urlParams.set("group_ids", selected_groups);
}
url.search = urlParams.toString();
return url.href; return url.href;
} }
@ -68,13 +61,11 @@ function change_list_options(selected_options) {
// Menu choix groupe: // Menu choix groupe:
function toggle_visible_etuds() { function toggle_visible_etuds() {
// //
document.querySelectorAll(".etud_elem").forEach((element) => { document.querySelectorAll('.etud_elem').forEach(element => {
element.style.display = "none"; element.style.display = 'none';
}); });
var qargs = ""; var qargs = "";
var selectedOptions = document.querySelectorAll( var selectedOptions = document.querySelectorAll("#group_ids_sel option:checked");
"#group_ids_sel option:checked"
);
var qargs = ""; var qargs = "";
selectedOptions.forEach(function (opt) { selectedOptions.forEach(function (opt) {
var group_id = opt.value; var group_id = opt.value;
@ -88,9 +79,7 @@ function toggle_visible_etuds() {
let input_eval = document.querySelectorAll("#formnotes_evaluation_id"); let input_eval = document.querySelectorAll("#formnotes_evaluation_id");
if (input_eval.length > 0) { if (input_eval.length > 0) {
let evaluation_id = input_eval[0].value; let evaluation_id = input_eval[0].value;
let menu_saisie_tableur_a = document.querySelector( let menu_saisie_tableur_a = document.querySelector("#menu_saisie_tableur a");
"#menu_saisie_tableur a"
);
menu_saisie_tableur_a.setAttribute( menu_saisie_tableur_a.setAttribute(
"href", "href",
"saisie_notes_tableur?evaluation_id=" + evaluation_id + qargs "saisie_notes_tableur?evaluation_id=" + evaluation_id + qargs

View File

@ -20,8 +20,7 @@
<multi-select>.values() => ["val1",...] <multi-select>.values() => ["val1",...]
<multi-select>.values(["val1",...]) => // sélectionne les options correspondantes (ne vérifie pas les options "single") <multi-select>.values(["val1",...]) => // sélectionne les options correspondantes (ne vérifie pas les options "single")
<multi-select>.on((values) => {}) => // écoute le changement de valeur <multi-select>.on("change", (values) => {}) => // écoute le changement de valeur
<multi-select>.format((values)=>{}) // modifie les valeurs avant d'être envoyées / récupérées. values est un tableau des valeurs des options sélectionnées
*/ */
class MultiSelect extends HTMLElement { class MultiSelect extends HTMLElement {
@ -248,6 +247,8 @@ class MultiSelect extends HTMLElement {
(checkbox) => checkbox.checked (checkbox) => checkbox.checked
); );
const values = checkedBoxes.map((checkbox) => checkbox.value);
const opts = checkedBoxes.map((checkbox) => { const opts = checkedBoxes.map((checkbox) => {
return this.querySelector(`option[value="${checkbox.value}"]`); return this.querySelector(`option[value="${checkbox.value}"]`);
}); });
@ -262,21 +263,6 @@ class MultiSelect extends HTMLElement {
btn.textContent = `${checkedBoxes.length} sélections`; btn.textContent = `${checkedBoxes.length} sélections`;
} }
this.dispatchEvent(new Event("change")); this.dispatchEvent(new Event("change"));
// create a FormData object
const fd = new FormData();
const values = this._values();
// check if values is an array
if (Array.isArray(values)) {
values.forEach((value) => {
fd.append(this.name, value);
});
} else {
fd.append(this.name, values);
}
// update the form values
this._internals.setFormValue(fd);
} }
_values(newValues = null) { _values(newValues = null) {
@ -298,6 +284,7 @@ class MultiSelect extends HTMLElement {
checkbox.checked = newValues.includes(checkbox.value); checkbox.checked = newValues.includes(checkbox.value);
}); });
this._internals.setFormValue(this._values());
this._updateSelect(); this._updateSelect();
} }
} }
@ -311,9 +298,7 @@ class MultiSelect extends HTMLElement {
} }
on(callback) { on(callback) {
this.addEventListener("change", () => { this.addEventListener("change", callback);
callback(this._values());
});
} }
format(callback) { format(callback) {

View File

@ -6,7 +6,7 @@
<h2>Système de gestion scolarité</h2> <h2>Système de gestion scolarité</h2>
<p>&copy; Emmanuel Viennet 2024</p> <p>&copy; Emmanuel Viennet 2023</p>
<p>Version {{ version }}</p> <p>Version {{ version }}</p>

View File

@ -1,5 +1,6 @@
{# -*- mode: jinja-html -*- #} {# -*- mode: jinja-html -*- #}
{# L'en-tête des bulletins HTML #} {# L'en-tête des bulletins HTML #}
{# was _formsemestre_bulletinetud_header_html #}
<div class="bull_head"> <div class="bull_head">
<div class="bull_head_text"> <div class="bull_head_text">

View File

@ -23,6 +23,7 @@
id="feuille_emargement" id="feuille_emargement"
action="{{request.base_url}}" action="{{request.base_url}}"
method="post" method="post"
onsubmit="serializeGroupIds(event)"
> >
{{ form.hidden_tag() }} {{ form.hidden_tag() }}
<div class="infos-button">Groupes&nbsp;: {{grp|safe}}</div> <div class="infos-button">Groupes&nbsp;: {{grp|safe}}</div>
@ -55,4 +56,24 @@
{% include "sco_timepicker.j2" %} {% include "sco_timepicker.j2" %}
<script src="{{scu.STATIC_DIR}}/js/groups_view.js"></script> <script src="{{scu.STATIC_DIR}}/js/groups_view.js"></script>
<script src="{{scu.STATIC_DIR}}/libjs/purl.js"></script> <script src="{{scu.STATIC_DIR}}/libjs/purl.js"></script>
<script>
function serializeGroupIds(event) {
// Dealing with multiselect
event.preventDefault();
var form = document.getElementById("feuille_emargement");
var groupIdsField = form.elements["group_ids"];
// Check if the group_ids field exists and is an array
if (groupIdsField && Array.isArray(groupIdsField.value)) {
// Convert the array to a comma-separated string
var serializedValue = groupIdsField.value.join(',');
// Replace the field's value with the serialized string
groupIdsField.value = serializedValue;
}
// Now submit the form
form.submit();
}
</script>
{% endblock scripts %} {% endblock scripts %}

View File

@ -24,7 +24,8 @@
# #
############################################################################## ##############################################################################
"""Vues assiduité""" """Vues assiduité
"""
import datetime import datetime
import json import json
@ -1166,7 +1167,7 @@ def signal_assiduites_group():
formsemestre_date_fin=str(formsemestre.date_fin), formsemestre_date_fin=str(formsemestre.date_fin),
formsemestre_id=formsemestre_id, formsemestre_id=formsemestre_id,
gr_tit=gr_tit, gr_tit=gr_tit,
grp=sco_groups_view.menu_groups_choice(groups_infos), grp=sco_groups_view.menu_groups_choice(groups_infos, html_export=False),
minitimeline=_mini_timeline(), minitimeline=_mini_timeline(),
moduleimpl_select=_module_selector(formsemestre, moduleimpl_id), moduleimpl_select=_module_selector(formsemestre, moduleimpl_id),
nonworkdays=_non_work_days(), nonworkdays=_non_work_days(),

View File

@ -41,11 +41,11 @@ def formulaire_feuille_appel(formsemestre_id: int):
group_ids: list[int] = request.args.getlist("group_ids") group_ids: list[int] = request.args.getlist("group_ids")
data = {"group_ids": group_ids} data = {"group_ids": group_ids}
else: else:
group_ids_list = request.form.getlist("group_ids") group_ids_str = request.form.get("group_ids")
try: try:
group_ids = [int(gid) for gid in group_ids_list if gid] group_ids = [int(gid) for gid in group_ids_str.split(",") if gid]
except ValueError as exc: except ValueError as exc:
log(f"formulaire_feuille_appel: group_ids invalide: {group_ids_list[:100]}") log(f"formulaire_feuille_appel: group_ids invalide: {group_ids_str[:100]}")
raise ScoValueError("groupes invalides") from exc raise ScoValueError("groupes invalides") from exc
data = {} data = {}
@ -81,6 +81,6 @@ def formulaire_feuille_appel(formsemestre_id: int):
sco_data=ScoData(formsemestre=formsemestre), sco_data=ScoData(formsemestre=formsemestre),
form=form, form=form,
group_name=groups_infos.groups_titles, group_name=groups_infos.groups_titles,
grp=menu_groups_choice(groups_infos), grp=menu_groups_choice(groups_infos, html_export=False),
formsemestre_id=formsemestre_id, formsemestre_id=formsemestre_id,
) )

View File

@ -30,7 +30,6 @@ Module notes: issu de ScoDoc7 / ZNotes.py
Emmanuel Viennet, 2021 Emmanuel Viennet, 2021
""" """
import html import html
from operator import itemgetter from operator import itemgetter
import time import time
@ -42,7 +41,7 @@ from flask_login import current_user
from flask_wtf import FlaskForm from flask_wtf import FlaskForm
from flask_wtf.file import FileAllowed from flask_wtf.file import FileAllowed
from wtforms.validators import DataRequired, Length from wtforms.validators import DataRequired, Length
from wtforms import FileField, StringField, SubmitField from wtforms import FileField, HiddenField, StringField, SubmitField
from app import db, log, send_scodoc_alarm from app import db, log, send_scodoc_alarm
from app import models from app import models
@ -945,10 +944,10 @@ def edit_enseignants_form(moduleimpl_id):
modimpl.can_change_ens(raise_exc=True) modimpl.can_change_ens(raise_exc=True)
# #
page_title = f"Enseignants du module {modimpl.module.titre or modimpl.module.code}" page_title = f"Enseignants du module {modimpl.module.titre or modimpl.module.code}"
title = f"""<h2>Enseignants du <a class="stdlink" href="{ title = f"""Enseignants du <a href="{
url_for("notes.moduleimpl_status", url_for("notes.moduleimpl_status",
scodoc_dept=g.scodoc_dept, moduleimpl_id=modimpl.id) scodoc_dept=g.scodoc_dept, moduleimpl_id=modimpl.id)
}">module {modimpl.module.titre or modimpl.module.code}</a></h2>""" }">module {modimpl.module.titre or modimpl.module.code}</a>"""
# Liste des enseignants avec forme pour affichage / saisie avec suggestion # Liste des enseignants avec forme pour affichage / saisie avec suggestion
userlist = sco_users.get_user_list() userlist = sco_users.get_user_list()
uid2display = {} # uid : forme pour affichage = "NOM Prenom (login)"(login)" uid2display = {} # uid : forme pour affichage = "NOM Prenom (login)"(login)"
@ -973,8 +972,7 @@ def edit_enseignants_form(moduleimpl_id):
</li>""" </li>"""
) )
H.append("</ul>") H.append("</ul>")
F = f"""<div class="help space-before-18"> F = f"""<p class="help">Les enseignants d'un module ont le droit de
<p>Les enseignants d'un module ont le droit de
saisir et modifier toutes les notes des évaluations de ce module. saisir et modifier toutes les notes des évaluations de ce module.
</p> </p>
<p class="help">Pour changer le responsable du module, passez par la <p class="help">Pour changer le responsable du module, passez par la
@ -984,7 +982,6 @@ def edit_enseignants_form(moduleimpl_id):
}">Modification du semestre</a>", }">Modification du semestre</a>",
accessible uniquement au responsable de la formation (chef de département) accessible uniquement au responsable de la formation (chef de département)
</p> </p>
</div>
""" """
modform = [ modform = [
@ -1021,7 +1018,7 @@ def edit_enseignants_form(moduleimpl_id):
return render_template( return render_template(
"sco_page.j2", "sco_page.j2",
title=page_title, title=page_title,
content=title + "\n".join(H) + tf[1] + F, content=title + "\n".join(H) + tf[1],
javascripts=["libjs/AutoSuggest.js"], javascripts=["libjs/AutoSuggest.js"],
cssstyles=["css/autosuggest_inquisitor.css"], cssstyles=["css/autosuggest_inquisitor.css"],
) )
@ -1064,7 +1061,7 @@ def edit_enseignants_form(moduleimpl_id):
return render_template( return render_template(
"sco_page.j2", "sco_page.j2",
title=page_title, title=page_title,
content=title + "\n".join(H) + tf[1] + F, content=title + "\n".join(H) + tf[1],
javascripts=["libjs/AutoSuggest.js"], javascripts=["libjs/AutoSuggest.js"],
cssstyles=["css/autosuggest_inquisitor.css"], cssstyles=["css/autosuggest_inquisitor.css"],
) )
@ -2570,6 +2567,7 @@ def check_sem_integrity(formsemestre_id, fix=False):
modimpl["mod"] = mod modimpl["mod"] = mod
H = [ H = [
html_sco_header.sco_header(),
"<p>formation_id=%s" % sem["formation_id"], "<p>formation_id=%s" % sem["formation_id"],
] ]
if bad_ue: if bad_ue:
@ -2607,7 +2605,7 @@ def check_sem_integrity(formsemestre_id, fix=False):
else: else:
H.append("""<p class="alert">Problème détecté !</p>""") H.append("""<p class="alert">Problème détecté !</p>""")
return render_template("sco_page.j2", content="\n".join(H)) return "\n".join(H) + html_sco_header.sco_footer()
@bp.route("/check_form_integrity") @bp.route("/check_form_integrity")

View File

@ -82,6 +82,7 @@ from app.scodoc.TrivialFormulator import TrivialFormulator, tf_error_message
from app.scodoc.gen_tables import GenTable from app.scodoc.gen_tables import GenTable
from app.scodoc import ( from app.scodoc import (
codes_cursus, codes_cursus,
html_sco_header,
sco_import_etuds, sco_import_etuds,
sco_archives_etud, sco_archives_etud,
sco_bug_report, sco_bug_report,
@ -826,7 +827,9 @@ def form_change_coordonnees(etudid):
else: else:
adr = {} # no data for this student adr = {} # no data for this student
H = [ H = [
f""" f"""{html_sco_header.sco_header(
page_title=f"Changement coordonnées de {etud.nomprenom}"
)}
<h2>Changement des coordonnées de {etud.nomprenom}</h2> <h2>Changement des coordonnées de {etud.nomprenom}</h2>
<p>""" <p>"""
] ]
@ -870,11 +873,7 @@ def form_change_coordonnees(etudid):
) )
dest_url = url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid) dest_url = url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid)
if tf[0] == 0: if tf[0] == 0:
return render_template( return "\n".join(H) + tf[1] + html_sco_header.sco_footer()
"sco_page_dept.j2",
title=f"Changement coordonnées de {etud.nomprenom}",
content="\n".join(H) + tf[1],
)
elif tf[0] == -1: elif tf[0] == -1:
return flask.redirect(dest_url) return flask.redirect(dest_url)
else: else:
@ -1005,14 +1004,17 @@ def students_groups_auto_assignment(formsemestre_id: int):
"""Répartition auto des groupes""" """Répartition auto des groupes"""
formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id) formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id)
H = [ H = [
html_sco_header.sco_header(
page_title="Répartition des groupes",
),
render_template( render_template(
"scolar/students_groups_auto_assignment.j2", "scolar/students_groups_auto_assignment.j2",
formsemestre=formsemestre, formsemestre=formsemestre,
), ),
html_sco_header.sco_footer(),
] ]
return render_template(
"sco_page.j2", title="Répartition des groupes", content="\n".join(H) return "\n".join(H)
)
@bp.route("/create_partition_parcours", methods=["GET", "POST"]) @bp.route("/create_partition_parcours", methods=["GET", "POST"])
@ -1047,17 +1049,15 @@ sco_publish("/etud_photo_html", sco_photos.etud_photo_html, Permission.ScoView)
def etud_photo_orig_page(etudid): def etud_photo_orig_page(etudid):
"Page with photo in orig. size" "Page with photo in orig. size"
etud = Identite.get_etud(etudid) etud = Identite.get_etud(etudid)
return render_template( return f"""{
"sco_page_dept.j2", html_sco_header.sco_header(etudid=etud.id, page_title=etud.nomprenom)
title=f"Photo de {etud.nomprenom}", }
content=f"""
<h2>{etud.nomprenom}</h2> <h2>{etud.nomprenom}</h2>
<div> <div>
<a href="{etud.url_fiche()}">{etud.photo_html(size='orig')}</a> <a href="{etud.url_fiche()}">{etud.photo_html(size='orig')}</a>
</div> </div>
""", {html_sco_header.sco_footer()}
sco=ScoData(etud=etud), """
)
@bp.route("/form_change_photo", methods=["GET", "POST"]) @bp.route("/form_change_photo", methods=["GET", "POST"])
@ -1072,8 +1072,8 @@ def form_change_photo(etudid=None):
else: else:
photo_loc = "externe" photo_loc = "externe"
H = [ H = [
html_sco_header.sco_header(page_title="Changement de photo"),
f"""<h2>Changement de la photo de {etud.nomprenom}</h2> f"""<h2>Changement de la photo de {etud.nomprenom}</h2>
<p>Photo actuelle ({photo_loc}): <p>Photo actuelle ({photo_loc}):
{sco_photos.etud_photo_html(etudid=etud.id, title="photo actuelle")} {sco_photos.etud_photo_html(etudid=etud.id, title="photo actuelle")}
</p> </p>
@ -1098,17 +1098,16 @@ def form_change_photo(etudid=None):
) )
dest_url = url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etud.id) dest_url = url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etud.id)
if tf[0] == 0: if tf[0] == 0:
return render_template( return (
"sco_page_dept.j2", "\n".join(H)
title="Changement de photo",
content="\n".join(H)
+ f""" + f"""
{tf[1]} {tf[1]}
<div class=""><a class="stdlink" href="{ <p><a class="stdlink" href="{
url_for("scolar.form_suppress_photo", url_for("scolar.form_suppress_photo",
scodoc_dept=g.scodoc_dept, etudid=etud.id) scodoc_dept=g.scodoc_dept, etudid=etud.id)
}">Supprimer cette photo</a></div> }">Supprimer cette photo</a></p>
""", {html_sco_header.sco_footer()}
"""
) )
elif tf[0] == -1: elif tf[0] == -1:
return flask.redirect(dest_url) return flask.redirect(dest_url)
@ -1121,9 +1120,7 @@ def form_change_photo(etudid=None):
return flask.redirect(dest_url) return flask.redirect(dest_url)
else: else:
H.append(f"""<p class="warning">Erreur: {err_msg}</p>""") H.append(f"""<p class="warning">Erreur: {err_msg}</p>""")
return render_template( return "\n".join(H) + html_sco_header.sco_footer()
"sco_page_dept.j2", title="Changement de photo", content="\n".join(H)
)
@bp.route("/form_suppress_photo", methods=["POST", "GET"]) @bp.route("/form_suppress_photo", methods=["POST", "GET"])
@ -1194,11 +1191,12 @@ def _form_dem_of_def(
raise ScoValueError("Modification impossible: semestre verrouille") raise ScoValueError("Modification impossible: semestre verrouille")
nowdmy = time.strftime(scu.DATE_FMT) nowdmy = time.strftime(scu.DATE_FMT)
# #
header = html_sco_header.sco_header(
page_title=f"""{operation_name} de {etud.nomprenom} (du semestre {formsemestre.titre_mois()})"""
)
validations_descr = formsemestre.etud_validations_description_html(etudid) validations_descr = formsemestre.etud_validations_description_html(etudid)
return render_template( return f"""
"sco_page_dept.j2", {header}
title=f"""{operation_name} de {etud.nomprenom} (du semestre {formsemestre.titre_mois()})""",
content=f"""
<h2><font color="#FF0000">{operation_name} de</font> {etud.nomprenom} ({formsemestre.titre_mois()})</h2> <h2><font color="#FF0000">{operation_name} de</font> {etud.nomprenom} ({formsemestre.titre_mois()})</h2>
<form action="{operation_method}" method="get"> <form action="{operation_method}" method="get">
@ -1218,8 +1216,8 @@ def _form_dem_of_def(
formsemestre_id=formsemestre_id, etudid=etudid) formsemestre_id=formsemestre_id, etudid=etudid)
+ '">modifier ces décisions</a></p>') if validations_descr else ""} + '">modifier ces décisions</a></p>') if validations_descr else ""}
</div> </div>
""", {html_sco_header.sco_footer()}
) """
@bp.route("/do_dem_etudiant") @bp.route("/do_dem_etudiant")
@ -1407,7 +1405,8 @@ def _validate_date_naissance(val: str, field) -> bool:
def _etudident_create_or_edit_form(edit): def _etudident_create_or_edit_form(edit):
"Le formulaire HTML" "Le formulaire HTML"
H = [] H = [html_sco_header.sco_header()]
F = html_sco_header.sco_footer()
vals = scu.get_request_args() vals = scu.get_request_args()
etudid = vals.get("etudid", None) etudid = vals.get("etudid", None)
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
@ -1768,12 +1767,11 @@ def _etudident_create_or_edit_form(edit):
cancelbutton="Re-interroger Apogee", cancelbutton="Re-interroger Apogee",
initvalues=initvalues, initvalues=initvalues,
) )
if tf[0] in (0, -1): if tf[0] == 0:
return render_template( return "\n".join(H) + tf[1] + "<p>" + A + F
"sco_page_dept.j2", elif tf[0] == -1:
content="\n".join(H) + tf[1] + "<p>" + A, return "\n".join(H) + tf[1] + "<p>" + A + F
title="Création/édition d'étudiant", # return '\n'.join(H) + '<h4>annulation</h4>' + F
)
else: else:
# form submission # form submission
if edit: if edit:
@ -1785,14 +1783,13 @@ def _etudident_create_or_edit_form(edit):
) )
nb_homonyms = len(homonyms) nb_homonyms = len(homonyms)
if not ok: if not ok:
return render_template( return (
"sco_page_dept.j2", "\n".join(H)
content="\n".join(H)
+ tf_error_message("Nom ou prénom invalide") + tf_error_message("Nom ou prénom invalide")
+ tf[1] + tf[1]
+ "<p>" + "<p>"
+ A, + A
title="Création/édition d'étudiant", + F
) )
if not tf[2]["dont_check_homonyms"] and nb_homonyms > 0: if not tf[2]["dont_check_homonyms"] and nb_homonyms > 0:
homonyms_html = f""" homonyms_html = f"""
@ -1804,10 +1801,7 @@ def _etudident_create_or_edit_form(edit):
</ul> </ul>
</div> </div>
""" """
return render_template( return (
"sco_page_dept.j2",
title="Création/édition d'étudiant",
content=(
"\n".join(H) "\n".join(H)
+ tf_error_message( + tf_error_message(
"""Attention: il y a déjà un étudiant portant des noms et prénoms proches """Attention: il y a déjà un étudiant portant des noms et prénoms proches
@ -1820,7 +1814,7 @@ def _etudident_create_or_edit_form(edit):
+ "<p>" + "<p>"
+ A + A
+ homonyms_html + homonyms_html
), + F
) )
tf[2]["date_naissance"] = ( tf[2]["date_naissance"] = (
scu.convert_fr_date(tf[2]["date_naissance"]) scu.convert_fr_date(tf[2]["date_naissance"])
@ -2179,6 +2173,7 @@ def form_students_import_excel(formsemestre_id=None):
if sem and not sem["etat"]: if sem and not sem["etat"]:
raise ScoValueError("Modification impossible: semestre verrouille") raise ScoValueError("Modification impossible: semestre verrouille")
H = [ H = [
html_sco_header.sco_header(page_title="Import etudiants"),
"""<h2 class="formsemestre">Téléchargement d\'une nouvelle liste d\'etudiants</h2> """<h2 class="formsemestre">Téléchargement d\'une nouvelle liste d\'etudiants</h2>
<div style="color: red"> <div style="color: red">
<p>A utiliser pour importer de <b>nouveaux</b> étudiants (typiquement au <p>A utiliser pour importer de <b>nouveaux</b> étudiants (typiquement au
@ -2234,6 +2229,7 @@ def form_students_import_excel(formsemestre_id=None):
<li>""" <li>"""
) )
F = html_sco_header.sco_footer()
tf = TrivialFormulator( tf = TrivialFormulator(
request.base_url, request.base_url,
scu.get_request_args(), scu.get_request_args(),
@ -2289,11 +2285,7 @@ Les champs avec un astérisque (*) doivent être présents (nulls non autorisés
% (t[0], t[1], t[4], ast) % (t[0], t[1], t[4], ast)
) )
if tf[0] == 0: if tf[0] == 0:
return render_template( return "\n".join(H) + tf[1] + "</li></ol>" + "\n".join(S) + F
"sco_page.j2",
title="Import etudiants",
content="\n".join(H) + tf[1] + "</li></ol>" + "\n".join(S),
)
elif tf[0] == -1: elif tf[0] == -1:
return flask.redirect(dest_url) return flask.redirect(dest_url)
else: else:
@ -2353,13 +2345,14 @@ def import_generate_admission_sample(formsemestre_id):
def form_students_import_infos_admissions(formsemestre_id=None): def form_students_import_infos_admissions(formsemestre_id=None):
"formulaire import xls" "formulaire import xls"
authuser = current_user authuser = current_user
F = html_sco_header.sco_footer()
if not authuser.has_permission(Permission.EtudInscrit): if not authuser.has_permission(Permission.EtudInscrit):
# autorise juste l'export # autorise juste l'export
return render_template( H = [
"sco_page.j2", html_sco_header.sco_header(
title="Export données admissions (Parcoursup ou autre)", page_title="Export données admissions (Parcoursup ou autre)",
content=f""" ),
<h2 class="formsemestre">Téléchargement des informations sur l'admission f"""<h2 class="formsemestre">Téléchargement des informations sur l'admission
des étudiants</h2> des étudiants</h2>
<p> <p>
<a href="{ url_for('scolar.import_generate_admission_sample', <a href="{ url_for('scolar.import_generate_admission_sample',
@ -2369,10 +2362,12 @@ def form_students_import_infos_admissions(formsemestre_id=None):
</p> </p>
<p class="warning">Vous n'avez pas le droit d'importer les données</p> <p class="warning">Vous n'avez pas le droit d'importer les données</p>
""", """,
) ]
return "\n".join(H) + F
# On a le droit d'importer: # On a le droit d'importer:
H = [ H = [
html_sco_header.sco_header(page_title="Import données admissions Parcoursup"),
f"""<h2 class="formsemestre">Téléchargement des informations sur l'admission des étudiants f"""<h2 class="formsemestre">Téléchargement des informations sur l'admission des étudiants
depuis feuilles import Parcoursup</h2> depuis feuilles import Parcoursup</h2>
<div style="color: red"> <div style="color: red">
@ -2456,11 +2451,7 @@ def form_students_import_infos_admissions(formsemestre_id=None):
) )
if tf[0] == 0: if tf[0] == 0:
return render_template( return "\n".join(H) + tf[1] + help_text + F
"sco_page.j2",
title="Import données admissions Parcoursup",
content="\n".join(H) + tf[1] + help_text,
)
elif tf[0] == -1: elif tf[0] == -1:
return flask.redirect( return flask.redirect(
url_for( url_for(
@ -2591,15 +2582,13 @@ def sco_dump_and_send_db(message="", request_url="", traceback_str_base64=""):
Merci de contacter <a href="mailto:{scu.SCO_DEV_MAIL}">{scu.SCO_DEV_MAIL}</a> Merci de contacter <a href="mailto:{scu.SCO_DEV_MAIL}">{scu.SCO_DEV_MAIL}</a>
""" """
H = [] H = [html_sco_header.sco_header(page_title="Assistance technique")]
if status_code == requests.codes.OK: # pylint: disable=no-member if status_code == requests.codes.OK: # pylint: disable=no-member
H.append(f"""<p>Opération effectuée.</p><p>{r_msg}</p>""") H.append(f"""<p>Opération effectuée.</p><p>{r_msg}</p>""")
else: else:
H.append(f"""<p class="warning">{r_msg}</p>""") H.append(f"""<p class="warning">{r_msg}</p>""")
flash("Données envoyées au serveur d'assistance") flash("Données envoyées au serveur d'assistance")
return render_template( return "\n".join(H) + html_sco_header.sco_footer()
"sco_page_dept.j2", title="Assistance technique", content="\n".join(H)
)
# --- Report form (assistance) # --- Report form (assistance)
@ -2627,14 +2616,12 @@ def sco_bug_report_form():
<a href="mailto:{scu.SCO_DEV_MAIL}">{scu.SCO_DEV_MAIL}</a> <a href="mailto:{scu.SCO_DEV_MAIL}">{scu.SCO_DEV_MAIL}</a>
""" """
H = [] H = [html_sco_header.sco_header(page_title="Assistance technique")]
if r.status_code >= 200 and r.status_code < 300: if r.status_code >= 200 and r.status_code < 300:
H.append(f"""<p>Opération effectuée.</p><p>{r_msg}</p>""") H.append(f"""<p>Opération effectuée.</p><p>{r_msg}</p>""")
else: else:
H.append(f"""<p class="warning">{r_msg}</p>""") H.append(f"""<p class="warning">{r_msg}</p>""")
return render_template( return "\n".join(H) + html_sco_header.sco_footer()
"sco_page_dept.j2", title="Assistance technique", content="\n".join(H)
)
return render_template( return render_template(
"sco_bug_report.j2", "sco_bug_report.j2",