forked from ScoDoc/ScoDoc
Compare commits
10 Commits
37c93c8524
...
cf174cdc18
Author | SHA1 | Date | |
---|---|---|---|
|
cf174cdc18 | ||
|
720fa34757 | ||
754ebde544 | |||
25f69aebb3 | |||
fa29725f92 | |||
d46e77b48a | |||
ebd71a3299 | |||
dc25ad7ca2 | |||
f059073bfc | |||
de75812efc |
@ -353,8 +353,7 @@ def create_app(config_class=DevConfig):
|
|||||||
app.jinja_env.autoescape = select_autoescape(default_for_string=True, default=True)
|
app.jinja_env.autoescape = select_autoescape(default_for_string=True, default=True)
|
||||||
app.jinja_env.trim_blocks = True
|
app.jinja_env.trim_blocks = True
|
||||||
app.jinja_env.lstrip_blocks = True
|
app.jinja_env.lstrip_blocks = True
|
||||||
# previously in Flask-Bootstrap:
|
app.jinja_env.globals["is_hidden_field"] = lambda field: isinstance(
|
||||||
app.jinja_env.globals["bootstrap_is_hidden_field"] = lambda field: isinstance(
|
|
||||||
field, HiddenField
|
field, HiddenField
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -39,15 +39,13 @@ from wtforms import ValidationError
|
|||||||
from wtforms.fields.simple import StringField, HiddenField
|
from wtforms.fields.simple import StringField, HiddenField
|
||||||
|
|
||||||
from app.models import Departement
|
from app.models import Departement
|
||||||
from app.scodoc import sco_logos, html_sco_header
|
from app.scodoc import sco_logos
|
||||||
from app.scodoc import sco_utils as scu
|
from app.scodoc import sco_utils as scu
|
||||||
|
|
||||||
from app.scodoc.sco_config_actions import LogoInsert
|
from app.scodoc.sco_config_actions import LogoInsert
|
||||||
from app.scodoc.sco_exceptions import ScoValueError
|
from app.scodoc.sco_exceptions import ScoValueError
|
||||||
from app.scodoc.sco_logos import find_logo
|
from app.scodoc.sco_logos import find_logo
|
||||||
|
|
||||||
CSSSTYLES = html_sco_header.BOOTSTRAP_CSS
|
|
||||||
JAVASCRIPTS = html_sco_header.BOOTSTRAP_JS
|
|
||||||
|
|
||||||
# class ItemForm(FlaskForm):
|
# class ItemForm(FlaskForm):
|
||||||
# """Unused Generic class to document common behavior for classes
|
# """Unused Generic class to document common behavior for classes
|
||||||
@ -367,6 +365,7 @@ def _make_data(modele):
|
|||||||
|
|
||||||
class LogosConfigurationForm(FlaskForm):
|
class LogosConfigurationForm(FlaskForm):
|
||||||
"Panneau de configuration des logos"
|
"Panneau de configuration des logos"
|
||||||
|
|
||||||
depts = FieldList(FormField(DeptForm))
|
depts = FieldList(FormField(DeptForm))
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
@ -36,11 +36,6 @@ from app.scodoc import html_sidebar
|
|||||||
import sco_version
|
import sco_version
|
||||||
|
|
||||||
|
|
||||||
# Some constants:
|
|
||||||
BOOTSTRAP_JS = ["libjs/bootstrap/js/bootstrap.min.js", "libjs/purl.js"]
|
|
||||||
BOOTSTRAP_CSS = ["libjs/bootstrap/css/bootstrap.min.css"]
|
|
||||||
|
|
||||||
|
|
||||||
def standard_html_header():
|
def standard_html_header():
|
||||||
"""Standard HTML header for pages outside depts"""
|
"""Standard HTML header for pages outside depts"""
|
||||||
# not used in ZScolar, see sco_header
|
# not used in ZScolar, see sco_header
|
||||||
|
@ -96,7 +96,7 @@ def formation_delete(formation_id=None, dialog_confirmed=False):
|
|||||||
)
|
)
|
||||||
|
|
||||||
return render_template(
|
return render_template(
|
||||||
"sco_page-dept.j2", content="\n".join(H), title="Suppression d'une formation"
|
"sco_page_dept.j2", content="\n".join(H), title="Suppression d'une formation"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1059,10 +1059,8 @@ du programme" (menu "Semestre") si vous avez un semestre en cours);
|
|||||||
"sco_page_dept.j2",
|
"sco_page_dept.j2",
|
||||||
content="".join(H),
|
content="".join(H),
|
||||||
page_title=f"Formation {formation.acronyme} v{formation.version}",
|
page_title=f"Formation {formation.acronyme} v{formation.version}",
|
||||||
cssstyles=html_sco_header.BOOTSTRAP_CSS
|
cssstyles=["libjs/jQuery-tagEditor/jquery.tag-editor.css", "css/ue_table.css"],
|
||||||
+ ["libjs/jQuery-tagEditor/jquery.tag-editor.css", "css/ue_table.css"],
|
javascripts=[
|
||||||
javascripts=html_sco_header.BOOTSTRAP_JS
|
|
||||||
+ [
|
|
||||||
"libjs/jinplace-1.2.1.min.js",
|
"libjs/jinplace-1.2.1.min.js",
|
||||||
"js/ue_list.js",
|
"js/ue_list.js",
|
||||||
"js/edit_ue.js",
|
"js/edit_ue.js",
|
||||||
@ -1130,9 +1128,7 @@ def _ue_table_ues(
|
|||||||
scodoc_dept=g.scodoc_dept,
|
scodoc_dept=g.scodoc_dept,
|
||||||
ue_id=ue["ue_id"],
|
ue_id=ue["ue_id"],
|
||||||
)
|
)
|
||||||
ue[
|
ue["code_apogee_str"] = f""", Apo: <span
|
||||||
"code_apogee_str"
|
|
||||||
] = f""", Apo: <span
|
|
||||||
class="{klass}" data-url="{edit_url}" id="{ue['ue_id']}"
|
class="{klass}" data-url="{edit_url}" id="{ue['ue_id']}"
|
||||||
data-placeholder="{scu.APO_MISSING_CODE_STR}">{
|
data-placeholder="{scu.APO_MISSING_CODE_STR}">{
|
||||||
ue["code_apogee"] or ""
|
ue["code_apogee"] or ""
|
||||||
|
@ -25,8 +25,8 @@
|
|||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
"""Export d'une table avec les résultats de tous les étudiants
|
"""Export d'une table avec les résultats de tous les étudiants"""
|
||||||
"""
|
|
||||||
from flask import url_for, g, request
|
from flask import url_for, g, request
|
||||||
|
|
||||||
from app.comp import res_sem
|
from app.comp import res_sem
|
||||||
@ -73,9 +73,7 @@ def _build_results_table(start_date=None, end_date=None, types_parcours=[]):
|
|||||||
formsemestre_ids_parcours = [sem["formsemestre_id"] for sem in semlist_parcours]
|
formsemestre_ids_parcours = [sem["formsemestre_id"] for sem in semlist_parcours]
|
||||||
|
|
||||||
# Ensemble des étudiants
|
# Ensemble des étudiants
|
||||||
etuds_infos = (
|
etuds_infos = {} # etudid : { formsemestre_id d'inscription le plus recent dans les dates considérées, etud }
|
||||||
{}
|
|
||||||
) # etudid : { formsemestre_id d'inscription le plus recent dans les dates considérées, etud }
|
|
||||||
for formsemestre_id in formsemestre_ids_parcours:
|
for formsemestre_id in formsemestre_ids_parcours:
|
||||||
formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
|
formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
|
||||||
nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
|
nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
|
||||||
@ -287,8 +285,7 @@ def scodoc_table_results(
|
|||||||
H = [
|
H = [
|
||||||
html_sco_header.sco_header(
|
html_sco_header.sco_header(
|
||||||
page_title="Export résultats",
|
page_title="Export résultats",
|
||||||
javascripts=html_sco_header.BOOTSTRAP_JS + ["js/export_results.js"],
|
javascripts=["js/export_results.js"],
|
||||||
cssstyles=html_sco_header.BOOTSTRAP_CSS,
|
|
||||||
),
|
),
|
||||||
# XXX
|
# XXX
|
||||||
"""
|
"""
|
||||||
|
@ -1397,7 +1397,8 @@ def do_formsemestre_clone(
|
|||||||
formsemestre.parcours = formsemestre_orig.parcours
|
formsemestre.parcours = formsemestre_orig.parcours
|
||||||
|
|
||||||
# 6- Copy description
|
# 6- Copy description
|
||||||
formsemestre.description = formsemestre_orig.description.clone()
|
if formsemestre_orig.description:
|
||||||
|
formsemestre.description = formsemestre_orig.description.clone()
|
||||||
|
|
||||||
db.session.add(formsemestre)
|
db.session.add(formsemestre)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
@ -57,13 +57,6 @@ from app.scodoc.gen_tables import GenTable
|
|||||||
from app.scodoc.sco_exceptions import ScoValueError, ScoPermissionDenied
|
from app.scodoc.sco_exceptions import ScoValueError, ScoPermissionDenied
|
||||||
from app.scodoc.sco_permissions import Permission
|
from app.scodoc.sco_permissions import Permission
|
||||||
|
|
||||||
JAVASCRIPTS = html_sco_header.BOOTSTRAP_JS + [
|
|
||||||
"js/groups_view.js",
|
|
||||||
"js/multi-select.js",
|
|
||||||
]
|
|
||||||
|
|
||||||
CSSSTYLES = html_sco_header.BOOTSTRAP_CSS
|
|
||||||
|
|
||||||
|
|
||||||
# view
|
# view
|
||||||
def groups_lists(
|
def groups_lists(
|
||||||
|
@ -51,7 +51,7 @@ from wtforms import (
|
|||||||
from app.models import Evaluation, ModuleImpl
|
from app.models import Evaluation, ModuleImpl
|
||||||
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, sco_preferences
|
from app.scodoc import sco_preferences
|
||||||
from app.scodoc import sco_edit_module
|
from app.scodoc import sco_edit_module
|
||||||
from app.scodoc import sco_evaluations
|
from app.scodoc import sco_evaluations
|
||||||
from app.scodoc import sco_excel
|
from app.scodoc import sco_excel
|
||||||
@ -204,14 +204,14 @@ def placement_eval_selectetuds(evaluation_id):
|
|||||||
% runner.__dict__
|
% runner.__dict__
|
||||||
)
|
)
|
||||||
return runner.exec_placement() # calcul et generation du fichier
|
return runner.exec_placement() # calcul et generation du fichier
|
||||||
htmls = [
|
|
||||||
html_sco_header.sco_header(),
|
return render_template(
|
||||||
sco_evaluations.evaluation_describe(evaluation_id=evaluation_id),
|
"scodoc/forms/placement.j2",
|
||||||
"<h3>Placement et émargement des étudiants</h3>",
|
evaluations_description=sco_evaluations.evaluation_describe(
|
||||||
render_template("scodoc/forms/placement.j2", form=form),
|
evaluation_id=evaluation_id
|
||||||
]
|
),
|
||||||
footer = html_sco_header.sco_footer()
|
form=form,
|
||||||
return "\n".join(htmls) + "<p>" + footer
|
)
|
||||||
|
|
||||||
|
|
||||||
class PlacementRunner:
|
class PlacementRunner:
|
||||||
|
@ -350,7 +350,7 @@ def formsemestre_pvjury_pdf(formsemestre_id, group_ids: list[int] = None, etudid
|
|||||||
etud = Identite.get_etud(etudid)
|
etud = Identite.get_etud(etudid)
|
||||||
etudids = [etudid]
|
etudids = [etudid]
|
||||||
else:
|
else:
|
||||||
etuddescr = ""
|
etud = None
|
||||||
if not group_ids:
|
if not group_ids:
|
||||||
# tous les inscrits du semestre
|
# tous les inscrits du semestre
|
||||||
group_ids = [sco_groups.get_default_group(formsemestre_id)]
|
group_ids = [sco_groups.get_default_group(formsemestre_id)]
|
||||||
@ -399,7 +399,7 @@ def formsemestre_pvjury_pdf(formsemestre_id, group_ids: list[int] = None, etudid
|
|||||||
if tf[0] == 0:
|
if tf[0] == 0:
|
||||||
return render_template(
|
return render_template(
|
||||||
"sco_page.j2",
|
"sco_page.j2",
|
||||||
title=f"Édition du PV de jury de {etud.nom_prenom()}",
|
title=f"Édition du PV de jury {('de ' + etud.nom_prenom()) if etud else ''}",
|
||||||
content=f"""<h2 class="formsemestre">Édition du PV de jury
|
content=f"""<h2 class="formsemestre">Édition du PV de jury
|
||||||
de <a class="discretelink" href="{
|
de <a class="discretelink" href="{
|
||||||
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||||
|
@ -37,7 +37,7 @@ import time
|
|||||||
import datetime
|
import datetime
|
||||||
from operator import itemgetter
|
from operator import itemgetter
|
||||||
|
|
||||||
from flask import url_for, g, request
|
from flask import url_for, g, render_template, request
|
||||||
import pydot
|
import pydot
|
||||||
|
|
||||||
from app import log
|
from app import log
|
||||||
@ -50,7 +50,6 @@ from app.models.etudiants import Identite
|
|||||||
|
|
||||||
from app.scodoc import (
|
from app.scodoc import (
|
||||||
codes_cursus,
|
codes_cursus,
|
||||||
html_sco_header,
|
|
||||||
sco_etud,
|
sco_etud,
|
||||||
sco_formsemestre,
|
sco_formsemestre,
|
||||||
sco_formsemestre_inscriptions,
|
sco_formsemestre_inscriptions,
|
||||||
@ -411,11 +410,6 @@ def formsemestre_report_counts(
|
|||||||
if fmt != "html":
|
if fmt != "html":
|
||||||
return tableau
|
return tableau
|
||||||
H = [
|
H = [
|
||||||
html_sco_header.sco_header(
|
|
||||||
cssstyles=sco_groups_view.CSSSTYLES,
|
|
||||||
javascripts=sco_groups_view.JAVASCRIPTS,
|
|
||||||
page_title=title,
|
|
||||||
),
|
|
||||||
tableau,
|
tableau,
|
||||||
"\n".join(F),
|
"\n".join(F),
|
||||||
"""<p class="help">Le tableau affiche le nombre d'étudiants de ce semestre dans chacun
|
"""<p class="help">Le tableau affiche le nombre d'étudiants de ce semestre dans chacun
|
||||||
@ -423,9 +417,14 @@ def formsemestre_report_counts(
|
|||||||
pour les lignes et les colonnes. Le <tt>codedecision</tt> est le code de la décision
|
pour les lignes et les colonnes. Le <tt>codedecision</tt> est le code de la décision
|
||||||
du jury.
|
du jury.
|
||||||
</p>""",
|
</p>""",
|
||||||
html_sco_header.sco_footer(),
|
|
||||||
]
|
]
|
||||||
return "\n".join(H)
|
return render_template(
|
||||||
|
"sco_page.j2",
|
||||||
|
cssstyles=sco_groups_view.CSSSTYLES,
|
||||||
|
javascripts=sco_groups_view.JAVASCRIPTS,
|
||||||
|
title=title,
|
||||||
|
content="\n".join(H),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
@ -813,11 +812,6 @@ def formsemestre_suivi_cohorte(
|
|||||||
href="{burl}&percent=1">Afficher les résultats en pourcentages</a></p>"""
|
href="{burl}&percent=1">Afficher les résultats en pourcentages</a></p>"""
|
||||||
|
|
||||||
H = [
|
H = [
|
||||||
html_sco_header.sco_header(
|
|
||||||
cssstyles=sco_groups_view.CSSSTYLES,
|
|
||||||
javascripts=sco_groups_view.JAVASCRIPTS,
|
|
||||||
page_title=tab.page_title,
|
|
||||||
),
|
|
||||||
"""<h2 class="formsemestre">Suivi cohorte: devenir des étudiants de ce semestre</h2>""",
|
"""<h2 class="formsemestre">Suivi cohorte: devenir des étudiants de ce semestre</h2>""",
|
||||||
_gen_form_selectetuds(
|
_gen_form_selectetuds(
|
||||||
formsemestre.id,
|
formsemestre.id,
|
||||||
@ -853,9 +847,14 @@ def formsemestre_suivi_cohorte(
|
|||||||
</p>
|
</p>
|
||||||
""",
|
""",
|
||||||
expl,
|
expl,
|
||||||
html_sco_header.sco_footer(),
|
|
||||||
]
|
]
|
||||||
return "\n".join(H)
|
return render_template(
|
||||||
|
"sco_page.j2",
|
||||||
|
cssstyles=sco_groups_view.CSSSTYLES,
|
||||||
|
javascripts=sco_groups_view.JAVASCRIPTS,
|
||||||
|
title=tab.page_title,
|
||||||
|
content="\n".join(H),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def _gen_form_selectetuds(
|
def _gen_form_selectetuds(
|
||||||
@ -1365,15 +1364,11 @@ def formsemestre_suivi_cursus(
|
|||||||
]
|
]
|
||||||
|
|
||||||
H = [
|
H = [
|
||||||
html_sco_header.sco_header(
|
|
||||||
page_title=tab.page_title,
|
|
||||||
),
|
|
||||||
"""<h2 class="formsemestre">Cursus suivis par les étudiants de ce semestre</h2>""",
|
"""<h2 class="formsemestre">Cursus suivis par les étudiants de ce semestre</h2>""",
|
||||||
"\n".join(F),
|
"\n".join(F),
|
||||||
t,
|
t,
|
||||||
html_sco_header.sco_footer(),
|
|
||||||
]
|
]
|
||||||
return "\n".join(H)
|
return render_template("sco_page.j2", title=tab.page_title, content="\n".join(H))
|
||||||
|
|
||||||
|
|
||||||
# -------------
|
# -------------
|
||||||
@ -1742,12 +1737,6 @@ def formsemestre_graph_cursus(
|
|||||||
)
|
)
|
||||||
|
|
||||||
H = [
|
H = [
|
||||||
html_sco_header.sco_header(
|
|
||||||
cssstyles=sco_groups_view.CSSSTYLES,
|
|
||||||
javascripts=sco_groups_view.JAVASCRIPTS,
|
|
||||||
page_title="Graphe cursus de %(titreannee)s" % sem,
|
|
||||||
no_sidebar=True,
|
|
||||||
),
|
|
||||||
"""<h2 class="formsemestre">Cursus des étudiants de ce semestre</h2>""",
|
"""<h2 class="formsemestre">Cursus des étudiants de ce semestre</h2>""",
|
||||||
doc,
|
doc,
|
||||||
f"<p>{len(etuds)} étudiants sélectionnés</p>",
|
f"<p>{len(etuds)} étudiants sélectionnés</p>",
|
||||||
@ -1771,11 +1760,12 @@ def formsemestre_graph_cursus(
|
|||||||
),
|
),
|
||||||
"""<p>Origine et devenir des étudiants inscrits dans %(titreannee)s"""
|
"""<p>Origine et devenir des étudiants inscrits dans %(titreannee)s"""
|
||||||
% sem,
|
% sem,
|
||||||
"""(<a href="%s">version pdf</a>"""
|
f"""(<a href="{
|
||||||
% url_for("notes.formsemestre_graph_cursus", fmt="pdf", **url_kw),
|
url_for("notes.formsemestre_graph_cursus", fmt="pdf", **url_kw)
|
||||||
""", <a href="%s">image PNG</a>)"""
|
}">version pdf</a>,
|
||||||
% url_for("notes.formsemestre_graph_cursus", fmt="png", **url_kw),
|
<a href="{
|
||||||
f"""
|
url_for("notes.formsemestre_graph_cursus", fmt="png", **url_kw)}">image PNG</a>)
|
||||||
|
|
||||||
</p>
|
</p>
|
||||||
<p class="help">Le graphe permet de suivre les étudiants inscrits dans le semestre
|
<p class="help">Le graphe permet de suivre les étudiants inscrits dans le semestre
|
||||||
sélectionné (dessiné en vert). Chaque rectangle représente un semestre (cliquez dedans
|
sélectionné (dessiné en vert). Chaque rectangle représente un semestre (cliquez dedans
|
||||||
@ -1788,8 +1778,14 @@ def formsemestre_graph_cursus(
|
|||||||
étudiants appartenant aux groupes indiqués <em>dans le semestre d'origine</em>.
|
étudiants appartenant aux groupes indiqués <em>dans le semestre d'origine</em>.
|
||||||
</p>
|
</p>
|
||||||
""",
|
""",
|
||||||
html_sco_header.sco_footer(),
|
|
||||||
]
|
]
|
||||||
return "\n".join(H)
|
return render_template(
|
||||||
|
"sco_page.j2",
|
||||||
|
cssstyles=sco_groups_view.CSSSTYLES,
|
||||||
|
javascripts=sco_groups_view.JAVASCRIPTS,
|
||||||
|
page_title=f"Graphe cursus de {sem['titreannee']}",
|
||||||
|
no_sidebar=True,
|
||||||
|
content="\n".join(H),
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
raise ValueError(f"invalid format: {fmt}")
|
raise ValueError(f"invalid format: {fmt}")
|
||||||
|
@ -31,21 +31,18 @@
|
|||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
|
||||||
|
|
||||||
from flask import request
|
from flask import render_template, request
|
||||||
|
|
||||||
from app import db
|
from app import db
|
||||||
from app.but import jury_but
|
from app.but import jury_but
|
||||||
from app.models import FormSemestre
|
from app.models import FormSemestre
|
||||||
from app.models.formsemestre import FormSemestreInscription
|
from app.models.formsemestre import FormSemestreInscription
|
||||||
|
|
||||||
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 codes_cursus
|
from app.scodoc import codes_cursus
|
||||||
from app.scodoc.sco_exceptions import ScoValueError
|
from app.scodoc.sco_exceptions import ScoValueError
|
||||||
|
|
||||||
from app.scodoc import sco_preferences
|
from app.scodoc import sco_preferences
|
||||||
import sco_version
|
|
||||||
from app.scodoc.gen_tables import GenTable
|
from app.scodoc.gen_tables import GenTable
|
||||||
|
import sco_version
|
||||||
|
|
||||||
|
|
||||||
# Titres, ordonnés
|
# Titres, ordonnés
|
||||||
@ -107,13 +104,11 @@ def formsemestre_but_indicateurs(formsemestre_id: int, fmt="html"):
|
|||||||
if fmt != "html":
|
if fmt != "html":
|
||||||
return t
|
return t
|
||||||
H = [
|
H = [
|
||||||
html_sco_header.sco_header(page_title=title),
|
|
||||||
t,
|
t,
|
||||||
"""<p class="help">
|
"""<p class="help">
|
||||||
</p>""",
|
</p>""",
|
||||||
html_sco_header.sco_footer(),
|
|
||||||
]
|
]
|
||||||
return "\n".join(H)
|
return render_template("sco_page.j2", title=title, content="\n".join(H))
|
||||||
|
|
||||||
|
|
||||||
def but_indicateurs_by_bac(formsemestre: FormSemestre) -> dict[str:dict]:
|
def but_indicateurs_by_bac(formsemestre: FormSemestre) -> dict[str:dict]:
|
||||||
|
@ -40,17 +40,15 @@ sem_set_list()
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import flask
|
import flask
|
||||||
from flask import g, url_for
|
from flask import g, render_template, url_for
|
||||||
|
|
||||||
from app import db, log
|
from app import db, log
|
||||||
from app.comp import res_sem
|
from app.comp import res_sem
|
||||||
from app.comp.res_compat import NotesTableCompat
|
from app.comp.res_compat import NotesTableCompat
|
||||||
from app.models import FormSemestre
|
from app.models import FormSemestre
|
||||||
from app.scodoc import html_sco_header
|
|
||||||
from app.scodoc import sco_etape_apogee
|
from app.scodoc import sco_etape_apogee
|
||||||
from app.scodoc import sco_formsemestre
|
from app.scodoc import sco_formsemestre
|
||||||
from app.scodoc import sco_formsemestre_status
|
from app.scodoc import sco_formsemestre_status
|
||||||
from app.scodoc import sco_portal_apogee
|
|
||||||
from app.scodoc import sco_preferences
|
from app.scodoc import sco_preferences
|
||||||
from app.scodoc.gen_tables import GenTable
|
from app.scodoc.gen_tables import GenTable
|
||||||
from app.scodoc.sco_etape_bilan import EtapeBilan
|
from app.scodoc.sco_etape_bilan import EtapeBilan
|
||||||
@ -412,7 +410,7 @@ def do_semset_delete(semset_id, dialog_confirmed=False):
|
|||||||
s = SemSet(semset_id=semset_id)
|
s = SemSet(semset_id=semset_id)
|
||||||
if not dialog_confirmed:
|
if not dialog_confirmed:
|
||||||
return scu.confirm_dialog(
|
return scu.confirm_dialog(
|
||||||
"<h2>Suppression de l'ensemble %(title)s ?</h2>" % s,
|
f"<h2>Suppression de l'ensemble {s['title']} ?</h2>",
|
||||||
dest_url="",
|
dest_url="",
|
||||||
parameters={"semset_id": semset_id},
|
parameters={"semset_id": semset_id},
|
||||||
cancel_url="semset_page",
|
cancel_url="semset_page",
|
||||||
@ -421,14 +419,14 @@ def do_semset_delete(semset_id, dialog_confirmed=False):
|
|||||||
return flask.redirect("semset_page")
|
return flask.redirect("semset_page")
|
||||||
|
|
||||||
|
|
||||||
def edit_semset_set_title(id=None, value=None):
|
def edit_semset_set_title(oid=None, value=None):
|
||||||
"""Change title of semset"""
|
"""Change title of semset"""
|
||||||
title = value.strip()
|
title = value.strip()
|
||||||
if not id:
|
if not oid:
|
||||||
raise ScoValueError("empty semset_id")
|
raise ScoValueError("empty semset_id")
|
||||||
SemSet(semset_id=id)
|
SemSet(semset_id=oid)
|
||||||
cnx = ndb.GetDBConnexion()
|
cnx = ndb.GetDBConnexion()
|
||||||
semset_edit(cnx, {"semset_id": id, "title": title})
|
semset_edit(cnx, {"semset_id": oid, "title": title})
|
||||||
return title
|
return title
|
||||||
|
|
||||||
|
|
||||||
@ -517,22 +515,18 @@ def semset_page(fmt="html"):
|
|||||||
|
|
||||||
page_title = "Ensembles de semestres"
|
page_title = "Ensembles de semestres"
|
||||||
H = [
|
H = [
|
||||||
html_sco_header.sco_header(
|
|
||||||
page_title=page_title,
|
|
||||||
javascripts=["libjs/jinplace-1.2.1.min.js"],
|
|
||||||
),
|
|
||||||
"""<script>$(function() {
|
"""<script>$(function() {
|
||||||
$('.inplace_edit').jinplace();
|
$('.inplace_edit').jinplace();
|
||||||
});
|
});
|
||||||
</script>""",
|
</script>""",
|
||||||
"<h2>%s</h2>" % page_title,
|
f"<h2>{page_title}</h2>",
|
||||||
]
|
]
|
||||||
H.append(tab.html())
|
H.append(tab.html())
|
||||||
|
|
||||||
annee_courante = int(scu.annee_scolaire())
|
annee_courante = int(scu.annee_scolaire())
|
||||||
menu_annee = "\n".join(
|
menu_annee = "\n".join(
|
||||||
[
|
[
|
||||||
'<option value="%s">%s</option>' % (i, i)
|
f"""<option value="{i}">{i}</option>"""
|
||||||
for i in range(2014, annee_courante + 1)
|
for i in range(2014, annee_courante + 1)
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
@ -561,8 +555,8 @@ def semset_page(fmt="html"):
|
|||||||
|
|
||||||
H.append(
|
H.append(
|
||||||
"""
|
"""
|
||||||
<div>
|
<div class="scobox space-before-24">
|
||||||
<h4>Autres opérations:</h4>
|
<div class="scobox-title">Autres opérations :</div>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a class="stdlink" href="scodoc_table_results">
|
<li><a class="stdlink" href="scodoc_table_results">
|
||||||
Table des résultats de tous les semestres
|
Table des résultats de tous les semestres
|
||||||
@ -575,4 +569,9 @@ def semset_page(fmt="html"):
|
|||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
return "\n".join(H) + html_sco_header.sco_footer()
|
return render_template(
|
||||||
|
"sco_page_dept.j2",
|
||||||
|
title=page_title,
|
||||||
|
javascripts=["libjs/jinplace-1.2.1.min.js"],
|
||||||
|
content="\n".join(H),
|
||||||
|
)
|
||||||
|
@ -49,7 +49,6 @@ import app.scodoc.sco_utils as scu
|
|||||||
from app.scodoc.TrivialFormulator import TrivialFormulator
|
from app.scodoc.TrivialFormulator import TrivialFormulator
|
||||||
from app.scodoc.sco_exceptions import ScoPDFFormatError, ScoValueError
|
from app.scodoc.sco_exceptions import ScoPDFFormatError, ScoValueError
|
||||||
from app.scodoc.sco_pdf import SU
|
from app.scodoc.sco_pdf import SU
|
||||||
from app.scodoc import html_sco_header
|
|
||||||
from app.scodoc import htmlutils
|
from app.scodoc import htmlutils
|
||||||
from app.scodoc import sco_import_etuds
|
from app.scodoc import sco_import_etuds
|
||||||
from app.scodoc import sco_excel
|
from app.scodoc import sco_excel
|
||||||
@ -90,12 +89,7 @@ def trombino(
|
|||||||
return _listeappel_photos_pdf(groups_infos)
|
return _listeappel_photos_pdf(groups_infos)
|
||||||
elif fmt == "doc":
|
elif fmt == "doc":
|
||||||
return sco_trombino_doc.trombino_doc(groups_infos)
|
return sco_trombino_doc.trombino_doc(groups_infos)
|
||||||
else:
|
raise ValueError("invalid format")
|
||||||
raise Exception("invalid format")
|
|
||||||
|
|
||||||
|
|
||||||
def _trombino_html_header():
|
|
||||||
return html_sco_header.sco_header(javascripts=["js/trombino.js"])
|
|
||||||
|
|
||||||
|
|
||||||
def trombino_html(groups_infos):
|
def trombino_html(groups_infos):
|
||||||
@ -251,14 +245,18 @@ def trombino_copy_photos(group_ids=None, dialog_confirmed=False):
|
|||||||
back_url = "groups_photos?" + str(groups_infos.groups_query_args)
|
back_url = "groups_photos?" + str(groups_infos.groups_query_args)
|
||||||
|
|
||||||
portal_url = sco_portal_apogee.get_portal_url()
|
portal_url = sco_portal_apogee.get_portal_url()
|
||||||
header = html_sco_header.sco_header(page_title="Chargement des photos")
|
|
||||||
footer = html_sco_header.sco_footer()
|
|
||||||
if not portal_url:
|
if not portal_url:
|
||||||
return f"""{ header }
|
return render_template(
|
||||||
|
"sco_page.j2",
|
||||||
|
content=f"""
|
||||||
<p>portail non configuré</p>
|
<p>portail non configuré</p>
|
||||||
<p><a href="{back_url}" class="stdlink">Retour au trombinoscope</a></p>
|
<div>
|
||||||
{ footer }
|
<a class="stdlink" href="{back_url}" class="stdlink">
|
||||||
"""
|
Retour au trombinoscope
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
""",
|
||||||
|
)
|
||||||
if not dialog_confirmed:
|
if not dialog_confirmed:
|
||||||
return scu.confirm_dialog(
|
return scu.confirm_dialog(
|
||||||
f"""<h2>Copier les photos du portail vers ScoDoc ?</h2>
|
f"""<h2>Copier les photos du portail vers ScoDoc ?</h2>
|
||||||
@ -285,14 +283,18 @@ def trombino_copy_photos(group_ids=None, dialog_confirmed=False):
|
|||||||
|
|
||||||
msg.append(f"<b>{nok} photos correctement chargées</b>")
|
msg.append(f"<b>{nok} photos correctement chargées</b>")
|
||||||
|
|
||||||
return f"""{ header }
|
return render_template(
|
||||||
|
"sco_page.j2",
|
||||||
|
content=f"""
|
||||||
<h2>Chargement des photos depuis le portail</h2>
|
<h2>Chargement des photos depuis le portail</h2>
|
||||||
<ul><li>
|
<ul><li>
|
||||||
{ '</li><li>'.join(msg) }
|
{ '</li><li>'.join(msg) }
|
||||||
</li></ul>
|
</li></ul>
|
||||||
<p><a href="{back_url}">retour au trombinoscope</a>
|
<div class="space-before-24">
|
||||||
{ footer }
|
<a class="stdlink" href="{back_url}">retour au trombinoscope</a>
|
||||||
"""
|
</div>
|
||||||
|
""",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def _get_etud_platypus_image(t, image_width=2 * cm):
|
def _get_etud_platypus_image(t, image_width=2 * cm):
|
||||||
@ -506,7 +508,6 @@ def photos_import_files_form(group_ids=()):
|
|||||||
back_url = f"groups_photos?{groups_infos.groups_query_args}"
|
back_url = f"groups_photos?{groups_infos.groups_query_args}"
|
||||||
|
|
||||||
H = [
|
H = [
|
||||||
html_sco_header.sco_header(page_title="Import des photos des étudiants"),
|
|
||||||
f"""<h2 class="formsemestre">Téléchargement des photos des étudiants</h2>
|
f"""<h2 class="formsemestre">Téléchargement des photos des étudiants</h2>
|
||||||
<p><b>Vous pouvez aussi charger les photos individuellement via la fiche
|
<p><b>Vous pouvez aussi charger les photos individuellement via la fiche
|
||||||
de chaque étudiant (menu "Étudiant" / "Changer la photo").</b>
|
de chaque étudiant (menu "Étudiant" / "Changer la photo").</b>
|
||||||
@ -526,7 +527,6 @@ def photos_import_files_form(group_ids=()):
|
|||||||
<li style="padding-top: 2em;">
|
<li style="padding-top: 2em;">
|
||||||
""",
|
""",
|
||||||
]
|
]
|
||||||
F = html_sco_header.sco_footer()
|
|
||||||
vals = scu.get_request_args()
|
vals = scu.get_request_args()
|
||||||
vals["group_ids"] = groups_infos.group_ids
|
vals["group_ids"] = groups_infos.group_ids
|
||||||
tf = TrivialFormulator(
|
tf = TrivialFormulator(
|
||||||
@ -540,37 +540,40 @@ def photos_import_files_form(group_ids=()):
|
|||||||
)
|
)
|
||||||
|
|
||||||
if tf[0] == 0:
|
if tf[0] == 0:
|
||||||
return "\n".join(H) + tf[1] + "</li></ol>" + F
|
|
||||||
elif tf[0] == -1:
|
|
||||||
return flask.redirect(back_url)
|
|
||||||
else:
|
|
||||||
|
|
||||||
def callback(etud: Identite, data, filename):
|
|
||||||
return sco_photos.store_photo(etud, data, filename)
|
|
||||||
|
|
||||||
(
|
|
||||||
ignored_zipfiles,
|
|
||||||
unmatched_files,
|
|
||||||
stored_etud_filename,
|
|
||||||
) = zip_excel_import_files(
|
|
||||||
xlsfile=tf[2]["xlsfile"],
|
|
||||||
zipfile=tf[2]["zipfile"],
|
|
||||||
callback=callback,
|
|
||||||
filename_title="fichier_photo",
|
|
||||||
back_url=back_url,
|
|
||||||
)
|
|
||||||
return render_template(
|
return render_template(
|
||||||
"scolar/photos_import_files.j2",
|
"sco_page.j2",
|
||||||
page_title="Téléchargement des photos des étudiants",
|
title="Import des photos des étudiants",
|
||||||
ignored_zipfiles=ignored_zipfiles,
|
content="\n".join(H) + tf[1] + "</li></ol>",
|
||||||
unmatched_files=unmatched_files,
|
|
||||||
stored_etud_filename=stored_etud_filename,
|
|
||||||
next_page=url_for(
|
|
||||||
"scolar.groups_photos",
|
|
||||||
scodoc_dept=g.scodoc_dept,
|
|
||||||
formsemestre_id=groups_infos.formsemestre_id,
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
|
if tf[0] == -1:
|
||||||
|
return flask.redirect(back_url)
|
||||||
|
|
||||||
|
def callback(etud: Identite, data, filename):
|
||||||
|
return sco_photos.store_photo(etud, data, filename)
|
||||||
|
|
||||||
|
(
|
||||||
|
ignored_zipfiles,
|
||||||
|
unmatched_files,
|
||||||
|
stored_etud_filename,
|
||||||
|
) = zip_excel_import_files(
|
||||||
|
xlsfile=tf[2]["xlsfile"],
|
||||||
|
zipfile=tf[2]["zipfile"],
|
||||||
|
callback=callback,
|
||||||
|
filename_title="fichier_photo",
|
||||||
|
back_url=back_url,
|
||||||
|
)
|
||||||
|
return render_template(
|
||||||
|
"scolar/photos_import_files.j2",
|
||||||
|
page_title="Téléchargement des photos des étudiants",
|
||||||
|
ignored_zipfiles=ignored_zipfiles,
|
||||||
|
unmatched_files=unmatched_files,
|
||||||
|
stored_etud_filename=stored_etud_filename,
|
||||||
|
next_page=url_for(
|
||||||
|
"scolar.groups_photos",
|
||||||
|
scodoc_dept=g.scodoc_dept,
|
||||||
|
formsemestre_id=groups_infos.formsemestre_id,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def _norm_zip_filename(fn, lowercase=True):
|
def _norm_zip_filename(fn, lowercase=True):
|
||||||
|
@ -59,11 +59,11 @@ div.sco-app-content {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.space-before-18 {
|
.space-before-18 {
|
||||||
margin-top: 18px;
|
margin-top: 18px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.space-before-24 {
|
.space-before-24 {
|
||||||
margin-top: 24px;
|
margin-top: 24px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.scobox.maxwidth {
|
div.scobox.maxwidth {
|
||||||
@ -480,7 +480,7 @@ div.box-chercheetud {
|
|||||||
}
|
}
|
||||||
|
|
||||||
div.box-chercheetud form input {
|
div.box-chercheetud form input {
|
||||||
width: 120px;
|
max-width: 120px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Page accueil général */
|
/* Page accueil général */
|
||||||
|
@ -323,4 +323,179 @@ body {
|
|||||||
|
|
||||||
#tableau-modules-details:not([open]) #tableau_modules {
|
#tableau-modules-details:not([open]) #tableau_modules {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* #region bootstrap <== Remplacement styles bootstrap ==> */
|
||||||
|
|
||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert {
|
||||||
|
text-wrap: balance;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 1140px;
|
||||||
|
--x: 1.5rem;
|
||||||
|
--y: 0;
|
||||||
|
width: 100%;
|
||||||
|
padding-right: calc(var(--x) * 0.5);
|
||||||
|
padding-left: calc(var(--x) * 0.5);
|
||||||
|
margin-right: auto;
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* #region btn */
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
appearance: none;
|
||||||
|
background-color: #FAFBFC;
|
||||||
|
border: 1px solid rgba(27, 31, 35, 0.15);
|
||||||
|
border-radius: 6px;
|
||||||
|
box-shadow: rgba(27, 31, 35, 0.04) 0 1px 0, rgba(255, 255, 255, 0.25) 0 1px 0 inset;
|
||||||
|
box-sizing: border-box;
|
||||||
|
color: #24292E;
|
||||||
|
cursor: pointer;
|
||||||
|
display: inline-block;
|
||||||
|
font-family: -apple-system, system-ui, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 20px;
|
||||||
|
list-style: none;
|
||||||
|
padding: 6px 16px;
|
||||||
|
position: relative;
|
||||||
|
transition: background-color 0.2s cubic-bezier(0.3, 0, 0.5, 1);
|
||||||
|
user-select: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
touch-action: manipulation;
|
||||||
|
vertical-align: middle;
|
||||||
|
white-space: nowrap;
|
||||||
|
word-wrap: break-word;
|
||||||
|
|
||||||
|
margin: 4px 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.btn {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:hover {
|
||||||
|
background-color: #F3F4F6;
|
||||||
|
text-decoration: none;
|
||||||
|
transition-duration: 0.1s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:disabled {
|
||||||
|
background-color: #FAFBFC;
|
||||||
|
border-color: rgba(27, 31, 35, 0.15);
|
||||||
|
color: #959DA5;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:active {
|
||||||
|
background-color: #EDEFF2;
|
||||||
|
box-shadow: rgba(225, 228, 232, 0.2) 0 1px 0 inset;
|
||||||
|
transition: none 0s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:focus {
|
||||||
|
outline: 1px transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:before {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:-webkit-details-marker {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* #endregion btn */
|
||||||
|
|
||||||
|
/* #region form */
|
||||||
|
|
||||||
|
label,
|
||||||
|
input,
|
||||||
|
select,
|
||||||
|
textarea {
|
||||||
|
margin: 4px 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.control-label {
|
||||||
|
display: inline-block;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group input,
|
||||||
|
.form-control {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
border: 1px solid #ced4da;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 16px;
|
||||||
|
transition: border-color 0.2s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group input:focus,
|
||||||
|
.form-control:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: #007bff;
|
||||||
|
box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group input[type="submit"],
|
||||||
|
.form-control[type="submit"] {
|
||||||
|
background-color: #007bff;
|
||||||
|
color: white;
|
||||||
|
padding: 10px 16px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 16px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.2s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group input[type="submit"]:hover,
|
||||||
|
.form-control[type="submit"]:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group input[type="submit"][name="cancel"]:hover,
|
||||||
|
.form-control[type="submit"][name="cancel"]:hover {
|
||||||
|
background-color: #606060;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group input[type="submit"][name="cancel"],
|
||||||
|
.form-control[type="submit"][name="cancel"] {
|
||||||
|
background-color: #8a8a8a;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldset {
|
||||||
|
min-width: 0;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* #endregion form */
|
||||||
|
/* #region pagination */
|
||||||
|
|
||||||
|
.pagination {
|
||||||
|
list-style: none;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* #endregion pagination */
|
||||||
|
|
||||||
|
/* #region navbar */
|
||||||
|
/* #endregion navbar */
|
||||||
|
|
||||||
|
/* #endregion bootstrap ==> */
|
@ -1,10 +0,0 @@
|
|||||||
// Affichage progressif du trombinoscope html
|
|
||||||
|
|
||||||
$().ready(function () {
|
|
||||||
var spans = $(".unloaded_img");
|
|
||||||
for (var i = 0; i < spans.size(); i++) {
|
|
||||||
var sp = spans[i];
|
|
||||||
var etudid = sp.id;
|
|
||||||
$(sp).load(SCO_URL + "etud_photo_html?etudid=" + etudid);
|
|
||||||
}
|
|
||||||
});
|
|
@ -1 +0,0 @@
|
|||||||
bootstrap-5.3.3-dist/
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,597 +0,0 @@
|
|||||||
/*!
|
|
||||||
* Bootstrap Reboot v5.3.3 (https://getbootstrap.com/)
|
|
||||||
* Copyright 2011-2024 The Bootstrap Authors
|
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
||||||
*/
|
|
||||||
:root,
|
|
||||||
[data-bs-theme=light] {
|
|
||||||
--bs-blue: #0d6efd;
|
|
||||||
--bs-indigo: #6610f2;
|
|
||||||
--bs-purple: #6f42c1;
|
|
||||||
--bs-pink: #d63384;
|
|
||||||
--bs-red: #dc3545;
|
|
||||||
--bs-orange: #fd7e14;
|
|
||||||
--bs-yellow: #ffc107;
|
|
||||||
--bs-green: #198754;
|
|
||||||
--bs-teal: #20c997;
|
|
||||||
--bs-cyan: #0dcaf0;
|
|
||||||
--bs-black: #000;
|
|
||||||
--bs-white: #fff;
|
|
||||||
--bs-gray: #6c757d;
|
|
||||||
--bs-gray-dark: #343a40;
|
|
||||||
--bs-gray-100: #f8f9fa;
|
|
||||||
--bs-gray-200: #e9ecef;
|
|
||||||
--bs-gray-300: #dee2e6;
|
|
||||||
--bs-gray-400: #ced4da;
|
|
||||||
--bs-gray-500: #adb5bd;
|
|
||||||
--bs-gray-600: #6c757d;
|
|
||||||
--bs-gray-700: #495057;
|
|
||||||
--bs-gray-800: #343a40;
|
|
||||||
--bs-gray-900: #212529;
|
|
||||||
--bs-primary: #0d6efd;
|
|
||||||
--bs-secondary: #6c757d;
|
|
||||||
--bs-success: #198754;
|
|
||||||
--bs-info: #0dcaf0;
|
|
||||||
--bs-warning: #ffc107;
|
|
||||||
--bs-danger: #dc3545;
|
|
||||||
--bs-light: #f8f9fa;
|
|
||||||
--bs-dark: #212529;
|
|
||||||
--bs-primary-rgb: 13, 110, 253;
|
|
||||||
--bs-secondary-rgb: 108, 117, 125;
|
|
||||||
--bs-success-rgb: 25, 135, 84;
|
|
||||||
--bs-info-rgb: 13, 202, 240;
|
|
||||||
--bs-warning-rgb: 255, 193, 7;
|
|
||||||
--bs-danger-rgb: 220, 53, 69;
|
|
||||||
--bs-light-rgb: 248, 249, 250;
|
|
||||||
--bs-dark-rgb: 33, 37, 41;
|
|
||||||
--bs-primary-text-emphasis: #052c65;
|
|
||||||
--bs-secondary-text-emphasis: #2b2f32;
|
|
||||||
--bs-success-text-emphasis: #0a3622;
|
|
||||||
--bs-info-text-emphasis: #055160;
|
|
||||||
--bs-warning-text-emphasis: #664d03;
|
|
||||||
--bs-danger-text-emphasis: #58151c;
|
|
||||||
--bs-light-text-emphasis: #495057;
|
|
||||||
--bs-dark-text-emphasis: #495057;
|
|
||||||
--bs-primary-bg-subtle: #cfe2ff;
|
|
||||||
--bs-secondary-bg-subtle: #e2e3e5;
|
|
||||||
--bs-success-bg-subtle: #d1e7dd;
|
|
||||||
--bs-info-bg-subtle: #cff4fc;
|
|
||||||
--bs-warning-bg-subtle: #fff3cd;
|
|
||||||
--bs-danger-bg-subtle: #f8d7da;
|
|
||||||
--bs-light-bg-subtle: #fcfcfd;
|
|
||||||
--bs-dark-bg-subtle: #ced4da;
|
|
||||||
--bs-primary-border-subtle: #9ec5fe;
|
|
||||||
--bs-secondary-border-subtle: #c4c8cb;
|
|
||||||
--bs-success-border-subtle: #a3cfbb;
|
|
||||||
--bs-info-border-subtle: #9eeaf9;
|
|
||||||
--bs-warning-border-subtle: #ffe69c;
|
|
||||||
--bs-danger-border-subtle: #f1aeb5;
|
|
||||||
--bs-light-border-subtle: #e9ecef;
|
|
||||||
--bs-dark-border-subtle: #adb5bd;
|
|
||||||
--bs-white-rgb: 255, 255, 255;
|
|
||||||
--bs-black-rgb: 0, 0, 0;
|
|
||||||
--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
|
||||||
--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
|
||||||
--bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));
|
|
||||||
--bs-body-font-family: var(--bs-font-sans-serif);
|
|
||||||
--bs-body-font-size: 1rem;
|
|
||||||
--bs-body-font-weight: 400;
|
|
||||||
--bs-body-line-height: 1.5;
|
|
||||||
--bs-body-color: #212529;
|
|
||||||
--bs-body-color-rgb: 33, 37, 41;
|
|
||||||
--bs-body-bg: #fff;
|
|
||||||
--bs-body-bg-rgb: 255, 255, 255;
|
|
||||||
--bs-emphasis-color: #000;
|
|
||||||
--bs-emphasis-color-rgb: 0, 0, 0;
|
|
||||||
--bs-secondary-color: rgba(33, 37, 41, 0.75);
|
|
||||||
--bs-secondary-color-rgb: 33, 37, 41;
|
|
||||||
--bs-secondary-bg: #e9ecef;
|
|
||||||
--bs-secondary-bg-rgb: 233, 236, 239;
|
|
||||||
--bs-tertiary-color: rgba(33, 37, 41, 0.5);
|
|
||||||
--bs-tertiary-color-rgb: 33, 37, 41;
|
|
||||||
--bs-tertiary-bg: #f8f9fa;
|
|
||||||
--bs-tertiary-bg-rgb: 248, 249, 250;
|
|
||||||
--bs-heading-color: inherit;
|
|
||||||
--bs-link-color: #0d6efd;
|
|
||||||
--bs-link-color-rgb: 13, 110, 253;
|
|
||||||
--bs-link-decoration: underline;
|
|
||||||
--bs-link-hover-color: #0a58ca;
|
|
||||||
--bs-link-hover-color-rgb: 10, 88, 202;
|
|
||||||
--bs-code-color: #d63384;
|
|
||||||
--bs-highlight-color: #212529;
|
|
||||||
--bs-highlight-bg: #fff3cd;
|
|
||||||
--bs-border-width: 1px;
|
|
||||||
--bs-border-style: solid;
|
|
||||||
--bs-border-color: #dee2e6;
|
|
||||||
--bs-border-color-translucent: rgba(0, 0, 0, 0.175);
|
|
||||||
--bs-border-radius: 0.375rem;
|
|
||||||
--bs-border-radius-sm: 0.25rem;
|
|
||||||
--bs-border-radius-lg: 0.5rem;
|
|
||||||
--bs-border-radius-xl: 1rem;
|
|
||||||
--bs-border-radius-xxl: 2rem;
|
|
||||||
--bs-border-radius-2xl: var(--bs-border-radius-xxl);
|
|
||||||
--bs-border-radius-pill: 50rem;
|
|
||||||
--bs-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
|
|
||||||
--bs-box-shadow-sm: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
|
|
||||||
--bs-box-shadow-lg: 0 1rem 3rem rgba(0, 0, 0, 0.175);
|
|
||||||
--bs-box-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.075);
|
|
||||||
--bs-focus-ring-width: 0.25rem;
|
|
||||||
--bs-focus-ring-opacity: 0.25;
|
|
||||||
--bs-focus-ring-color: rgba(13, 110, 253, 0.25);
|
|
||||||
--bs-form-valid-color: #198754;
|
|
||||||
--bs-form-valid-border-color: #198754;
|
|
||||||
--bs-form-invalid-color: #dc3545;
|
|
||||||
--bs-form-invalid-border-color: #dc3545;
|
|
||||||
}
|
|
||||||
|
|
||||||
[data-bs-theme=dark] {
|
|
||||||
color-scheme: dark;
|
|
||||||
--bs-body-color: #dee2e6;
|
|
||||||
--bs-body-color-rgb: 222, 226, 230;
|
|
||||||
--bs-body-bg: #212529;
|
|
||||||
--bs-body-bg-rgb: 33, 37, 41;
|
|
||||||
--bs-emphasis-color: #fff;
|
|
||||||
--bs-emphasis-color-rgb: 255, 255, 255;
|
|
||||||
--bs-secondary-color: rgba(222, 226, 230, 0.75);
|
|
||||||
--bs-secondary-color-rgb: 222, 226, 230;
|
|
||||||
--bs-secondary-bg: #343a40;
|
|
||||||
--bs-secondary-bg-rgb: 52, 58, 64;
|
|
||||||
--bs-tertiary-color: rgba(222, 226, 230, 0.5);
|
|
||||||
--bs-tertiary-color-rgb: 222, 226, 230;
|
|
||||||
--bs-tertiary-bg: #2b3035;
|
|
||||||
--bs-tertiary-bg-rgb: 43, 48, 53;
|
|
||||||
--bs-primary-text-emphasis: #6ea8fe;
|
|
||||||
--bs-secondary-text-emphasis: #a7acb1;
|
|
||||||
--bs-success-text-emphasis: #75b798;
|
|
||||||
--bs-info-text-emphasis: #6edff6;
|
|
||||||
--bs-warning-text-emphasis: #ffda6a;
|
|
||||||
--bs-danger-text-emphasis: #ea868f;
|
|
||||||
--bs-light-text-emphasis: #f8f9fa;
|
|
||||||
--bs-dark-text-emphasis: #dee2e6;
|
|
||||||
--bs-primary-bg-subtle: #031633;
|
|
||||||
--bs-secondary-bg-subtle: #161719;
|
|
||||||
--bs-success-bg-subtle: #051b11;
|
|
||||||
--bs-info-bg-subtle: #032830;
|
|
||||||
--bs-warning-bg-subtle: #332701;
|
|
||||||
--bs-danger-bg-subtle: #2c0b0e;
|
|
||||||
--bs-light-bg-subtle: #343a40;
|
|
||||||
--bs-dark-bg-subtle: #1a1d20;
|
|
||||||
--bs-primary-border-subtle: #084298;
|
|
||||||
--bs-secondary-border-subtle: #41464b;
|
|
||||||
--bs-success-border-subtle: #0f5132;
|
|
||||||
--bs-info-border-subtle: #087990;
|
|
||||||
--bs-warning-border-subtle: #997404;
|
|
||||||
--bs-danger-border-subtle: #842029;
|
|
||||||
--bs-light-border-subtle: #495057;
|
|
||||||
--bs-dark-border-subtle: #343a40;
|
|
||||||
--bs-heading-color: inherit;
|
|
||||||
--bs-link-color: #6ea8fe;
|
|
||||||
--bs-link-hover-color: #8bb9fe;
|
|
||||||
--bs-link-color-rgb: 110, 168, 254;
|
|
||||||
--bs-link-hover-color-rgb: 139, 185, 254;
|
|
||||||
--bs-code-color: #e685b5;
|
|
||||||
--bs-highlight-color: #dee2e6;
|
|
||||||
--bs-highlight-bg: #664d03;
|
|
||||||
--bs-border-color: #495057;
|
|
||||||
--bs-border-color-translucent: rgba(255, 255, 255, 0.15);
|
|
||||||
--bs-form-valid-color: #75b798;
|
|
||||||
--bs-form-valid-border-color: #75b798;
|
|
||||||
--bs-form-invalid-color: #ea868f;
|
|
||||||
--bs-form-invalid-border-color: #ea868f;
|
|
||||||
}
|
|
||||||
|
|
||||||
*,
|
|
||||||
*::before,
|
|
||||||
*::after {
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (prefers-reduced-motion: no-preference) {
|
|
||||||
:root {
|
|
||||||
scroll-behavior: smooth;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
font-family: var(--bs-body-font-family);
|
|
||||||
font-size: var(--bs-body-font-size);
|
|
||||||
font-weight: var(--bs-body-font-weight);
|
|
||||||
line-height: var(--bs-body-line-height);
|
|
||||||
color: var(--bs-body-color);
|
|
||||||
text-align: var(--bs-body-text-align);
|
|
||||||
background-color: var(--bs-body-bg);
|
|
||||||
-webkit-text-size-adjust: 100%;
|
|
||||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
hr {
|
|
||||||
margin: 1rem 0;
|
|
||||||
color: inherit;
|
|
||||||
border: 0;
|
|
||||||
border-top: var(--bs-border-width) solid;
|
|
||||||
opacity: 0.25;
|
|
||||||
}
|
|
||||||
|
|
||||||
h6, h5, h4, h3, h2, h1 {
|
|
||||||
margin-top: 0;
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
font-weight: 500;
|
|
||||||
line-height: 1.2;
|
|
||||||
color: var(--bs-heading-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-size: calc(1.375rem + 1.5vw);
|
|
||||||
}
|
|
||||||
@media (min-width: 1200px) {
|
|
||||||
h1 {
|
|
||||||
font-size: 2.5rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
font-size: calc(1.325rem + 0.9vw);
|
|
||||||
}
|
|
||||||
@media (min-width: 1200px) {
|
|
||||||
h2 {
|
|
||||||
font-size: 2rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
h3 {
|
|
||||||
font-size: calc(1.3rem + 0.6vw);
|
|
||||||
}
|
|
||||||
@media (min-width: 1200px) {
|
|
||||||
h3 {
|
|
||||||
font-size: 1.75rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
h4 {
|
|
||||||
font-size: calc(1.275rem + 0.3vw);
|
|
||||||
}
|
|
||||||
@media (min-width: 1200px) {
|
|
||||||
h4 {
|
|
||||||
font-size: 1.5rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
h5 {
|
|
||||||
font-size: 1.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
h6 {
|
|
||||||
font-size: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
margin-top: 0;
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
abbr[title] {
|
|
||||||
-webkit-text-decoration: underline dotted;
|
|
||||||
text-decoration: underline dotted;
|
|
||||||
cursor: help;
|
|
||||||
-webkit-text-decoration-skip-ink: none;
|
|
||||||
text-decoration-skip-ink: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
address {
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
font-style: normal;
|
|
||||||
line-height: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
ol,
|
|
||||||
ul {
|
|
||||||
padding-left: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
ol,
|
|
||||||
ul,
|
|
||||||
dl {
|
|
||||||
margin-top: 0;
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
ol ol,
|
|
||||||
ul ul,
|
|
||||||
ol ul,
|
|
||||||
ul ol {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
dt {
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
|
|
||||||
dd {
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
margin-left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
blockquote {
|
|
||||||
margin: 0 0 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
b,
|
|
||||||
strong {
|
|
||||||
font-weight: bolder;
|
|
||||||
}
|
|
||||||
|
|
||||||
small {
|
|
||||||
font-size: 0.875em;
|
|
||||||
}
|
|
||||||
|
|
||||||
mark {
|
|
||||||
padding: 0.1875em;
|
|
||||||
color: var(--bs-highlight-color);
|
|
||||||
background-color: var(--bs-highlight-bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
sub,
|
|
||||||
sup {
|
|
||||||
position: relative;
|
|
||||||
font-size: 0.75em;
|
|
||||||
line-height: 0;
|
|
||||||
vertical-align: baseline;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub {
|
|
||||||
bottom: -0.25em;
|
|
||||||
}
|
|
||||||
|
|
||||||
sup {
|
|
||||||
top: -0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1));
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
a:hover {
|
|
||||||
--bs-link-color-rgb: var(--bs-link-hover-color-rgb);
|
|
||||||
}
|
|
||||||
|
|
||||||
a:not([href]):not([class]), a:not([href]):not([class]):hover {
|
|
||||||
color: inherit;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre,
|
|
||||||
code,
|
|
||||||
kbd,
|
|
||||||
samp {
|
|
||||||
font-family: var(--bs-font-monospace);
|
|
||||||
font-size: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre {
|
|
||||||
display: block;
|
|
||||||
margin-top: 0;
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
overflow: auto;
|
|
||||||
font-size: 0.875em;
|
|
||||||
}
|
|
||||||
pre code {
|
|
||||||
font-size: inherit;
|
|
||||||
color: inherit;
|
|
||||||
word-break: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
code {
|
|
||||||
font-size: 0.875em;
|
|
||||||
color: var(--bs-code-color);
|
|
||||||
word-wrap: break-word;
|
|
||||||
}
|
|
||||||
a > code {
|
|
||||||
color: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
kbd {
|
|
||||||
padding: 0.1875rem 0.375rem;
|
|
||||||
font-size: 0.875em;
|
|
||||||
color: var(--bs-body-bg);
|
|
||||||
background-color: var(--bs-body-color);
|
|
||||||
border-radius: 0.25rem;
|
|
||||||
}
|
|
||||||
kbd kbd {
|
|
||||||
padding: 0;
|
|
||||||
font-size: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
figure {
|
|
||||||
margin: 0 0 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
img,
|
|
||||||
svg {
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
table {
|
|
||||||
caption-side: bottom;
|
|
||||||
border-collapse: collapse;
|
|
||||||
}
|
|
||||||
|
|
||||||
caption {
|
|
||||||
padding-top: 0.5rem;
|
|
||||||
padding-bottom: 0.5rem;
|
|
||||||
color: var(--bs-secondary-color);
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
th {
|
|
||||||
text-align: inherit;
|
|
||||||
text-align: -webkit-match-parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
thead,
|
|
||||||
tbody,
|
|
||||||
tfoot,
|
|
||||||
tr,
|
|
||||||
td,
|
|
||||||
th {
|
|
||||||
border-color: inherit;
|
|
||||||
border-style: solid;
|
|
||||||
border-width: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
label {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
border-radius: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
button:focus:not(:focus-visible) {
|
|
||||||
outline: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
input,
|
|
||||||
button,
|
|
||||||
select,
|
|
||||||
optgroup,
|
|
||||||
textarea {
|
|
||||||
margin: 0;
|
|
||||||
font-family: inherit;
|
|
||||||
font-size: inherit;
|
|
||||||
line-height: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
button,
|
|
||||||
select {
|
|
||||||
text-transform: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
[role=button] {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
select {
|
|
||||||
word-wrap: normal;
|
|
||||||
}
|
|
||||||
select:disabled {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
button,
|
|
||||||
[type=button],
|
|
||||||
[type=reset],
|
|
||||||
[type=submit] {
|
|
||||||
-webkit-appearance: button;
|
|
||||||
}
|
|
||||||
button:not(:disabled),
|
|
||||||
[type=button]:not(:disabled),
|
|
||||||
[type=reset]:not(:disabled),
|
|
||||||
[type=submit]:not(:disabled) {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
::-moz-focus-inner {
|
|
||||||
padding: 0;
|
|
||||||
border-style: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
textarea {
|
|
||||||
resize: vertical;
|
|
||||||
}
|
|
||||||
|
|
||||||
fieldset {
|
|
||||||
min-width: 0;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
border: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
legend {
|
|
||||||
float: left;
|
|
||||||
width: 100%;
|
|
||||||
padding: 0;
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
font-size: calc(1.275rem + 0.3vw);
|
|
||||||
line-height: inherit;
|
|
||||||
}
|
|
||||||
@media (min-width: 1200px) {
|
|
||||||
legend {
|
|
||||||
font-size: 1.5rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
legend + * {
|
|
||||||
clear: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-datetime-edit-fields-wrapper,
|
|
||||||
::-webkit-datetime-edit-text,
|
|
||||||
::-webkit-datetime-edit-minute,
|
|
||||||
::-webkit-datetime-edit-hour-field,
|
|
||||||
::-webkit-datetime-edit-day-field,
|
|
||||||
::-webkit-datetime-edit-month-field,
|
|
||||||
::-webkit-datetime-edit-year-field {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-inner-spin-button {
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
[type=search] {
|
|
||||||
-webkit-appearance: textfield;
|
|
||||||
outline-offset: -2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* rtl:raw:
|
|
||||||
[type="tel"],
|
|
||||||
[type="url"],
|
|
||||||
[type="email"],
|
|
||||||
[type="number"] {
|
|
||||||
direction: ltr;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
::-webkit-search-decoration {
|
|
||||||
-webkit-appearance: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-color-swatch-wrapper {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-file-upload-button {
|
|
||||||
font: inherit;
|
|
||||||
-webkit-appearance: button;
|
|
||||||
}
|
|
||||||
|
|
||||||
::file-selector-button {
|
|
||||||
font: inherit;
|
|
||||||
-webkit-appearance: button;
|
|
||||||
}
|
|
||||||
|
|
||||||
output {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
iframe {
|
|
||||||
border: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
summary {
|
|
||||||
display: list-item;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
progress {
|
|
||||||
vertical-align: baseline;
|
|
||||||
}
|
|
||||||
|
|
||||||
[hidden] {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*# sourceMappingURL=bootstrap-reboot.css.map */
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,594 +0,0 @@
|
|||||||
/*!
|
|
||||||
* Bootstrap Reboot v5.3.3 (https://getbootstrap.com/)
|
|
||||||
* Copyright 2011-2024 The Bootstrap Authors
|
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
||||||
*/
|
|
||||||
:root,
|
|
||||||
[data-bs-theme=light] {
|
|
||||||
--bs-blue: #0d6efd;
|
|
||||||
--bs-indigo: #6610f2;
|
|
||||||
--bs-purple: #6f42c1;
|
|
||||||
--bs-pink: #d63384;
|
|
||||||
--bs-red: #dc3545;
|
|
||||||
--bs-orange: #fd7e14;
|
|
||||||
--bs-yellow: #ffc107;
|
|
||||||
--bs-green: #198754;
|
|
||||||
--bs-teal: #20c997;
|
|
||||||
--bs-cyan: #0dcaf0;
|
|
||||||
--bs-black: #000;
|
|
||||||
--bs-white: #fff;
|
|
||||||
--bs-gray: #6c757d;
|
|
||||||
--bs-gray-dark: #343a40;
|
|
||||||
--bs-gray-100: #f8f9fa;
|
|
||||||
--bs-gray-200: #e9ecef;
|
|
||||||
--bs-gray-300: #dee2e6;
|
|
||||||
--bs-gray-400: #ced4da;
|
|
||||||
--bs-gray-500: #adb5bd;
|
|
||||||
--bs-gray-600: #6c757d;
|
|
||||||
--bs-gray-700: #495057;
|
|
||||||
--bs-gray-800: #343a40;
|
|
||||||
--bs-gray-900: #212529;
|
|
||||||
--bs-primary: #0d6efd;
|
|
||||||
--bs-secondary: #6c757d;
|
|
||||||
--bs-success: #198754;
|
|
||||||
--bs-info: #0dcaf0;
|
|
||||||
--bs-warning: #ffc107;
|
|
||||||
--bs-danger: #dc3545;
|
|
||||||
--bs-light: #f8f9fa;
|
|
||||||
--bs-dark: #212529;
|
|
||||||
--bs-primary-rgb: 13, 110, 253;
|
|
||||||
--bs-secondary-rgb: 108, 117, 125;
|
|
||||||
--bs-success-rgb: 25, 135, 84;
|
|
||||||
--bs-info-rgb: 13, 202, 240;
|
|
||||||
--bs-warning-rgb: 255, 193, 7;
|
|
||||||
--bs-danger-rgb: 220, 53, 69;
|
|
||||||
--bs-light-rgb: 248, 249, 250;
|
|
||||||
--bs-dark-rgb: 33, 37, 41;
|
|
||||||
--bs-primary-text-emphasis: #052c65;
|
|
||||||
--bs-secondary-text-emphasis: #2b2f32;
|
|
||||||
--bs-success-text-emphasis: #0a3622;
|
|
||||||
--bs-info-text-emphasis: #055160;
|
|
||||||
--bs-warning-text-emphasis: #664d03;
|
|
||||||
--bs-danger-text-emphasis: #58151c;
|
|
||||||
--bs-light-text-emphasis: #495057;
|
|
||||||
--bs-dark-text-emphasis: #495057;
|
|
||||||
--bs-primary-bg-subtle: #cfe2ff;
|
|
||||||
--bs-secondary-bg-subtle: #e2e3e5;
|
|
||||||
--bs-success-bg-subtle: #d1e7dd;
|
|
||||||
--bs-info-bg-subtle: #cff4fc;
|
|
||||||
--bs-warning-bg-subtle: #fff3cd;
|
|
||||||
--bs-danger-bg-subtle: #f8d7da;
|
|
||||||
--bs-light-bg-subtle: #fcfcfd;
|
|
||||||
--bs-dark-bg-subtle: #ced4da;
|
|
||||||
--bs-primary-border-subtle: #9ec5fe;
|
|
||||||
--bs-secondary-border-subtle: #c4c8cb;
|
|
||||||
--bs-success-border-subtle: #a3cfbb;
|
|
||||||
--bs-info-border-subtle: #9eeaf9;
|
|
||||||
--bs-warning-border-subtle: #ffe69c;
|
|
||||||
--bs-danger-border-subtle: #f1aeb5;
|
|
||||||
--bs-light-border-subtle: #e9ecef;
|
|
||||||
--bs-dark-border-subtle: #adb5bd;
|
|
||||||
--bs-white-rgb: 255, 255, 255;
|
|
||||||
--bs-black-rgb: 0, 0, 0;
|
|
||||||
--bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
|
||||||
--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
|
||||||
--bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));
|
|
||||||
--bs-body-font-family: var(--bs-font-sans-serif);
|
|
||||||
--bs-body-font-size: 1rem;
|
|
||||||
--bs-body-font-weight: 400;
|
|
||||||
--bs-body-line-height: 1.5;
|
|
||||||
--bs-body-color: #212529;
|
|
||||||
--bs-body-color-rgb: 33, 37, 41;
|
|
||||||
--bs-body-bg: #fff;
|
|
||||||
--bs-body-bg-rgb: 255, 255, 255;
|
|
||||||
--bs-emphasis-color: #000;
|
|
||||||
--bs-emphasis-color-rgb: 0, 0, 0;
|
|
||||||
--bs-secondary-color: rgba(33, 37, 41, 0.75);
|
|
||||||
--bs-secondary-color-rgb: 33, 37, 41;
|
|
||||||
--bs-secondary-bg: #e9ecef;
|
|
||||||
--bs-secondary-bg-rgb: 233, 236, 239;
|
|
||||||
--bs-tertiary-color: rgba(33, 37, 41, 0.5);
|
|
||||||
--bs-tertiary-color-rgb: 33, 37, 41;
|
|
||||||
--bs-tertiary-bg: #f8f9fa;
|
|
||||||
--bs-tertiary-bg-rgb: 248, 249, 250;
|
|
||||||
--bs-heading-color: inherit;
|
|
||||||
--bs-link-color: #0d6efd;
|
|
||||||
--bs-link-color-rgb: 13, 110, 253;
|
|
||||||
--bs-link-decoration: underline;
|
|
||||||
--bs-link-hover-color: #0a58ca;
|
|
||||||
--bs-link-hover-color-rgb: 10, 88, 202;
|
|
||||||
--bs-code-color: #d63384;
|
|
||||||
--bs-highlight-color: #212529;
|
|
||||||
--bs-highlight-bg: #fff3cd;
|
|
||||||
--bs-border-width: 1px;
|
|
||||||
--bs-border-style: solid;
|
|
||||||
--bs-border-color: #dee2e6;
|
|
||||||
--bs-border-color-translucent: rgba(0, 0, 0, 0.175);
|
|
||||||
--bs-border-radius: 0.375rem;
|
|
||||||
--bs-border-radius-sm: 0.25rem;
|
|
||||||
--bs-border-radius-lg: 0.5rem;
|
|
||||||
--bs-border-radius-xl: 1rem;
|
|
||||||
--bs-border-radius-xxl: 2rem;
|
|
||||||
--bs-border-radius-2xl: var(--bs-border-radius-xxl);
|
|
||||||
--bs-border-radius-pill: 50rem;
|
|
||||||
--bs-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
|
|
||||||
--bs-box-shadow-sm: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
|
|
||||||
--bs-box-shadow-lg: 0 1rem 3rem rgba(0, 0, 0, 0.175);
|
|
||||||
--bs-box-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.075);
|
|
||||||
--bs-focus-ring-width: 0.25rem;
|
|
||||||
--bs-focus-ring-opacity: 0.25;
|
|
||||||
--bs-focus-ring-color: rgba(13, 110, 253, 0.25);
|
|
||||||
--bs-form-valid-color: #198754;
|
|
||||||
--bs-form-valid-border-color: #198754;
|
|
||||||
--bs-form-invalid-color: #dc3545;
|
|
||||||
--bs-form-invalid-border-color: #dc3545;
|
|
||||||
}
|
|
||||||
|
|
||||||
[data-bs-theme=dark] {
|
|
||||||
color-scheme: dark;
|
|
||||||
--bs-body-color: #dee2e6;
|
|
||||||
--bs-body-color-rgb: 222, 226, 230;
|
|
||||||
--bs-body-bg: #212529;
|
|
||||||
--bs-body-bg-rgb: 33, 37, 41;
|
|
||||||
--bs-emphasis-color: #fff;
|
|
||||||
--bs-emphasis-color-rgb: 255, 255, 255;
|
|
||||||
--bs-secondary-color: rgba(222, 226, 230, 0.75);
|
|
||||||
--bs-secondary-color-rgb: 222, 226, 230;
|
|
||||||
--bs-secondary-bg: #343a40;
|
|
||||||
--bs-secondary-bg-rgb: 52, 58, 64;
|
|
||||||
--bs-tertiary-color: rgba(222, 226, 230, 0.5);
|
|
||||||
--bs-tertiary-color-rgb: 222, 226, 230;
|
|
||||||
--bs-tertiary-bg: #2b3035;
|
|
||||||
--bs-tertiary-bg-rgb: 43, 48, 53;
|
|
||||||
--bs-primary-text-emphasis: #6ea8fe;
|
|
||||||
--bs-secondary-text-emphasis: #a7acb1;
|
|
||||||
--bs-success-text-emphasis: #75b798;
|
|
||||||
--bs-info-text-emphasis: #6edff6;
|
|
||||||
--bs-warning-text-emphasis: #ffda6a;
|
|
||||||
--bs-danger-text-emphasis: #ea868f;
|
|
||||||
--bs-light-text-emphasis: #f8f9fa;
|
|
||||||
--bs-dark-text-emphasis: #dee2e6;
|
|
||||||
--bs-primary-bg-subtle: #031633;
|
|
||||||
--bs-secondary-bg-subtle: #161719;
|
|
||||||
--bs-success-bg-subtle: #051b11;
|
|
||||||
--bs-info-bg-subtle: #032830;
|
|
||||||
--bs-warning-bg-subtle: #332701;
|
|
||||||
--bs-danger-bg-subtle: #2c0b0e;
|
|
||||||
--bs-light-bg-subtle: #343a40;
|
|
||||||
--bs-dark-bg-subtle: #1a1d20;
|
|
||||||
--bs-primary-border-subtle: #084298;
|
|
||||||
--bs-secondary-border-subtle: #41464b;
|
|
||||||
--bs-success-border-subtle: #0f5132;
|
|
||||||
--bs-info-border-subtle: #087990;
|
|
||||||
--bs-warning-border-subtle: #997404;
|
|
||||||
--bs-danger-border-subtle: #842029;
|
|
||||||
--bs-light-border-subtle: #495057;
|
|
||||||
--bs-dark-border-subtle: #343a40;
|
|
||||||
--bs-heading-color: inherit;
|
|
||||||
--bs-link-color: #6ea8fe;
|
|
||||||
--bs-link-hover-color: #8bb9fe;
|
|
||||||
--bs-link-color-rgb: 110, 168, 254;
|
|
||||||
--bs-link-hover-color-rgb: 139, 185, 254;
|
|
||||||
--bs-code-color: #e685b5;
|
|
||||||
--bs-highlight-color: #dee2e6;
|
|
||||||
--bs-highlight-bg: #664d03;
|
|
||||||
--bs-border-color: #495057;
|
|
||||||
--bs-border-color-translucent: rgba(255, 255, 255, 0.15);
|
|
||||||
--bs-form-valid-color: #75b798;
|
|
||||||
--bs-form-valid-border-color: #75b798;
|
|
||||||
--bs-form-invalid-color: #ea868f;
|
|
||||||
--bs-form-invalid-border-color: #ea868f;
|
|
||||||
}
|
|
||||||
|
|
||||||
*,
|
|
||||||
*::before,
|
|
||||||
*::after {
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (prefers-reduced-motion: no-preference) {
|
|
||||||
:root {
|
|
||||||
scroll-behavior: smooth;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
font-family: var(--bs-body-font-family);
|
|
||||||
font-size: var(--bs-body-font-size);
|
|
||||||
font-weight: var(--bs-body-font-weight);
|
|
||||||
line-height: var(--bs-body-line-height);
|
|
||||||
color: var(--bs-body-color);
|
|
||||||
text-align: var(--bs-body-text-align);
|
|
||||||
background-color: var(--bs-body-bg);
|
|
||||||
-webkit-text-size-adjust: 100%;
|
|
||||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
hr {
|
|
||||||
margin: 1rem 0;
|
|
||||||
color: inherit;
|
|
||||||
border: 0;
|
|
||||||
border-top: var(--bs-border-width) solid;
|
|
||||||
opacity: 0.25;
|
|
||||||
}
|
|
||||||
|
|
||||||
h6, h5, h4, h3, h2, h1 {
|
|
||||||
margin-top: 0;
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
font-weight: 500;
|
|
||||||
line-height: 1.2;
|
|
||||||
color: var(--bs-heading-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-size: calc(1.375rem + 1.5vw);
|
|
||||||
}
|
|
||||||
@media (min-width: 1200px) {
|
|
||||||
h1 {
|
|
||||||
font-size: 2.5rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
font-size: calc(1.325rem + 0.9vw);
|
|
||||||
}
|
|
||||||
@media (min-width: 1200px) {
|
|
||||||
h2 {
|
|
||||||
font-size: 2rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
h3 {
|
|
||||||
font-size: calc(1.3rem + 0.6vw);
|
|
||||||
}
|
|
||||||
@media (min-width: 1200px) {
|
|
||||||
h3 {
|
|
||||||
font-size: 1.75rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
h4 {
|
|
||||||
font-size: calc(1.275rem + 0.3vw);
|
|
||||||
}
|
|
||||||
@media (min-width: 1200px) {
|
|
||||||
h4 {
|
|
||||||
font-size: 1.5rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
h5 {
|
|
||||||
font-size: 1.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
h6 {
|
|
||||||
font-size: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
margin-top: 0;
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
abbr[title] {
|
|
||||||
-webkit-text-decoration: underline dotted;
|
|
||||||
text-decoration: underline dotted;
|
|
||||||
cursor: help;
|
|
||||||
-webkit-text-decoration-skip-ink: none;
|
|
||||||
text-decoration-skip-ink: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
address {
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
font-style: normal;
|
|
||||||
line-height: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
ol,
|
|
||||||
ul {
|
|
||||||
padding-right: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
ol,
|
|
||||||
ul,
|
|
||||||
dl {
|
|
||||||
margin-top: 0;
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
ol ol,
|
|
||||||
ul ul,
|
|
||||||
ol ul,
|
|
||||||
ul ol {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
dt {
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
|
|
||||||
dd {
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
margin-right: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
blockquote {
|
|
||||||
margin: 0 0 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
b,
|
|
||||||
strong {
|
|
||||||
font-weight: bolder;
|
|
||||||
}
|
|
||||||
|
|
||||||
small {
|
|
||||||
font-size: 0.875em;
|
|
||||||
}
|
|
||||||
|
|
||||||
mark {
|
|
||||||
padding: 0.1875em;
|
|
||||||
color: var(--bs-highlight-color);
|
|
||||||
background-color: var(--bs-highlight-bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
sub,
|
|
||||||
sup {
|
|
||||||
position: relative;
|
|
||||||
font-size: 0.75em;
|
|
||||||
line-height: 0;
|
|
||||||
vertical-align: baseline;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub {
|
|
||||||
bottom: -0.25em;
|
|
||||||
}
|
|
||||||
|
|
||||||
sup {
|
|
||||||
top: -0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1));
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
a:hover {
|
|
||||||
--bs-link-color-rgb: var(--bs-link-hover-color-rgb);
|
|
||||||
}
|
|
||||||
|
|
||||||
a:not([href]):not([class]), a:not([href]):not([class]):hover {
|
|
||||||
color: inherit;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre,
|
|
||||||
code,
|
|
||||||
kbd,
|
|
||||||
samp {
|
|
||||||
font-family: var(--bs-font-monospace);
|
|
||||||
font-size: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre {
|
|
||||||
display: block;
|
|
||||||
margin-top: 0;
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
overflow: auto;
|
|
||||||
font-size: 0.875em;
|
|
||||||
}
|
|
||||||
pre code {
|
|
||||||
font-size: inherit;
|
|
||||||
color: inherit;
|
|
||||||
word-break: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
code {
|
|
||||||
font-size: 0.875em;
|
|
||||||
color: var(--bs-code-color);
|
|
||||||
word-wrap: break-word;
|
|
||||||
}
|
|
||||||
a > code {
|
|
||||||
color: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
kbd {
|
|
||||||
padding: 0.1875rem 0.375rem;
|
|
||||||
font-size: 0.875em;
|
|
||||||
color: var(--bs-body-bg);
|
|
||||||
background-color: var(--bs-body-color);
|
|
||||||
border-radius: 0.25rem;
|
|
||||||
}
|
|
||||||
kbd kbd {
|
|
||||||
padding: 0;
|
|
||||||
font-size: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
figure {
|
|
||||||
margin: 0 0 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
img,
|
|
||||||
svg {
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
table {
|
|
||||||
caption-side: bottom;
|
|
||||||
border-collapse: collapse;
|
|
||||||
}
|
|
||||||
|
|
||||||
caption {
|
|
||||||
padding-top: 0.5rem;
|
|
||||||
padding-bottom: 0.5rem;
|
|
||||||
color: var(--bs-secondary-color);
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
th {
|
|
||||||
text-align: inherit;
|
|
||||||
text-align: -webkit-match-parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
thead,
|
|
||||||
tbody,
|
|
||||||
tfoot,
|
|
||||||
tr,
|
|
||||||
td,
|
|
||||||
th {
|
|
||||||
border-color: inherit;
|
|
||||||
border-style: solid;
|
|
||||||
border-width: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
label {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
border-radius: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
button:focus:not(:focus-visible) {
|
|
||||||
outline: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
input,
|
|
||||||
button,
|
|
||||||
select,
|
|
||||||
optgroup,
|
|
||||||
textarea {
|
|
||||||
margin: 0;
|
|
||||||
font-family: inherit;
|
|
||||||
font-size: inherit;
|
|
||||||
line-height: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
button,
|
|
||||||
select {
|
|
||||||
text-transform: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
[role=button] {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
select {
|
|
||||||
word-wrap: normal;
|
|
||||||
}
|
|
||||||
select:disabled {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
button,
|
|
||||||
[type=button],
|
|
||||||
[type=reset],
|
|
||||||
[type=submit] {
|
|
||||||
-webkit-appearance: button;
|
|
||||||
}
|
|
||||||
button:not(:disabled),
|
|
||||||
[type=button]:not(:disabled),
|
|
||||||
[type=reset]:not(:disabled),
|
|
||||||
[type=submit]:not(:disabled) {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
::-moz-focus-inner {
|
|
||||||
padding: 0;
|
|
||||||
border-style: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
textarea {
|
|
||||||
resize: vertical;
|
|
||||||
}
|
|
||||||
|
|
||||||
fieldset {
|
|
||||||
min-width: 0;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
border: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
legend {
|
|
||||||
float: right;
|
|
||||||
width: 100%;
|
|
||||||
padding: 0;
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
font-size: calc(1.275rem + 0.3vw);
|
|
||||||
line-height: inherit;
|
|
||||||
}
|
|
||||||
@media (min-width: 1200px) {
|
|
||||||
legend {
|
|
||||||
font-size: 1.5rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
legend + * {
|
|
||||||
clear: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-datetime-edit-fields-wrapper,
|
|
||||||
::-webkit-datetime-edit-text,
|
|
||||||
::-webkit-datetime-edit-minute,
|
|
||||||
::-webkit-datetime-edit-hour-field,
|
|
||||||
::-webkit-datetime-edit-day-field,
|
|
||||||
::-webkit-datetime-edit-month-field,
|
|
||||||
::-webkit-datetime-edit-year-field {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-inner-spin-button {
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
[type=search] {
|
|
||||||
-webkit-appearance: textfield;
|
|
||||||
outline-offset: -2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
[type="tel"],
|
|
||||||
[type="url"],
|
|
||||||
[type="email"],
|
|
||||||
[type="number"] {
|
|
||||||
direction: ltr;
|
|
||||||
}
|
|
||||||
::-webkit-search-decoration {
|
|
||||||
-webkit-appearance: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-color-swatch-wrapper {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-file-upload-button {
|
|
||||||
font: inherit;
|
|
||||||
-webkit-appearance: button;
|
|
||||||
}
|
|
||||||
|
|
||||||
::file-selector-button {
|
|
||||||
font: inherit;
|
|
||||||
-webkit-appearance: button;
|
|
||||||
}
|
|
||||||
|
|
||||||
output {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
iframe {
|
|
||||||
border: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
summary {
|
|
||||||
display: list-item;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
progress {
|
|
||||||
vertical-align: baseline;
|
|
||||||
}
|
|
||||||
|
|
||||||
[hidden] {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
/*# sourceMappingURL=bootstrap-reboot.rtl.css.map */
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
12057
app/static/libjs/bootstrap-5.3.3-dist/css/bootstrap.css
vendored
12057
app/static/libjs/bootstrap-5.3.3-dist/css/bootstrap.css
vendored
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
12030
app/static/libjs/bootstrap-5.3.3-dist/css/bootstrap.rtl.css
vendored
12030
app/static/libjs/bootstrap-5.3.3-dist/css/bootstrap.rtl.css
vendored
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
4494
app/static/libjs/bootstrap-5.3.3-dist/js/bootstrap.js
vendored
4494
app/static/libjs/bootstrap-5.3.3-dist/js/bootstrap.js
vendored
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,44 +0,0 @@
|
|||||||
/**
|
|
||||||
* Bootstrap Multiselect (http://davidstutz.de/bootstrap-multiselect/)
|
|
||||||
*
|
|
||||||
* Apache License, Version 2.0:
|
|
||||||
* Copyright (c) 2012 - 2022 David Stutz
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
|
||||||
* use this file except in compliance with the License. You may obtain a
|
|
||||||
* copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* BSD 3-Clause License:
|
|
||||||
* Copyright (c) 2012 - 2022 David Stutz
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
* - Redistributions of source code must retain the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer.
|
|
||||||
* - Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer in the documentation
|
|
||||||
* and/or other materials provided with the distribution.
|
|
||||||
* - Neither the name of David Stutz nor the names of its contributors may be
|
|
||||||
* used to endorse or promote products derived from this software without
|
|
||||||
* specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
||||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
|
||||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
||||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
|
||||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
||||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
|
||||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
|
||||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
span.multiselect-native-select{position:relative}span.multiselect-native-select select{border:0!important;clip:rect(0 0 0 0)!important;height:1px!important;margin:-1px -1px -1px -3px!important;overflow:hidden!important;padding:0!important;position:absolute!important;width:1px!important;left:50%;top:30px}.multiselect.dropdown-toggle:after{display:none}.multiselect{overflow:hidden;text-overflow:ellipsis}.multiselect-container{position:absolute;list-style-type:none;margin:0;padding:0}.multiselect-container .multiselect-reset .input-group{width:93%}.multiselect-container .multiselect-filter>.fa-search{z-index:1;padding-left:.75rem}.multiselect-container .multiselect-filter>input.multiselect-search{border:none;border-bottom:1px solid #d3d3d3;padding-left:2rem;margin-left:-1.625rem;border-bottom-right-radius:0;border-bottom-left-radius:0}.multiselect-container .multiselect-filter>input.multiselect-search:focus{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.multiselect-container .multiselect-filter>.multiselect-moz-clear-filter{margin-left:-1.5rem;display:none}.multiselect-container .multiselect-option.multiselect-group-option-indented-full{padding-left:2.6rem}.multiselect-container .multiselect-option.multiselect-group-option-indented{padding-left:1.8rem}.multiselect-container .multiselect-group{cursor:pointer}.multiselect-container .multiselect-group.closed .dropdown-toggle::after{transform:rotate(-90deg)}.multiselect-container .multiselect-group .caret-container~.form-check{margin-left:.5rem}.multiselect-container .multiselect-all,.multiselect-container .multiselect-group,.multiselect-container .multiselect-option{padding:.25rem .25rem .25rem .75rem}.multiselect-container .multiselect-all.dropdown-item,.multiselect-container .multiselect-all.dropdown-toggle,.multiselect-container .multiselect-group.dropdown-item,.multiselect-container .multiselect-group.dropdown-toggle,.multiselect-container .multiselect-option.dropdown-item,.multiselect-container .multiselect-option.dropdown-toggle{cursor:pointer}.multiselect-container .multiselect-all .form-check-label,.multiselect-container .multiselect-group .form-check-label,.multiselect-container .multiselect-option .form-check-label{cursor:pointer}.multiselect-container .multiselect-all.active:not(.multiselect-active-item-fallback),.multiselect-container .multiselect-all:not(.multiselect-active-item-fallback):active,.multiselect-container .multiselect-group.active:not(.multiselect-active-item-fallback),.multiselect-container .multiselect-group:not(.multiselect-active-item-fallback):active,.multiselect-container .multiselect-option.active:not(.multiselect-active-item-fallback),.multiselect-container .multiselect-option:not(.multiselect-active-item-fallback):active{background-color:#d3d3d3;color:#000}.multiselect-container .multiselect-all:focus,.multiselect-container .multiselect-all:hover,.multiselect-container .multiselect-group:focus,.multiselect-container .multiselect-group:hover,.multiselect-container .multiselect-option:focus,.multiselect-container .multiselect-option:hover{background-color:#a9a9a9!important}.multiselect-container .multiselect-all .form-check,.multiselect-container .multiselect-group .form-check,.multiselect-container .multiselect-option .form-check{padding:0 5px 0 20px}.multiselect-container .multiselect-all:focus,.multiselect-container .multiselect-group:focus,.multiselect-container .multiselect-option:focus{outline:0}.form-inline .multiselect-container span.form-check{padding:3px 20px 3px 40px}.input-group.input-group-sm>.multiselect-native-select .multiselect{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;padding-right:1.75rem;height:calc(1.5em + .5rem + 2px)}.input-group>.multiselect-native-select{flex:1 1 auto;width:1%}.input-group>.multiselect-native-select>div.btn-group{width:100%}.input-group>.multiselect-native-select:not(:first-child) .multiselect{border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.multiselect-native-select:not(:last-child) .multiselect{border-top-right-radius:0;border-bottom-right-radius:0}
|
|
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
|||||||
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="./favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Scodoc Mobile"/><link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"><link rel="apple-touch-icon" href="./scologo.png"/><link rel="manifest" href="./manifest.json"/><title>Scodoc Mobile</title><link href="./static/css/2.4c97ca4f.chunk.css" rel="stylesheet"><link href="./static/css/main.6be5a531.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(e){function r(r){for(var n,i,a=r[0],c=r[1],l=r[2],s=0,p=[];s<a.length;s++)i=a[s],Object.prototype.hasOwnProperty.call(o,i)&&o[i]&&p.push(o[i][0]),o[i]=0;for(n in c)Object.prototype.hasOwnProperty.call(c,n)&&(e[n]=c[n]);for(f&&f(r);p.length;)p.shift()();return u.push.apply(u,l||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,a=1;a<t.length;a++){var c=t[a];0!==o[c]&&(n=!1)}n&&(u.splice(r--,1),e=i(i.s=t[0]))}return e}var n={},o={1:0},u=[];function i(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,i),t.l=!0,t.exports}i.e=function(e){var r=[],t=o[e];if(0!==t)if(t)r.push(t[2]);else{var n=new Promise((function(r,n){t=o[e]=[r,n]}));r.push(t[2]=n);var u,a=document.createElement("script");a.charset="utf-8",a.timeout=120,i.nc&&a.setAttribute("nonce",i.nc),a.src=function(e){return i.p+"static/js/"+({}[e]||e)+"."+{3:"b810fcea"}[e]+".chunk.js"}(e);var c=new Error;u=function(r){a.onerror=a.onload=null,clearTimeout(l);var t=o[e];if(0!==t){if(t){var n=r&&("load"===r.type?"missing":r.type),u=r&&r.target&&r.target.src;c.message="Loading chunk "+e+" failed.\n("+n+": "+u+")",c.name="ChunkLoadError",c.type=n,c.request=u,t[1](c)}o[e]=void 0}};var l=setTimeout((function(){u({type:"timeout",target:a})}),12e4);a.onerror=a.onload=u,document.head.appendChild(a)}return Promise.all(r)},i.m=e,i.c=n,i.d=function(e,r,t){i.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,r){if(1&r&&(e=i(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(i.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)i.d(t,n,function(r){return e[r]}.bind(null,n));return t},i.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(r,"a",r),r},i.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},i.p="./",i.oe=function(e){throw console.error(e),e};var a=this.webpackJsonpscodocmobile=this.webpackJsonpscodocmobile||[],c=a.push.bind(a);a.push=r,a=a.slice();for(var l=0;l<a.length;l++)r(a[l]);var f=c;t()}([])</script><script src="./static/js/2.fb06b1f5.chunk.js"></script><script src="./static/js/main.1a008285.chunk.js"></script></body></html>
|
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="./favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Scodoc Mobile"/><link rel="apple-touch-icon" href="./scologo.png"/><link rel="manifest" href="./manifest.json"/><title>Scodoc Mobile</title><link href="./static/css/2.4c97ca4f.chunk.css" rel="stylesheet"><link href="./static/css/main.6be5a531.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(e){function r(r){for(var n,i,a=r[0],c=r[1],l=r[2],s=0,p=[];s<a.length;s++)i=a[s],Object.prototype.hasOwnProperty.call(o,i)&&o[i]&&p.push(o[i][0]),o[i]=0;for(n in c)Object.prototype.hasOwnProperty.call(c,n)&&(e[n]=c[n]);for(f&&f(r);p.length;)p.shift()();return u.push.apply(u,l||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,a=1;a<t.length;a++){var c=t[a];0!==o[c]&&(n=!1)}n&&(u.splice(r--,1),e=i(i.s=t[0]))}return e}var n={},o={1:0},u=[];function i(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,i),t.l=!0,t.exports}i.e=function(e){var r=[],t=o[e];if(0!==t)if(t)r.push(t[2]);else{var n=new Promise((function(r,n){t=o[e]=[r,n]}));r.push(t[2]=n);var u,a=document.createElement("script");a.charset="utf-8",a.timeout=120,i.nc&&a.setAttribute("nonce",i.nc),a.src=function(e){return i.p+"static/js/"+({}[e]||e)+"."+{3:"b810fcea"}[e]+".chunk.js"}(e);var c=new Error;u=function(r){a.onerror=a.onload=null,clearTimeout(l);var t=o[e];if(0!==t){if(t){var n=r&&("load"===r.type?"missing":r.type),u=r&&r.target&&r.target.src;c.message="Loading chunk "+e+" failed.\n("+n+": "+u+")",c.name="ChunkLoadError",c.type=n,c.request=u,t[1](c)}o[e]=void 0}};var l=setTimeout((function(){u({type:"timeout",target:a})}),12e4);a.onerror=a.onload=u,document.head.appendChild(a)}return Promise.all(r)},i.m=e,i.c=n,i.d=function(e,r,t){i.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,r){if(1&r&&(e=i(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(i.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)i.d(t,n,function(r){return e[r]}.bind(null,n));return t},i.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(r,"a",r),r},i.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},i.p="./",i.oe=function(e){throw console.error(e),e};var a=this.webpackJsonpscodocmobile=this.webpackJsonpscodocmobile||[],c=a.push.bind(a);a.push=r,a=a.slice();for(var l=0;l<a.length;l++)r(a[l]);var f=c;t()}([])</script><script src="./static/js/2.fb06b1f5.chunk.js"></script><script src="./static/js/main.1a008285.chunk.js"></script></body></html>
|
@ -102,7 +102,6 @@
|
|||||||
|
|
||||||
{% block styles %}
|
{% block styles %}
|
||||||
{{ super() }}
|
{{ super() }}
|
||||||
{# <link rel="stylesheet" href="{{scu.STATIC_DIR}}/libjs/bootstrap/css/bootstrap.min.css"> #}
|
|
||||||
<link rel="stylesheet" href="{{scu.STATIC_DIR}}/css/assiduites.css">
|
<link rel="stylesheet" href="{{scu.STATIC_DIR}}/css/assiduites.css">
|
||||||
<link rel="stylesheet" href="{{scu.STATIC_DIR}}/css/minitimeline.css">
|
<link rel="stylesheet" href="{{scu.STATIC_DIR}}/css/minitimeline.css">
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
<br />
|
<br />
|
||||||
Ces utilisateurs peuvent être réactivés à tout moment.
|
Ces utilisateurs peuvent être réactivés à tout moment.
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row space-before-24">
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
{{ wtf.quick_form(form, button_map={'submit':'secondary'}) }}
|
{{ wtf.quick_form(form, button_map={'submit':'secondary'}) }}
|
||||||
</div>
|
</div>
|
||||||
|
@ -14,9 +14,6 @@
|
|||||||
href="{{scu.STATIC_DIR}}/libjs/jquery-ui-1.10.4.custom/css/smoothness/jquery-ui-1.10.4.custom.min.css" />
|
href="{{scu.STATIC_DIR}}/libjs/jquery-ui-1.10.4.custom/css/smoothness/jquery-ui-1.10.4.custom.min.css" />
|
||||||
<link type="text/css" rel="stylesheet"
|
<link type="text/css" rel="stylesheet"
|
||||||
href="{{scu.STATIC_DIR}}/libjs/timepicker-1.3.5/jquery.timepicker.min.css" />
|
href="{{scu.STATIC_DIR}}/libjs/timepicker-1.3.5/jquery.timepicker.min.css" />
|
||||||
<!-- Bootstrap -->
|
|
||||||
<link href="{{scu.STATIC_DIR}}/libjs/bootstrap/css/bootstrap.css" rel="stylesheet">
|
|
||||||
<link type="text/css" rel="stylesheet" href="{{scu.STATIC_DIR}}/libjs/bootstrap-multiselect-1.1.2/bootstrap-multiselect.min.css">
|
|
||||||
{% for css in cssstyles %}
|
{% for css in cssstyles %}
|
||||||
<link rel="stylesheet" href="{{scu.STATIC_DIR}}/{{css}}">
|
<link rel="stylesheet" href="{{scu.STATIC_DIR}}/{{css}}">
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
@ -35,8 +32,6 @@
|
|||||||
<script src="{{scu.STATIC_DIR}}/jQuery/jquery-migrate-3.5.2.min.js"></script>
|
<script src="{{scu.STATIC_DIR}}/jQuery/jquery-migrate-3.5.2.min.js"></script>
|
||||||
<script src="{{scu.STATIC_DIR}}/libjs/jquery.field.min.js"></script>
|
<script src="{{scu.STATIC_DIR}}/libjs/jquery.field.min.js"></script>
|
||||||
<script src="{{scu.STATIC_DIR}}/libjs/jquery-ui-1.10.4.custom/js/jquery-ui-1.10.4.custom.min.js"></script>
|
<script src="{{scu.STATIC_DIR}}/libjs/jquery-ui-1.10.4.custom/js/jquery-ui-1.10.4.custom.min.js"></script>
|
||||||
<script src="{{scu.STATIC_DIR}}/libjs/bootstrap/js/bootstrap.min.js"></script>
|
|
||||||
<script src="{{scu.STATIC_DIR}}/libjs/bootstrap-multiselect-1.1.2/bootstrap-multiselect.min.js"></script>
|
|
||||||
<script src="{{scu.STATIC_DIR}}/libjs/timepicker-1.3.5/jquery.timepicker.min.js"></script>
|
<script src="{{scu.STATIC_DIR}}/libjs/timepicker-1.3.5/jquery.timepicker.min.js"></script>
|
||||||
<script src="{{scu.STATIC_DIR}}/libjs/qtip/jquery.qtip-3.0.3.min.js"></script>
|
<script src="{{scu.STATIC_DIR}}/libjs/qtip/jquery.qtip-3.0.3.min.js"></script>
|
||||||
<script src="{{scu.STATIC_DIR}}/libjs/purl.js"></script>
|
<script src="{{scu.STATIC_DIR}}/libjs/purl.js"></script>
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
{% block styles %}
|
{% block styles %}
|
||||||
{{super()}}
|
{{super()}}
|
||||||
<link rel="stylesheet" href="{{ scu.STATIC_DIR }}/css/scodoc.css">
|
<link rel="stylesheet" href="{{ scu.STATIC_DIR }}/css/scodoc.css">
|
||||||
|
<link rel="stylesheet" href="{{ scu.STATIC_DIR }}/css/scodoc97.css">
|
||||||
<link rel="stylesheet" href="{{ scu.STATIC_DIR }}/css/entreprises.css">
|
<link rel="stylesheet" href="{{ scu.STATIC_DIR }}/css/entreprises.css">
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
{% extends 'sco_page.j2' %}
|
||||||
|
|
||||||
{% import 'wtf.j2' as wtf %}
|
{% import 'wtf.j2' as wtf %}
|
||||||
|
|
||||||
{% macro render_field(field) %}
|
{% macro render_field(field) %}
|
||||||
@ -15,6 +17,12 @@
|
|||||||
</tr>
|
</tr>
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
|
{% block app_content %}
|
||||||
|
|
||||||
|
{{ evaluations_description|safe}}
|
||||||
|
|
||||||
|
<h3 class="space-before-24">Placement et émargement des étudiants</h3>
|
||||||
|
|
||||||
<div class="saisienote_etape1 form_placement">
|
<div class="saisienote_etape1 form_placement">
|
||||||
<form method=post>
|
<form method=post>
|
||||||
{{ form.evaluation_id }}
|
{{ form.evaluation_id }}
|
||||||
@ -78,3 +86,4 @@
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
{% endblock %}
|
@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
{% block styles %}
|
{% block styles %}
|
||||||
{{super()}}
|
{{super()}}
|
||||||
<link rel="stylesheet" href="{{scu.STATIC_DIR}}/libjs/bootstrap/css/bootstrap.min.css">
|
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
div{
|
div{
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{# -*- mode: jinja-html -*- #}
|
{# -*- mode: jinja-html -*- #}
|
||||||
{% extends 'base.j2' %}
|
{% extends 'sco_page.j2' %}
|
||||||
|
|
||||||
{% block app_content %}
|
{% block app_content %}
|
||||||
|
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
{% macro form_errors(form, hiddens=True) %}
|
{% macro form_errors(form, hiddens=True) %}
|
||||||
{%- if form.errors %}
|
{%- if form.errors %}
|
||||||
{%- for fieldname, errors in form.errors.items() %}
|
{%- for fieldname, errors in form.errors.items() %}
|
||||||
{%- if bootstrap_is_hidden_field(form[fieldname]) and hiddens or
|
{%- if is_hidden_field(form[fieldname]) and hiddens or
|
||||||
not bootstrap_is_hidden_field(form[fieldname]) and hiddens != 'only' %}
|
not is_hidden_field(form[fieldname]) and hiddens != 'only' %}
|
||||||
{%- for error in errors %}
|
{%- for error in errors %}
|
||||||
<p class="error">{{error}}</p>
|
<p class="error">{{error}}</p>
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
@ -75,7 +75,7 @@ the necessary fix for required=False attributes, but will also not set the requi
|
|||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>{{field.label}}</legend>
|
<legend>{{field.label}}</legend>
|
||||||
{%- for subfield in field %}
|
{%- for subfield in field %}
|
||||||
{% if not bootstrap_is_hidden_field(subfield) -%}
|
{% if not is_hidden_field(subfield) -%}
|
||||||
{{ form_field(subfield,
|
{{ form_field(subfield,
|
||||||
form_type=form_type,
|
form_type=form_type,
|
||||||
horizontal_columns=horizontal_columns,
|
horizontal_columns=horizontal_columns,
|
||||||
@ -202,7 +202,7 @@ action="" is what we want, from http://www.ietf.org/rfc/rfc2396.txt:
|
|||||||
{{ form_errors(form, hiddens='only') }}
|
{{ form_errors(form, hiddens='only') }}
|
||||||
|
|
||||||
{%- for field in form %}
|
{%- for field in form %}
|
||||||
{% if not bootstrap_is_hidden_field(field) -%}
|
{% if not is_hidden_field(field) -%}
|
||||||
{{ form_field(field,
|
{{ form_field(field,
|
||||||
form_type=form_type,
|
form_type=form_type,
|
||||||
horizontal_columns=horizontal_columns,
|
horizontal_columns=horizontal_columns,
|
||||||
|
@ -24,7 +24,8 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Module absences: remplacé par assiduité en août 2023, reste ici seulement la gestion des "billets"
|
Module absences: remplacé par assiduité en août 2023,
|
||||||
|
reste ici seulement la gestion des "billets"
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -32,8 +33,7 @@ import dateutil
|
|||||||
import dateutil.parser
|
import dateutil.parser
|
||||||
|
|
||||||
import flask
|
import flask
|
||||||
from flask import g, request
|
from flask import abort, flash, g, render_template, request, url_for
|
||||||
from flask import abort, flash, url_for
|
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
|
|
||||||
from app import db, log
|
from app import db, log
|
||||||
@ -54,11 +54,8 @@ from app.scodoc import sco_utils as scu
|
|||||||
from app.scodoc.sco_permissions import Permission
|
from app.scodoc.sco_permissions import Permission
|
||||||
from app.scodoc.sco_exceptions import ScoValueError
|
from app.scodoc.sco_exceptions import ScoValueError
|
||||||
from app.scodoc.TrivialFormulator import TrivialFormulator
|
from app.scodoc.TrivialFormulator import TrivialFormulator
|
||||||
from app.scodoc import html_sco_header
|
|
||||||
from app.scodoc import sco_cal
|
|
||||||
from app.scodoc import sco_assiduites as scass
|
from app.scodoc import sco_assiduites as scass
|
||||||
from app.scodoc import sco_abs_billets
|
from app.scodoc import sco_abs_billets
|
||||||
from app.scodoc import sco_etud
|
|
||||||
from app.scodoc import sco_preferences
|
from app.scodoc import sco_preferences
|
||||||
|
|
||||||
|
|
||||||
@ -77,11 +74,7 @@ from app.scodoc import sco_preferences
|
|||||||
def index_html():
|
def index_html():
|
||||||
"""Gestionnaire absences, page principale"""
|
"""Gestionnaire absences, page principale"""
|
||||||
|
|
||||||
H = [
|
H = []
|
||||||
html_sco_header.sco_header(
|
|
||||||
page_title="Billets d'absences",
|
|
||||||
),
|
|
||||||
]
|
|
||||||
if current_user.has_permission(
|
if current_user.has_permission(
|
||||||
Permission.AbsChange
|
Permission.AbsChange
|
||||||
) and sco_preferences.get_preference("handle_billets_abs"):
|
) and sco_preferences.get_preference("handle_billets_abs"):
|
||||||
@ -93,8 +86,9 @@ def index_html():
|
|||||||
</li></ul>
|
</li></ul>
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
H.append(html_sco_header.sco_footer())
|
return render_template(
|
||||||
return "\n".join(H)
|
"sco_page_dept.j2", title="Billets d'absences", content="\n".join(H)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# ----- Gestion des "billets d'absence": signalement par les etudiants eux mêmes (à travers le portail)
|
# ----- Gestion des "billets d'absence": signalement par les etudiants eux mêmes (à travers le portail)
|
||||||
@ -158,12 +152,8 @@ def add_billets_absence_form(etudid):
|
|||||||
"""Formulaire ajout billet (pour tests seulement, le vrai
|
"""Formulaire ajout billet (pour tests seulement, le vrai
|
||||||
formulaire accessible aux etudiants étant sur le portail étudiant).
|
formulaire accessible aux etudiants étant sur le portail étudiant).
|
||||||
"""
|
"""
|
||||||
etud = sco_etud.get_etud_info(filled=True, etudid=etudid)[0]
|
_ = Identite.get_etud(etudid) # check
|
||||||
H = [
|
H = ["""<h2>Formulaire ajout billet (pour tests)</h2>"""]
|
||||||
html_sco_header.sco_header(
|
|
||||||
page_title="Billet d'absence de %s" % etud["nomprenom"]
|
|
||||||
)
|
|
||||||
]
|
|
||||||
tf = TrivialFormulator(
|
tf = TrivialFormulator(
|
||||||
request.base_url,
|
request.base_url,
|
||||||
scu.get_request_args(),
|
scu.get_request_args(),
|
||||||
@ -179,7 +169,11 @@ def add_billets_absence_form(etudid):
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
if tf[0] == 0:
|
if tf[0] == 0:
|
||||||
return "\n".join(H) + tf[1] + html_sco_header.sco_footer()
|
return render_template(
|
||||||
|
"sco_page_dept.j2",
|
||||||
|
title="""Billet d'absence de {etud["nomprenom"]}""",
|
||||||
|
content="\n".join(H) + tf[1],
|
||||||
|
)
|
||||||
elif tf[0] == -1:
|
elif tf[0] == -1:
|
||||||
return flask.redirect(url_for("scolar.index_html", scodoc_dept=g.scodoc_dept))
|
return flask.redirect(url_for("scolar.index_html", scodoc_dept=g.scodoc_dept))
|
||||||
else:
|
else:
|
||||||
@ -242,11 +236,8 @@ def list_billets():
|
|||||||
et formulaire recherche d'un billet.
|
et formulaire recherche d'un billet.
|
||||||
"""
|
"""
|
||||||
table = sco_abs_billets.table_billets_etud(etat=False)
|
table = sco_abs_billets.table_billets_etud(etat=False)
|
||||||
T = table.html()
|
table_html = table.html()
|
||||||
H = [
|
H = [
|
||||||
html_sco_header.sco_header(
|
|
||||||
page_title="Billet d'absence non traités",
|
|
||||||
),
|
|
||||||
f"<h2>Billets d'absence en attente de traitement ({table.get_nb_rows()})</h2>",
|
f"<h2>Billets d'absence en attente de traitement ({table.get_nb_rows()})</h2>",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -257,15 +248,18 @@ def list_billets():
|
|||||||
submitbutton=False,
|
submitbutton=False,
|
||||||
)
|
)
|
||||||
if tf[0] == 0:
|
if tf[0] == 0:
|
||||||
return "\n".join(H) + tf[1] + T + html_sco_header.sco_footer()
|
return render_template(
|
||||||
else:
|
"sco_page.j2",
|
||||||
return flask.redirect(
|
title="Billet d'absence non traités",
|
||||||
url_for(
|
content="\n".join(H) + tf[1] + table_html,
|
||||||
"absences.process_billet_absence_form",
|
|
||||||
billet_id=tf[2]["billet_id"],
|
|
||||||
scodoc_dept=g.scodoc_dept,
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
return flask.redirect(
|
||||||
|
url_for(
|
||||||
|
"absences.process_billet_absence_form",
|
||||||
|
billet_id=tf[2]["billet_id"],
|
||||||
|
scodoc_dept=g.scodoc_dept,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/delete_billets_absence", methods=["POST", "GET"])
|
@bp.route("/delete_billets_absence", methods=["POST", "GET"])
|
||||||
@ -337,7 +331,8 @@ def _ProcessBilletAbsence(
|
|||||||
def process_billet_absence_form(billet_id: int):
|
def process_billet_absence_form(billet_id: int):
|
||||||
"""Formulaire traitement d'un billet"""
|
"""Formulaire traitement d'un billet"""
|
||||||
if not isinstance(billet_id, int):
|
if not isinstance(billet_id, int):
|
||||||
raise abort(404, "billet_id invalide")
|
abort(404, "billet_id invalide")
|
||||||
|
return # safety guard
|
||||||
billet: BilletAbsence = (
|
billet: BilletAbsence = (
|
||||||
BilletAbsence.query.filter_by(id=billet_id)
|
BilletAbsence.query.filter_by(id=billet_id)
|
||||||
.join(Identite)
|
.join(Identite)
|
||||||
@ -352,9 +347,6 @@ def process_billet_absence_form(billet_id: int):
|
|||||||
etud = billet.etudiant
|
etud = billet.etudiant
|
||||||
|
|
||||||
H = [
|
H = [
|
||||||
html_sco_header.sco_header(
|
|
||||||
page_title=f"Traitement billet d'absence de {etud.nomprenom}",
|
|
||||||
),
|
|
||||||
f"""<h2>Traitement du billet {billet.id} : <a class="discretelink" href="{
|
f"""<h2>Traitement du billet {billet.id} : <a class="discretelink" href="{
|
||||||
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etud.id)
|
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etud.id)
|
||||||
}">{etud.nomprenom}</a></h2>
|
}">{etud.nomprenom}</a></h2>
|
||||||
@ -403,7 +395,11 @@ def process_billet_absence_form(billet_id: int):
|
|||||||
</p>
|
</p>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return "\n".join(H) + "<br>" + tf[1] + F + html_sco_header.sco_footer()
|
return render_template(
|
||||||
|
"sco_page.j2",
|
||||||
|
title=f"Traitement billet d'absence de {etud.nomprenom}",
|
||||||
|
content="\n".join(H) + "<br>" + tf[1] + F,
|
||||||
|
)
|
||||||
elif tf[0] == -1:
|
elif tf[0] == -1:
|
||||||
return flask.redirect(url_for("scolar.index_html", scodoc_dept=g.scodoc_dept))
|
return flask.redirect(url_for("scolar.index_html", scodoc_dept=g.scodoc_dept))
|
||||||
else:
|
else:
|
||||||
@ -414,7 +410,7 @@ def process_billet_absence_form(billet_id: int):
|
|||||||
j = "non justifiées"
|
j = "non justifiées"
|
||||||
H.append('<div class="head_message">')
|
H.append('<div class="head_message">')
|
||||||
if n > 0:
|
if n > 0:
|
||||||
H.append("%d absences (1/2 journées) %s ajoutées" % (n, j))
|
H.append(f"{n} absences (1/2 journées) {j} ajoutées")
|
||||||
elif n == 0:
|
elif n == 0:
|
||||||
H.append("Aucun jour d'absence dans les dates indiquées !")
|
H.append("Aucun jour d'absence dans les dates indiquées !")
|
||||||
elif n < 0:
|
elif n < 0:
|
||||||
@ -434,4 +430,8 @@ def process_billet_absence_form(billet_id: int):
|
|||||||
)
|
)
|
||||||
tab = sco_abs_billets.table_billets(billets, etud=etud)
|
tab = sco_abs_billets.table_billets(billets, etud=etud)
|
||||||
H.append(tab.html())
|
H.append(tab.html())
|
||||||
return "\n".join(H) + html_sco_header.sco_footer()
|
return render_template(
|
||||||
|
"sco_page.j2",
|
||||||
|
title=f"Traitement billet d'absence de {etud.nomprenom}",
|
||||||
|
content="\n".join(H),
|
||||||
|
)
|
||||||
|
@ -96,9 +96,6 @@ from app.tables.visu_assiduites import TableAssi, etuds_sorted_from_ids
|
|||||||
from app.scodoc.sco_archives_justificatifs import JustificatifArchiver
|
from app.scodoc.sco_archives_justificatifs import JustificatifArchiver
|
||||||
|
|
||||||
|
|
||||||
CSSSTYLES = html_sco_header.BOOTSTRAP_CSS
|
|
||||||
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------
|
# --------------------------------------------------------------------
|
||||||
#
|
#
|
||||||
# Assiduité (/ScoDoc/<dept>/Scolarite/Assiduites/...)
|
# Assiduité (/ScoDoc/<dept>/Scolarite/Assiduites/...)
|
||||||
@ -1073,10 +1070,10 @@ def signal_assiduites_group():
|
|||||||
select_all_when_unspecified=True,
|
select_all_when_unspecified=True,
|
||||||
)
|
)
|
||||||
if not groups_infos.members:
|
if not groups_infos.members:
|
||||||
return (
|
return render_template(
|
||||||
html_sco_header.sco_header(page_title="Saisie de l'assiduité")
|
"sco_page.j2",
|
||||||
+ "<h3>Aucun étudiant ! </h3>"
|
title="Saisie de l'assiduité",
|
||||||
+ html_sco_header.sco_footer()
|
content="<h3>Aucun étudiant !</h3>",
|
||||||
)
|
)
|
||||||
|
|
||||||
# --- Filtrage par formsemestre ---
|
# --- Filtrage par formsemestre ---
|
||||||
@ -1952,10 +1949,10 @@ def signal_assiduites_hebdo():
|
|||||||
group_ids, formsemestre_id=formsemestre.id, select_all_when_unspecified=True
|
group_ids, formsemestre_id=formsemestre.id, select_all_when_unspecified=True
|
||||||
)
|
)
|
||||||
if not groups_infos.members:
|
if not groups_infos.members:
|
||||||
return (
|
return render_template(
|
||||||
html_sco_header.sco_header(page_title="Assiduité: saisie hebdomadaire")
|
"sco_page.j2",
|
||||||
+ "<h3>Aucun étudiant ! </h3>"
|
title="Assiduité: feuille saisie hebdomadaire",
|
||||||
+ html_sco_header.sco_footer()
|
content="<h3>Aucun étudiant !</h3>",
|
||||||
)
|
)
|
||||||
|
|
||||||
# Récupération des étudiants
|
# Récupération des étudiants
|
||||||
@ -2305,12 +2302,10 @@ def feuille_abs_hebdo():
|
|||||||
group_ids, formsemestre_id=formsemestre.id, select_all_when_unspecified=True
|
group_ids, formsemestre_id=formsemestre.id, select_all_when_unspecified=True
|
||||||
)
|
)
|
||||||
if not groups_infos.members:
|
if not groups_infos.members:
|
||||||
return (
|
return render_template(
|
||||||
html_sco_header.sco_header(
|
"sco_page.j2",
|
||||||
page_title="Assiduité: feuille saisie hebdomadaire"
|
title="Assiduité: feuille saisie hebdomadaire",
|
||||||
)
|
content="<h3>Aucun étudiant !</h3>",
|
||||||
+ "<h3>Aucun étudiant ! </h3>"
|
|
||||||
+ html_sco_header.sco_footer()
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Gestion des jours
|
# Gestion des jours
|
||||||
|
@ -60,7 +60,6 @@ from app.models import (
|
|||||||
ScoDocSiteConfig,
|
ScoDocSiteConfig,
|
||||||
)
|
)
|
||||||
from app.scodoc import (
|
from app.scodoc import (
|
||||||
html_sco_header,
|
|
||||||
sco_bulletins_json,
|
sco_bulletins_json,
|
||||||
sco_cache,
|
sco_cache,
|
||||||
sco_formsemestre_exterieurs,
|
sco_formsemestre_exterieurs,
|
||||||
@ -251,27 +250,23 @@ def formsemestre_validation_but(
|
|||||||
</div>
|
</div>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
H = [
|
H = ["""<div class="jury_but">"""]
|
||||||
html_sco_header.sco_header(
|
inscription = formsemestre.etuds_inscriptions.get(etudid)
|
||||||
page_title=f"Validation BUT S{formsemestre.semestre_id}",
|
if not inscription:
|
||||||
formsemestre_id=formsemestre_id,
|
raise ScoValueError("étudiant non inscrit au semestre")
|
||||||
etudid=etudid,
|
if inscription.etat != scu.INSCRIT:
|
||||||
|
return render_template(
|
||||||
|
"sco_page.j2",
|
||||||
|
title=f"Validation BUT S{formsemestre.semestre_id}",
|
||||||
|
sco=ScoData(etud=etud, formsemestre=formsemestre),
|
||||||
cssstyles=[
|
cssstyles=[
|
||||||
"css/jury_but.css",
|
"css/jury_but.css",
|
||||||
"css/cursus_but.css",
|
"css/cursus_but.css",
|
||||||
],
|
],
|
||||||
javascripts=("js/jury_but.js",),
|
javascripts=("js/jury_but.js",),
|
||||||
),
|
content=(
|
||||||
"""<div class="jury_but">
|
"\n".join(H)
|
||||||
""",
|
+ f"""
|
||||||
]
|
|
||||||
inscription = formsemestre.etuds_inscriptions.get(etudid)
|
|
||||||
if not inscription:
|
|
||||||
raise ScoValueError("étudiant non inscrit au semestre")
|
|
||||||
if inscription.etat != scu.INSCRIT:
|
|
||||||
return (
|
|
||||||
"\n".join(H)
|
|
||||||
+ f"""
|
|
||||||
<div>
|
<div>
|
||||||
<div class="bull_head">
|
<div class="bull_head">
|
||||||
<div>
|
<div>
|
||||||
@ -291,7 +286,7 @@ def formsemestre_validation_but(
|
|||||||
{navigation_div}
|
{navigation_div}
|
||||||
</div>
|
</div>
|
||||||
"""
|
"""
|
||||||
+ html_sco_header.sco_footer()
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
deca = jury_but.DecisionsProposeesAnnee(etud, formsemestre)
|
deca = jury_but.DecisionsProposeesAnnee(etud, formsemestre)
|
||||||
@ -341,7 +336,7 @@ def formsemestre_validation_but(
|
|||||||
êtes-vous certain de vouloir enregistrer une décision de jury ?
|
êtes-vous certain de vouloir enregistrer une décision de jury ?
|
||||||
</div>"""
|
</div>"""
|
||||||
if read_only:
|
if read_only:
|
||||||
warning += f"""<div class="warning">Affichage en lecture seule</div>"""
|
warning += """<div class="warning">Affichage en lecture seule</div>"""
|
||||||
|
|
||||||
if deca.formsemestre_impair:
|
if deca.formsemestre_impair:
|
||||||
inscription = deca.formsemestre_impair.etuds_inscriptions.get(etud.id)
|
inscription = deca.formsemestre_impair.etuds_inscriptions.get(etud.id)
|
||||||
@ -507,7 +502,17 @@ def formsemestre_validation_but(
|
|||||||
</div>
|
</div>
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
return "\n".join(H) + html_sco_header.sco_footer()
|
return render_template(
|
||||||
|
"sco_page.j2",
|
||||||
|
title=f"Validation BUT S{formsemestre.semestre_id}",
|
||||||
|
sco=ScoData(etud=etud, formsemestre=formsemestre),
|
||||||
|
cssstyles=[
|
||||||
|
"css/jury_but.css",
|
||||||
|
"css/cursus_but.css",
|
||||||
|
],
|
||||||
|
javascripts=("js/jury_but.js",),
|
||||||
|
content="\n".join(H),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@bp.route(
|
@bp.route(
|
||||||
|
@ -88,7 +88,6 @@ from app.scodoc.sco_exceptions import (
|
|||||||
ScoInvalidIdType,
|
ScoInvalidIdType,
|
||||||
)
|
)
|
||||||
from app.scodoc import (
|
from app.scodoc import (
|
||||||
html_sco_header,
|
|
||||||
sco_apogee_compare,
|
sco_apogee_compare,
|
||||||
sco_archives_formsemestre,
|
sco_archives_formsemestre,
|
||||||
sco_assiduites,
|
sco_assiduites,
|
||||||
@ -770,8 +769,10 @@ def formation_import_xml_form():
|
|||||||
cancelbutton="Annuler",
|
cancelbutton="Annuler",
|
||||||
)
|
)
|
||||||
if tf[0] == 0:
|
if tf[0] == 0:
|
||||||
return f"""
|
return render_template(
|
||||||
{ html_sco_header.sco_header(page_title="Import d'une formation") }
|
"sco_page_dept.j2",
|
||||||
|
title="Import d'une formation",
|
||||||
|
content=f"""
|
||||||
<h2>Import d'une formation</h2>
|
<h2>Import d'une formation</h2>
|
||||||
<p>Création d'une formation (avec UE, matières, modules)
|
<p>Création d'une formation (avec UE, matières, modules)
|
||||||
à partir un fichier XML (réservé aux utilisateurs avertis).
|
à partir un fichier XML (réservé aux utilisateurs avertis).
|
||||||
@ -783,8 +784,8 @@ def formation_import_xml_form():
|
|||||||
}">page des référentiels</a>).
|
}">page des référentiels</a>).
|
||||||
</p>
|
</p>
|
||||||
{ tf[1] }
|
{ tf[1] }
|
||||||
{ html_sco_header.sco_footer() }
|
""",
|
||||||
"""
|
)
|
||||||
elif tf[0] == -1:
|
elif tf[0] == -1:
|
||||||
return flask.redirect(url_for("notes.index_html", scodoc_dept=g.scodoc_dept))
|
return flask.redirect(url_for("notes.index_html", scodoc_dept=g.scodoc_dept))
|
||||||
else:
|
else:
|
||||||
@ -792,8 +793,10 @@ def formation_import_xml_form():
|
|||||||
tf[2]["xmlfile"].read()
|
tf[2]["xmlfile"].read()
|
||||||
)
|
)
|
||||||
|
|
||||||
return f"""
|
return render_template(
|
||||||
{ html_sco_header.sco_header(page_title="Import d'une formation") }
|
"sco_page_dept.j2",
|
||||||
|
title="Import d'une formation",
|
||||||
|
content=f"""
|
||||||
<h2>Import effectué !</h2>
|
<h2>Import effectué !</h2>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a class="stdlink" href="{
|
<li><a class="stdlink" href="{
|
||||||
@ -806,8 +809,8 @@ def formation_import_xml_form():
|
|||||||
(en cas d'erreur, par exemple pour charger auparavant le référentiel de compétences)
|
(en cas d'erreur, par exemple pour charger auparavant le référentiel de compétences)
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
{ html_sco_header.sco_footer() }
|
""",
|
||||||
"""
|
)
|
||||||
|
|
||||||
|
|
||||||
sco_publish("/module_move", sco_edit_formation.module_move, Permission.EditFormation)
|
sco_publish("/module_move", sco_edit_formation.module_move, Permission.EditFormation)
|
||||||
@ -2182,15 +2185,17 @@ def formsemestre_bulletins_mailetuds(
|
|||||||
if sent:
|
if sent:
|
||||||
nb_sent += 1
|
nb_sent += 1
|
||||||
#
|
#
|
||||||
return f"""
|
return render_template(
|
||||||
{html_sco_header.sco_header()}
|
"sco_page.j2",
|
||||||
|
title="Mailing bulletins",
|
||||||
|
content=f"""
|
||||||
<p>{nb_sent} bulletins sur {len(inscriptions)} envoyés par mail !</p>
|
<p>{nb_sent} bulletins sur {len(inscriptions)} envoyés par mail !</p>
|
||||||
<p><a class="stdlink" href="{url_for('notes.formsemestre_status',
|
<p><a class="stdlink" href="{url_for('notes.formsemestre_status',
|
||||||
scodoc_dept=g.scodoc_dept,
|
scodoc_dept=g.scodoc_dept,
|
||||||
formsemestre_id=formsemestre_id)
|
formsemestre_id=formsemestre_id)
|
||||||
}">continuer</a></p>
|
}">continuer</a></p>
|
||||||
{html_sco_header.sco_footer()}
|
""",
|
||||||
"""
|
)
|
||||||
|
|
||||||
|
|
||||||
sco_publish(
|
sco_publish(
|
||||||
@ -2258,10 +2263,8 @@ def appreciation_add_form(
|
|||||||
else:
|
else:
|
||||||
action = "Ajout"
|
action = "Ajout"
|
||||||
H = [
|
H = [
|
||||||
html_sco_header.sco_header(),
|
|
||||||
f"""<h2>{action} d'une appréciation sur {etud.nomprenom}</h2>""",
|
f"""<h2>{action} d'une appréciation sur {etud.nomprenom}</h2>""",
|
||||||
]
|
]
|
||||||
F = html_sco_header.sco_footer()
|
|
||||||
descr = [
|
descr = [
|
||||||
("edit", {"input_type": "hidden", "default": edit}),
|
("edit", {"input_type": "hidden", "default": edit}),
|
||||||
("etudid", {"input_type": "hidden"}),
|
("etudid", {"input_type": "hidden"}),
|
||||||
@ -2286,7 +2289,7 @@ def appreciation_add_form(
|
|||||||
submitlabel="Ajouter appréciation",
|
submitlabel="Ajouter appréciation",
|
||||||
)
|
)
|
||||||
if tf[0] == 0:
|
if tf[0] == 0:
|
||||||
return "\n".join(H) + "\n" + tf[1] + F
|
return render_template("sco_page.j2", content="\n".join(H) + "\n" + tf[1])
|
||||||
elif tf[0] == -1:
|
elif tf[0] == -1:
|
||||||
return flask.redirect(bul_url)
|
return flask.redirect(bul_url)
|
||||||
else:
|
else:
|
||||||
@ -2643,7 +2646,7 @@ def check_form_integrity(formation_id, fix=False):
|
|||||||
else:
|
else:
|
||||||
txth = "OK"
|
txth = "OK"
|
||||||
log("ok")
|
log("ok")
|
||||||
return html_sco_header.sco_header() + txth + html_sco_header.sco_footer()
|
return render_template("sco_page.j2", content=txth)
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/check_formsemestre_integrity")
|
@bp.route("/check_formsemestre_integrity")
|
||||||
@ -2681,6 +2684,4 @@ def check_formsemestre_integrity(formsemestre_id):
|
|||||||
else:
|
else:
|
||||||
diag = ["OK"]
|
diag = ["OK"]
|
||||||
log("ok")
|
log("ok")
|
||||||
return (
|
return render_template("sco_page.j2", content="<br>".join(diag))
|
||||||
html_sco_header.sco_header() + "<br>".join(diag) + html_sco_header.sco_footer()
|
|
||||||
)
|
|
||||||
|
@ -64,7 +64,7 @@ from app.decorators import (
|
|||||||
permission_required,
|
permission_required,
|
||||||
)
|
)
|
||||||
|
|
||||||
from app.scodoc import html_sco_header, sco_import_users, sco_roles_default
|
from app.scodoc import sco_import_users, sco_roles_default
|
||||||
from app.scodoc import sco_users
|
from app.scodoc import sco_users
|
||||||
from app.scodoc import sco_utils as scu
|
from app.scodoc import sco_utils as scu
|
||||||
from app.scodoc import sco_xml
|
from app.scodoc import sco_xml
|
||||||
@ -74,7 +74,6 @@ from app.scodoc.sco_import_users import generate_password
|
|||||||
from app.scodoc.sco_permissions_check import can_handle_passwd
|
from app.scodoc.sco_permissions_check import can_handle_passwd
|
||||||
from app.scodoc.TrivialFormulator import TrivialFormulator, tf_error_message
|
from app.scodoc.TrivialFormulator import TrivialFormulator, tf_error_message
|
||||||
from app.views import users_bp as bp
|
from app.views import users_bp as bp
|
||||||
from app.views import scodoc_bp
|
|
||||||
|
|
||||||
|
|
||||||
_ = lambda x: x # sans babel
|
_ = lambda x: x # sans babel
|
||||||
@ -92,7 +91,7 @@ class ChangePasswordForm(FlaskForm):
|
|||||||
validators=[
|
validators=[
|
||||||
EqualTo(
|
EqualTo(
|
||||||
"new_password",
|
"new_password",
|
||||||
message="Les deux saisies sont " "différentes, recommencez",
|
message="Les deux saisies sont différentes, recommencez",
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
@ -106,9 +105,9 @@ class ChangePasswordForm(FlaskForm):
|
|||||||
submit = SubmitField()
|
submit = SubmitField()
|
||||||
cancel = SubmitField("Annuler")
|
cancel = SubmitField("Annuler")
|
||||||
|
|
||||||
def validate_email(self, email):
|
def validate_email(self, e_mail):
|
||||||
"vérifie que le mail est unique"
|
"vérifie que le mail est unique (inline wtf validator)"
|
||||||
user = User.query.filter_by(email=email.data.strip()).first()
|
user = User.query.filter_by(email=e_mail.data.strip()).first()
|
||||||
if user is not None and self.user_name.data != user.user_name:
|
if user is not None and self.user_name.data != user.user_name:
|
||||||
raise ValidationError(
|
raise ValidationError(
|
||||||
_("Cette adresse e-mail est déjà attribuée à un autre compte")
|
_("Cette adresse e-mail est déjà attribuée à un autre compte")
|
||||||
@ -120,6 +119,7 @@ class ChangePasswordForm(FlaskForm):
|
|||||||
raise ValidationError("Mot de passe trop simple, recommencez")
|
raise ValidationError("Mot de passe trop simple, recommencez")
|
||||||
|
|
||||||
def validate_old_password(self, old_password):
|
def validate_old_password(self, old_password):
|
||||||
|
"vérifie password actuel"
|
||||||
if not current_user.check_password(old_password.data):
|
if not current_user.check_password(old_password.data):
|
||||||
raise ValidationError("Mot de passe actuel incorrect, ré-essayez")
|
raise ValidationError("Mot de passe actuel incorrect, ré-essayez")
|
||||||
|
|
||||||
@ -855,9 +855,7 @@ def import_users_generate_excel_sample():
|
|||||||
@scodoc7func
|
@scodoc7func
|
||||||
def import_users_form():
|
def import_users_form():
|
||||||
"""Import utilisateurs depuis feuille Excel"""
|
"""Import utilisateurs depuis feuille Excel"""
|
||||||
head = html_sco_header.sco_header(page_title="Import utilisateurs")
|
|
||||||
H = [
|
H = [
|
||||||
head,
|
|
||||||
"""<h2>Téléchargement d'une liste d'utilisateurs</h2>
|
"""<h2>Téléchargement d'une liste d'utilisateurs</h2>
|
||||||
<p style="color: red">A utiliser pour importer de <b>nouveaux</b>
|
<p style="color: red">A utiliser pour importer de <b>nouveaux</b>
|
||||||
utilisateurs (enseignants ou secrétaires)
|
utilisateurs (enseignants ou secrétaires)
|
||||||
@ -886,12 +884,10 @@ def import_users_form():
|
|||||||
<li><b>Étape 1: </b><a class="stdlink" href="{
|
<li><b>Étape 1: </b><a class="stdlink" href="{
|
||||||
url_for("users.import_users_generate_excel_sample", scodoc_dept=g.scodoc_dept)
|
url_for("users.import_users_generate_excel_sample", scodoc_dept=g.scodoc_dept)
|
||||||
}">Obtenir la feuille excel vide à remplir</a>
|
}">Obtenir la feuille excel vide à remplir</a>
|
||||||
ou bien la liste complète des utilisateurs.
|
|
||||||
</li>
|
</li>
|
||||||
<li><b> Étape 2:</b>
|
<li><b> Étape 2:</b>
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
F = html_sco_header.sco_footer()
|
|
||||||
tf = TrivialFormulator(
|
tf = TrivialFormulator(
|
||||||
request.base_url,
|
request.base_url,
|
||||||
scu.get_request_args(),
|
scu.get_request_args(),
|
||||||
@ -915,7 +911,11 @@ def import_users_form():
|
|||||||
submitlabel="Télécharger",
|
submitlabel="Télécharger",
|
||||||
)
|
)
|
||||||
if tf[0] == 0:
|
if tf[0] == 0:
|
||||||
return "\n".join(H) + tf[1] + "</li></ul>" + help_msg + F
|
return render_template(
|
||||||
|
"sco_page_dept.j2",
|
||||||
|
title="Import utilisateurs",
|
||||||
|
content="\n".join(H) + tf[1] + "</li></ul>" + help_msg,
|
||||||
|
)
|
||||||
elif tf[0] == -1:
|
elif tf[0] == -1:
|
||||||
return flask.redirect(url_for("scolar.index_html", docodc_dept=g.scodoc_dept))
|
return flask.redirect(url_for("scolar.index_html", docodc_dept=g.scodoc_dept))
|
||||||
|
|
||||||
@ -923,8 +923,10 @@ def import_users_form():
|
|||||||
ok, diags, nb_created = sco_import_users.import_excel_file(
|
ok, diags, nb_created = sco_import_users.import_excel_file(
|
||||||
tf[2]["xlsfile"], tf[2]["force"]
|
tf[2]["xlsfile"], tf[2]["force"]
|
||||||
)
|
)
|
||||||
H = [html_sco_header.sco_header(page_title="Import utilisateurs")]
|
H = [
|
||||||
H.append("<ul>")
|
"""<h2>Téléchargement d'une liste d'utilisateurs</h2>
|
||||||
|
<ul>"""
|
||||||
|
]
|
||||||
for diag in diags:
|
for diag in diags:
|
||||||
H.append(f"<li>{diag}</li>")
|
H.append(f"<li>{diag}</li>")
|
||||||
H.append("</ul>")
|
H.append("</ul>")
|
||||||
@ -942,7 +944,9 @@ def import_users_form():
|
|||||||
<p><a class="stdlink" href="{dest_url}">Continuer</a></p>
|
<p><a class="stdlink" href="{dest_url}">Continuer</a></p>
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
return "\n".join(H) + html_sco_header.sco_footer()
|
return render_template(
|
||||||
|
"sco_page_dept.j2", title="Import utilisateurs", content="\n".join(H)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/user_info_page")
|
@bp.route("/user_info_page")
|
||||||
@ -1061,76 +1065,6 @@ def form_change_password(user_name=None):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/change_password", methods=["POST"])
|
|
||||||
@scodoc
|
|
||||||
@permission_required(Permission.ScoView)
|
|
||||||
@scodoc7func
|
|
||||||
def change_password(user_name, password, password2):
|
|
||||||
"Change the password for user given by user_name"
|
|
||||||
if user_name is not None: # scodoc7func converti en int !
|
|
||||||
user_name = str(user_name)
|
|
||||||
u = User.query.filter_by(user_name=user_name).first()
|
|
||||||
# Check access permission
|
|
||||||
if not can_handle_passwd(u):
|
|
||||||
# access denied
|
|
||||||
log(
|
|
||||||
f"change_password: access denied (authuser={current_user}, user_name={user_name})"
|
|
||||||
)
|
|
||||||
raise AccessDenied("vous n'avez pas la permission de changer ce mot de passe")
|
|
||||||
H = []
|
|
||||||
F = html_sco_header.sco_footer()
|
|
||||||
# check password
|
|
||||||
dest_url = url_for(
|
|
||||||
"users.form_change_password", scodoc_dept=g.scodoc_dept, user_name=user_name
|
|
||||||
)
|
|
||||||
if password != password2:
|
|
||||||
H.append(
|
|
||||||
f"""<p>Les deux mots de passes saisis sont différents !</p>
|
|
||||||
<p><a href="{dest_url}" class="stdlink">Recommencer</a></p>
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
if not is_valid_password(password):
|
|
||||||
H.append(
|
|
||||||
f"""<p><b>ce mot de passe n'est pas assez compliqué !</b>
|
|
||||||
<br>(oui, il faut un mot de passe vraiment compliqué !)
|
|
||||||
</p>
|
|
||||||
<p><a href="{dest_url}" class="stdlink">Recommencer</a></p>
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
# ok, strong password
|
|
||||||
db.session.add(u)
|
|
||||||
u.set_password(password)
|
|
||||||
db.session.commit()
|
|
||||||
#
|
|
||||||
# ici page simplifiee car on peut ne plus avoir
|
|
||||||
# le droit d'acceder aux feuilles de style
|
|
||||||
return f"""<?xml version="1.0" encoding="{scu.SCO_ENCODING}"?>
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Mot de passe changé</title>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset={scu.SCO_ENCODING}" />
|
|
||||||
<body>
|
|
||||||
<h1>Mot de passe changé !</h1>
|
|
||||||
<h2>Changement effectué</h2>
|
|
||||||
<p>Ne notez pas ce mot de passe, mais mémorisez le !</p>
|
|
||||||
<p>Rappel: il est <b>interdit</b> de communiquer son mot de passe à
|
|
||||||
un tiers, même si c'est un collègue de confiance !</p>
|
|
||||||
<p><b>Si vous n'êtes pas administrateur, le système va vous redemander
|
|
||||||
votre login et nouveau mot de passe au prochain accès.</b>
|
|
||||||
</p>
|
|
||||||
<a href="{
|
|
||||||
url_for("scolar.index_html", scodoc_dept=g.scodoc_dept)
|
|
||||||
}" class="stdlink">Continuer</a>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
"""
|
|
||||||
|
|
||||||
return html_sco_header.sco_header() + "\n".join(H) + F
|
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/toggle_active_user/<user_name>", methods=["GET", "POST"])
|
@bp.route("/toggle_active_user/<user_name>", methods=["GET", "POST"])
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.UsersAdmin)
|
@permission_required(Permission.UsersAdmin)
|
||||||
|
@ -30,7 +30,6 @@ class Config:
|
|||||||
# Le "from" des mails émis. Attention: peut être remplacée par la préférence email_from_addr:
|
# Le "from" des mails émis. Attention: peut être remplacée par la préférence email_from_addr:
|
||||||
SCODOC_MAIL_FROM = os.environ.get("SCODOC_MAIL_FROM") or ("no-reply@" + MAIL_SERVER)
|
SCODOC_MAIL_FROM = os.environ.get("SCODOC_MAIL_FROM") or ("no-reply@" + MAIL_SERVER)
|
||||||
|
|
||||||
BOOTSTRAP_SERVE_LOCAL = os.environ.get("BOOTSTRAP_SERVE_LOCAL")
|
|
||||||
SCODOC_DIR = os.environ.get("SCODOC_DIR", "/opt/scodoc")
|
SCODOC_DIR = os.environ.get("SCODOC_DIR", "/opt/scodoc")
|
||||||
SCODOC_VAR_DIR = os.environ.get("SCODOC_VAR_DIR", "/opt/scodoc-data")
|
SCODOC_VAR_DIR = os.environ.get("SCODOC_VAR_DIR", "/opt/scodoc-data")
|
||||||
SCODOC_LOG_FILE = os.path.join(SCODOC_VAR_DIR, "log", "scodoc.log")
|
SCODOC_LOG_FILE = os.path.join(SCODOC_VAR_DIR, "log", "scodoc.log")
|
||||||
@ -46,6 +45,7 @@ class Config:
|
|||||||
|
|
||||||
class ProdConfig(Config):
|
class ProdConfig(Config):
|
||||||
"mode production, normalement derrière nginx/gunicorn"
|
"mode production, normalement derrière nginx/gunicorn"
|
||||||
|
|
||||||
FLASK_ENV = "production"
|
FLASK_ENV = "production"
|
||||||
DEBUG = False
|
DEBUG = False
|
||||||
TESTING = False
|
TESTING = False
|
||||||
@ -57,6 +57,7 @@ class ProdConfig(Config):
|
|||||||
|
|
||||||
class DevConfig(Config):
|
class DevConfig(Config):
|
||||||
"mode développement"
|
"mode développement"
|
||||||
|
|
||||||
FLASK_ENV = "development"
|
FLASK_ENV = "development"
|
||||||
DEBUG = True
|
DEBUG = True
|
||||||
TESTING = False
|
TESTING = False
|
||||||
@ -70,6 +71,7 @@ class DevConfig(Config):
|
|||||||
|
|
||||||
class TestConfig(DevConfig):
|
class TestConfig(DevConfig):
|
||||||
"Pour les tests unitaires"
|
"Pour les tests unitaires"
|
||||||
|
|
||||||
TESTING = True
|
TESTING = True
|
||||||
DEBUG = False
|
DEBUG = False
|
||||||
SQLALCHEMY_DATABASE_URI = (
|
SQLALCHEMY_DATABASE_URI = (
|
||||||
@ -82,6 +84,7 @@ class TestConfig(DevConfig):
|
|||||||
|
|
||||||
class TestAPIConfig(Config):
|
class TestAPIConfig(Config):
|
||||||
"Pour les tests de l'API"
|
"Pour les tests de l'API"
|
||||||
|
|
||||||
FLASK_ENV = "test_api"
|
FLASK_ENV = "test_api"
|
||||||
TESTING = False
|
TESTING = False
|
||||||
DEBUG = True
|
DEBUG = True
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# -*- mode: python -*-
|
# -*- mode: python -*-
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
SCOVERSION = "9.7.7"
|
SCOVERSION = "9.7.10"
|
||||||
|
|
||||||
SCONAME = "ScoDoc"
|
SCONAME = "ScoDoc"
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ debian_version=$(cat /etc/debian_version)
|
|||||||
debian_version=${debian_version%%.*}
|
debian_version=${debian_version%%.*}
|
||||||
|
|
||||||
die() {
|
die() {
|
||||||
echo
|
echo
|
||||||
echo "Erreur: $1"
|
echo "Erreur: $1"
|
||||||
echo
|
echo
|
||||||
exit 1
|
exit 1
|
||||||
@ -17,8 +17,8 @@ export PATH="${PATH}":/usr/sbin:/sbin
|
|||||||
umask 0022
|
umask 0022
|
||||||
|
|
||||||
export SCODOC_DIR=/opt/scodoc
|
export SCODOC_DIR=/opt/scodoc
|
||||||
export SCODOC_VAR_DIR=/opt/scodoc-data
|
export SCODOC_VAR_DIR=/opt/scodoc-data
|
||||||
|
export SCODOC_INSTALL_STATUS_FILE="${SCODOC_VAR_DIR}/.install_status"
|
||||||
export SCODOC_VERSION_DIR="${SCODOC_VAR_DIR}/config/version"
|
export SCODOC_VERSION_DIR="${SCODOC_VAR_DIR}/config/version"
|
||||||
export SCODOC_LOGOS_DIR="${SCODOC_VAR_DIR}/config/logos"
|
export SCODOC_LOGOS_DIR="${SCODOC_VAR_DIR}/config/logos"
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ else
|
|||||||
fi
|
fi
|
||||||
export PSQL
|
export PSQL
|
||||||
|
|
||||||
# tcp port for SQL server
|
# tcp port for SQL server
|
||||||
# Important note: if changed, you should probably also change it in
|
# Important note: if changed, you should probably also change it in
|
||||||
# sco_utils.py (SCO_DEFAULT_SQL_PORT).
|
# sco_utils.py (SCO_DEFAULT_SQL_PORT).
|
||||||
export POSTGRES_PORT=5432
|
export POSTGRES_PORT=5432
|
||||||
|
@ -3,11 +3,17 @@
|
|||||||
# Post-installation de scodoc
|
# Post-installation de scodoc
|
||||||
# ici, le répertoire /opt/scodoc vient d'être installé
|
# ici, le répertoire /opt/scodoc vient d'être installé
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
cd /opt/scodoc || (echo "Error chdir to /opt/scodoc"; exit 1)
|
cd /opt/scodoc || (echo "Error chdir to /opt/scodoc"; exit 1)
|
||||||
|
|
||||||
# On peut donc charger la config:
|
# On peut donc charger la config:
|
||||||
source /opt/scodoc/tools/config.sh
|
source /opt/scodoc/tools/config.sh || (echo "Error loading /opt/scodoc/tools/config.sh"; exit 1)
|
||||||
source /opt/scodoc/tools/utils.sh
|
source /opt/scodoc/tools/utils.sh || (echo "Error loading /opt/scodoc/tools/utils.sh"; exit 1)
|
||||||
|
|
||||||
|
# Enleve fichier de statut d'installation s'il existe
|
||||||
|
# (la présence de ce fichier indique que l'install s'est bien passée)
|
||||||
|
remove_install_status
|
||||||
|
|
||||||
# -- Création au besoin de notre utilisateur
|
# -- Création au besoin de notre utilisateur
|
||||||
# adduser --system "${SCODOC_USER}"
|
# adduser --system "${SCODOC_USER}"
|
||||||
@ -26,7 +32,7 @@ do
|
|||||||
then
|
then
|
||||||
echo adding $locname
|
echo adding $locname
|
||||||
echo "$locname ${locname##*.}" >> /etc/locale.gen
|
echo "$locname ${locname##*.}" >> /etc/locale.gen
|
||||||
/usr/sbin/locale-gen --keep-existing
|
/usr/sbin/locale-gen --keep-existing
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
echo "debian postinst: scodoc9 systemd service is $(systemctl is-active scodoc9)"
|
echo "debian postinst: scodoc9 systemd service is $(systemctl is-active scodoc9)"
|
||||||
@ -44,7 +50,7 @@ then
|
|||||||
if [[ ! "${SN}" =~ ^[0-9].* ]]
|
if [[ ! "${SN}" =~ ^[0-9].* ]]
|
||||||
then
|
then
|
||||||
SN='' # fix for invalid previous replies
|
SN='' # fix for invalid previous replies
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
# first install
|
# first install
|
||||||
echo "mode: install"
|
echo "mode: install"
|
||||||
@ -56,10 +62,10 @@ CMD="curl --fail --connect-timeout 5 --silent https://scodoc.org/scodoc-installm
|
|||||||
|
|
||||||
SVERSION="$(${CMD})"
|
SVERSION="$(${CMD})"
|
||||||
if [ "$?" == 0 ]; then
|
if [ "$?" == 0 ]; then
|
||||||
#echo "answer=${SVERSION}"
|
#echo "answer=${SVERSION}"
|
||||||
echo "${SVERSION}" > "${SCODOC_VERSION_DIR}"/scodoc.sn
|
echo "${SVERSION}" > "${SCODOC_VERSION_DIR}"/scodoc.sn
|
||||||
else
|
else
|
||||||
echo 'Warning: cannot connect to scodoc release server'
|
echo 'Warning: cannot connect to scodoc release server'
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# ------------ LIEN VERS .env
|
# ------------ LIEN VERS .env
|
||||||
@ -117,7 +123,7 @@ cp "$SCODOC_DIR"/tools/etc/scodoc-logrotate /etc/logrotate.d/scodoc
|
|||||||
chmod 644 /etc/logrotate.d/scodoc
|
chmod 644 /etc/logrotate.d/scodoc
|
||||||
|
|
||||||
# ------------ CONFIG SERVICE SCODOC
|
# ------------ CONFIG SERVICE SCODOC
|
||||||
echo
|
echo
|
||||||
echo "Installation du service systemd scodoc9..."
|
echo "Installation du service systemd scodoc9..."
|
||||||
cp "$SCODOC_DIR"/tools/etc/scodoc9.service /etc/systemd/system/
|
cp "$SCODOC_DIR"/tools/etc/scodoc9.service /etc/systemd/system/
|
||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
@ -134,3 +140,6 @@ systemctl enable scodoc9
|
|||||||
|
|
||||||
# --- RESTART SCODOC
|
# --- RESTART SCODOC
|
||||||
systemctl restart scodoc9
|
systemctl restart scodoc9
|
||||||
|
|
||||||
|
# On est arrivé au bout du post-install !
|
||||||
|
create_install_status
|
||||||
|
19
tools/debian/prerm
Executable file
19
tools/debian/prerm
Executable file
@ -0,0 +1,19 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Pre-removal script for scodoc
|
||||||
|
# This script is called by dpkg before removing the package
|
||||||
|
|
||||||
|
cd /opt/scodoc || (echo "Error chdir to /opt/scodoc"; exit 1)
|
||||||
|
|
||||||
|
# On peut donc charger la config:
|
||||||
|
source /opt/scodoc/tools/config.sh || (echo "Error loading /opt/scodoc/tools/config.sh"; exit 1)
|
||||||
|
source /opt/scodoc/tools/utils.sh || (echo "Error loading /opt/scodoc/tools/utils.sh"; exit 1)
|
||||||
|
|
||||||
|
check_uid_root
|
||||||
|
|
||||||
|
remove_install_status
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -35,14 +35,6 @@ server {
|
|||||||
alias /opt/scodoc/app/static;
|
alias /opt/scodoc/app/static;
|
||||||
expires 1d;
|
expires 1d;
|
||||||
}
|
}
|
||||||
location /ScoDoc/static/bootstrap {
|
|
||||||
# (temp.) exception: home page using flask_bootstrap !
|
|
||||||
proxy_pass http://localhost:8000;
|
|
||||||
proxy_redirect off;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
}
|
|
||||||
location /favicon.ico {
|
location /favicon.ico {
|
||||||
alias /opt/scodoc/app/static/icons/favicon.ico;
|
alias /opt/scodoc/app/static/icons/favicon.ico;
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,16 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Upgrade ScoDoc installation using APT
|
# Upgrade ScoDoc installation using APT
|
||||||
#
|
#
|
||||||
# This script STOP and RESTART ScoDoc and should be runned as root
|
# This script STOP and RESTART ScoDoc and should be runned as root
|
||||||
#
|
#
|
||||||
# Upgrade also the Linux system using apt.
|
# Upgrade also the Linux system using apt.
|
||||||
#
|
#
|
||||||
# Script for ScoDoc 9
|
# Script for ScoDoc 9. Lancé automatiquement par scodoc-updater.
|
||||||
#
|
#
|
||||||
# E. Viennet, sep 2013, mar 2017, jun 2019, aug 2020, dec 2020, aug 21
|
# E. Viennet, sep 2013, mar 2017, jun 2019, aug 2020, dec 2020, aug 21
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
# Le répertoire de ce script:
|
# Le répertoire de ce script:
|
||||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||||
@ -29,7 +30,7 @@ if [ -z "$SCODOC_UPGRADE_RUNNING" ]
|
|||||||
# install spécifiquement scodoc9, utile si les dépendances Debian de scodoc9
|
# install spécifiquement scodoc9, utile si les dépendances Debian de scodoc9
|
||||||
# ont été changées, ce qui peut provoquer un
|
# ont été changées, ce qui peut provoquer un
|
||||||
# "packages have been kept back"
|
# "packages have been kept back"
|
||||||
apt install scodoc9
|
apt install scodoc9 || alarm_admin "apt install scodoc9 failed"
|
||||||
fi
|
fi
|
||||||
systemctl restart redis
|
systemctl restart redis
|
||||||
systemctl restart nginx
|
systemctl restart nginx
|
||||||
|
@ -2,12 +2,12 @@
|
|||||||
# Misc utilities for ScoDoc install shell scripts
|
# Misc utilities for ScoDoc install shell scripts
|
||||||
|
|
||||||
to_lower() {
|
to_lower() {
|
||||||
echo "$1" | tr "[:upper:]" "[:lower:]"
|
echo "$1" | tr "[:upper:]" "[:lower:]"
|
||||||
}
|
}
|
||||||
|
|
||||||
to_upper() {
|
to_upper() {
|
||||||
echo "$1" | tr "[:lower:]" "[:upper:]"
|
echo "$1" | tr "[:lower:]" "[:upper:]"
|
||||||
}
|
}
|
||||||
|
|
||||||
norm_ans() {
|
norm_ans() {
|
||||||
x=$(to_upper "$1" | tr O Y)
|
x=$(to_upper "$1" | tr O Y)
|
||||||
@ -15,7 +15,7 @@ norm_ans() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
check_uid_root() {
|
check_uid_root() {
|
||||||
if [ "$UID" != "0" ]
|
if [ "$UID" != "0" ]
|
||||||
then
|
then
|
||||||
echo "Erreur: le script $1 doit etre lance par root"
|
echo "Erreur: le script $1 doit etre lance par root"
|
||||||
exit 1
|
exit 1
|
||||||
@ -24,7 +24,7 @@ check_uid_root() {
|
|||||||
|
|
||||||
terminate() {
|
terminate() {
|
||||||
status=${2:-1} # default: exit 1
|
status=${2:-1} # default: exit 1
|
||||||
echo
|
echo
|
||||||
echo "Erreur: $1"
|
echo "Erreur: $1"
|
||||||
echo
|
echo
|
||||||
exit $status
|
exit $status
|
||||||
@ -95,8 +95,8 @@ set_scodoc_var_dir() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# XXX inutilise
|
# XXX inutilise
|
||||||
gen_passwd() {
|
gen_passwd() {
|
||||||
PASSWORD_LENGTH="8"
|
PASSWORD_LENGTH="8"
|
||||||
ALLOWABLE_ASCII="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz@#$%^&*()_+=-?><"
|
ALLOWABLE_ASCII="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz@#$%^&*()_+=-?><"
|
||||||
SEED=$(head -c4 /dev/urandom | od -t u4 | awk '{ print $2 }')
|
SEED=$(head -c4 /dev/urandom | od -t u4 | awk '{ print $2 }')
|
||||||
@ -110,3 +110,26 @@ gen_passwd() {
|
|||||||
done
|
done
|
||||||
echo "$password"
|
echo "$password"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Status file: indique si l'install s'est complètement déroulée
|
||||||
|
create_install_status() {
|
||||||
|
touch "${SCODOC_INSTALL_STATUS_FILE}" || die "can't create ${SCODOC_INSTALL_STATUS_FILE}"
|
||||||
|
}
|
||||||
|
remove_install_status() {
|
||||||
|
if [ -e "${SCODOC_INSTALL_STATUS_FILE}" ]
|
||||||
|
then
|
||||||
|
rm -f "${SCODOC_INSTALL_STATUS_FILE}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
alarm_admin() {
|
||||||
|
echo "Error: alarm_admin $1"
|
||||||
|
echo "Sending email to admin..."
|
||||||
|
echo "Subject: ScoDoc: $1" | mail -s "ScoDoc: $1" root <<EOF
|
||||||
|
|
||||||
|
Erreur lors de la mise à jour de ScoDoc sur $(hostname --fqdn)
|
||||||
|
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user