forked from ScoDoc/ScoDoc
Compare commits
No commits in common. "cf174cdc18b18a73caff56670775dd58f9a32801" and "37c93c8524da904a9ecba1f816cc3f726a169f58" have entirely different histories.
cf174cdc18
...
37c93c8524
@ -353,7 +353,8 @@ def create_app(config_class=DevConfig):
|
||||
app.jinja_env.autoescape = select_autoescape(default_for_string=True, default=True)
|
||||
app.jinja_env.trim_blocks = True
|
||||
app.jinja_env.lstrip_blocks = True
|
||||
app.jinja_env.globals["is_hidden_field"] = lambda field: isinstance(
|
||||
# previously in Flask-Bootstrap:
|
||||
app.jinja_env.globals["bootstrap_is_hidden_field"] = lambda field: isinstance(
|
||||
field, HiddenField
|
||||
)
|
||||
|
||||
|
@ -39,13 +39,15 @@ from wtforms import ValidationError
|
||||
from wtforms.fields.simple import StringField, HiddenField
|
||||
|
||||
from app.models import Departement
|
||||
from app.scodoc import sco_logos
|
||||
from app.scodoc import sco_logos, html_sco_header
|
||||
from app.scodoc import sco_utils as scu
|
||||
|
||||
from app.scodoc.sco_config_actions import LogoInsert
|
||||
from app.scodoc.sco_exceptions import ScoValueError
|
||||
from app.scodoc.sco_logos import find_logo
|
||||
|
||||
CSSSTYLES = html_sco_header.BOOTSTRAP_CSS
|
||||
JAVASCRIPTS = html_sco_header.BOOTSTRAP_JS
|
||||
|
||||
# class ItemForm(FlaskForm):
|
||||
# """Unused Generic class to document common behavior for classes
|
||||
@ -365,7 +367,6 @@ def _make_data(modele):
|
||||
|
||||
class LogosConfigurationForm(FlaskForm):
|
||||
"Panneau de configuration des logos"
|
||||
|
||||
depts = FieldList(FormField(DeptForm))
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
@ -36,6 +36,11 @@ from app.scodoc import html_sidebar
|
||||
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():
|
||||
"""Standard HTML header for pages outside depts"""
|
||||
# not used in ZScolar, see sco_header
|
||||
|
@ -96,7 +96,7 @@ def formation_delete(formation_id=None, dialog_confirmed=False):
|
||||
)
|
||||
|
||||
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,8 +1059,10 @@ du programme" (menu "Semestre") si vous avez un semestre en cours);
|
||||
"sco_page_dept.j2",
|
||||
content="".join(H),
|
||||
page_title=f"Formation {formation.acronyme} v{formation.version}",
|
||||
cssstyles=["libjs/jQuery-tagEditor/jquery.tag-editor.css", "css/ue_table.css"],
|
||||
javascripts=[
|
||||
cssstyles=html_sco_header.BOOTSTRAP_CSS
|
||||
+ ["libjs/jQuery-tagEditor/jquery.tag-editor.css", "css/ue_table.css"],
|
||||
javascripts=html_sco_header.BOOTSTRAP_JS
|
||||
+ [
|
||||
"libjs/jinplace-1.2.1.min.js",
|
||||
"js/ue_list.js",
|
||||
"js/edit_ue.js",
|
||||
@ -1128,7 +1130,9 @@ def _ue_table_ues(
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
ue_id=ue["ue_id"],
|
||||
)
|
||||
ue["code_apogee_str"] = f""", Apo: <span
|
||||
ue[
|
||||
"code_apogee_str"
|
||||
] = f""", Apo: <span
|
||||
class="{klass}" data-url="{edit_url}" id="{ue['ue_id']}"
|
||||
data-placeholder="{scu.APO_MISSING_CODE_STR}">{
|
||||
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 app.comp import res_sem
|
||||
@ -73,7 +73,9 @@ def _build_results_table(start_date=None, end_date=None, types_parcours=[]):
|
||||
formsemestre_ids_parcours = [sem["formsemestre_id"] for sem in semlist_parcours]
|
||||
|
||||
# Ensemble des étudiants
|
||||
etuds_infos = {} # etudid : { formsemestre_id d'inscription le plus recent dans les dates considérées, etud }
|
||||
etuds_infos = (
|
||||
{}
|
||||
) # etudid : { formsemestre_id d'inscription le plus recent dans les dates considérées, etud }
|
||||
for formsemestre_id in formsemestre_ids_parcours:
|
||||
formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
|
||||
nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
|
||||
@ -285,7 +287,8 @@ def scodoc_table_results(
|
||||
H = [
|
||||
html_sco_header.sco_header(
|
||||
page_title="Export résultats",
|
||||
javascripts=["js/export_results.js"],
|
||||
javascripts=html_sco_header.BOOTSTRAP_JS + ["js/export_results.js"],
|
||||
cssstyles=html_sco_header.BOOTSTRAP_CSS,
|
||||
),
|
||||
# XXX
|
||||
"""
|
||||
|
@ -1397,8 +1397,7 @@ def do_formsemestre_clone(
|
||||
formsemestre.parcours = formsemestre_orig.parcours
|
||||
|
||||
# 6- Copy description
|
||||
if formsemestre_orig.description:
|
||||
formsemestre.description = formsemestre_orig.description.clone()
|
||||
formsemestre.description = formsemestre_orig.description.clone()
|
||||
|
||||
db.session.add(formsemestre)
|
||||
db.session.commit()
|
||||
|
@ -57,6 +57,13 @@ from app.scodoc.gen_tables import GenTable
|
||||
from app.scodoc.sco_exceptions import ScoValueError, ScoPermissionDenied
|
||||
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
|
||||
def groups_lists(
|
||||
|
@ -51,7 +51,7 @@ from wtforms import (
|
||||
from app.models import Evaluation, ModuleImpl
|
||||
import app.scodoc.sco_utils as scu
|
||||
import app.scodoc.notesdb as ndb
|
||||
from app.scodoc import sco_preferences
|
||||
from app.scodoc import html_sco_header, sco_preferences
|
||||
from app.scodoc import sco_edit_module
|
||||
from app.scodoc import sco_evaluations
|
||||
from app.scodoc import sco_excel
|
||||
@ -204,14 +204,14 @@ def placement_eval_selectetuds(evaluation_id):
|
||||
% runner.__dict__
|
||||
)
|
||||
return runner.exec_placement() # calcul et generation du fichier
|
||||
|
||||
return render_template(
|
||||
"scodoc/forms/placement.j2",
|
||||
evaluations_description=sco_evaluations.evaluation_describe(
|
||||
evaluation_id=evaluation_id
|
||||
),
|
||||
form=form,
|
||||
)
|
||||
htmls = [
|
||||
html_sco_header.sco_header(),
|
||||
sco_evaluations.evaluation_describe(evaluation_id=evaluation_id),
|
||||
"<h3>Placement et émargement des étudiants</h3>",
|
||||
render_template("scodoc/forms/placement.j2", form=form),
|
||||
]
|
||||
footer = html_sco_header.sco_footer()
|
||||
return "\n".join(htmls) + "<p>" + footer
|
||||
|
||||
|
||||
class PlacementRunner:
|
||||
|
@ -350,7 +350,7 @@ def formsemestre_pvjury_pdf(formsemestre_id, group_ids: list[int] = None, etudid
|
||||
etud = Identite.get_etud(etudid)
|
||||
etudids = [etudid]
|
||||
else:
|
||||
etud = None
|
||||
etuddescr = ""
|
||||
if not group_ids:
|
||||
# tous les inscrits du semestre
|
||||
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:
|
||||
return render_template(
|
||||
"sco_page.j2",
|
||||
title=f"Édition du PV de jury {('de ' + etud.nom_prenom()) if etud else ''}",
|
||||
title=f"Édition du PV de jury de {etud.nom_prenom()}",
|
||||
content=f"""<h2 class="formsemestre">Édition du PV de jury
|
||||
de <a class="discretelink" href="{
|
||||
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etudid)
|
||||
|
@ -37,7 +37,7 @@ import time
|
||||
import datetime
|
||||
from operator import itemgetter
|
||||
|
||||
from flask import url_for, g, render_template, request
|
||||
from flask import url_for, g, request
|
||||
import pydot
|
||||
|
||||
from app import log
|
||||
@ -50,6 +50,7 @@ from app.models.etudiants import Identite
|
||||
|
||||
from app.scodoc import (
|
||||
codes_cursus,
|
||||
html_sco_header,
|
||||
sco_etud,
|
||||
sco_formsemestre,
|
||||
sco_formsemestre_inscriptions,
|
||||
@ -410,6 +411,11 @@ def formsemestre_report_counts(
|
||||
if fmt != "html":
|
||||
return tableau
|
||||
H = [
|
||||
html_sco_header.sco_header(
|
||||
cssstyles=sco_groups_view.CSSSTYLES,
|
||||
javascripts=sco_groups_view.JAVASCRIPTS,
|
||||
page_title=title,
|
||||
),
|
||||
tableau,
|
||||
"\n".join(F),
|
||||
"""<p class="help">Le tableau affiche le nombre d'étudiants de ce semestre dans chacun
|
||||
@ -417,14 +423,9 @@ def formsemestre_report_counts(
|
||||
pour les lignes et les colonnes. Le <tt>codedecision</tt> est le code de la décision
|
||||
du jury.
|
||||
</p>""",
|
||||
html_sco_header.sco_footer(),
|
||||
]
|
||||
return render_template(
|
||||
"sco_page.j2",
|
||||
cssstyles=sco_groups_view.CSSSTYLES,
|
||||
javascripts=sco_groups_view.JAVASCRIPTS,
|
||||
title=title,
|
||||
content="\n".join(H),
|
||||
)
|
||||
return "\n".join(H)
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
@ -812,6 +813,11 @@ def formsemestre_suivi_cohorte(
|
||||
href="{burl}&percent=1">Afficher les résultats en pourcentages</a></p>"""
|
||||
|
||||
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>""",
|
||||
_gen_form_selectetuds(
|
||||
formsemestre.id,
|
||||
@ -847,14 +853,9 @@ def formsemestre_suivi_cohorte(
|
||||
</p>
|
||||
""",
|
||||
expl,
|
||||
html_sco_header.sco_footer(),
|
||||
]
|
||||
return render_template(
|
||||
"sco_page.j2",
|
||||
cssstyles=sco_groups_view.CSSSTYLES,
|
||||
javascripts=sco_groups_view.JAVASCRIPTS,
|
||||
title=tab.page_title,
|
||||
content="\n".join(H),
|
||||
)
|
||||
return "\n".join(H)
|
||||
|
||||
|
||||
def _gen_form_selectetuds(
|
||||
@ -1364,11 +1365,15 @@ def formsemestre_suivi_cursus(
|
||||
]
|
||||
|
||||
H = [
|
||||
html_sco_header.sco_header(
|
||||
page_title=tab.page_title,
|
||||
),
|
||||
"""<h2 class="formsemestre">Cursus suivis par les étudiants de ce semestre</h2>""",
|
||||
"\n".join(F),
|
||||
t,
|
||||
html_sco_header.sco_footer(),
|
||||
]
|
||||
return render_template("sco_page.j2", title=tab.page_title, content="\n".join(H))
|
||||
return "\n".join(H)
|
||||
|
||||
|
||||
# -------------
|
||||
@ -1737,6 +1742,12 @@ def formsemestre_graph_cursus(
|
||||
)
|
||||
|
||||
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>""",
|
||||
doc,
|
||||
f"<p>{len(etuds)} étudiants sélectionnés</p>",
|
||||
@ -1760,12 +1771,11 @@ def formsemestre_graph_cursus(
|
||||
),
|
||||
"""<p>Origine et devenir des étudiants inscrits dans %(titreannee)s"""
|
||||
% sem,
|
||||
f"""(<a href="{
|
||||
url_for("notes.formsemestre_graph_cursus", fmt="pdf", **url_kw)
|
||||
}">version pdf</a>,
|
||||
<a href="{
|
||||
url_for("notes.formsemestre_graph_cursus", fmt="png", **url_kw)}">image PNG</a>)
|
||||
|
||||
"""(<a href="%s">version pdf</a>"""
|
||||
% url_for("notes.formsemestre_graph_cursus", fmt="pdf", **url_kw),
|
||||
""", <a href="%s">image PNG</a>)"""
|
||||
% url_for("notes.formsemestre_graph_cursus", fmt="png", **url_kw),
|
||||
f"""
|
||||
</p>
|
||||
<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
|
||||
@ -1778,14 +1788,8 @@ def formsemestre_graph_cursus(
|
||||
étudiants appartenant aux groupes indiqués <em>dans le semestre d'origine</em>.
|
||||
</p>
|
||||
""",
|
||||
html_sco_header.sco_footer(),
|
||||
]
|
||||
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),
|
||||
)
|
||||
return "\n".join(H)
|
||||
else:
|
||||
raise ValueError(f"invalid format: {fmt}")
|
||||
|
@ -31,18 +31,21 @@
|
||||
from collections import defaultdict
|
||||
|
||||
|
||||
from flask import render_template, request
|
||||
from flask import request
|
||||
|
||||
from app import db
|
||||
from app.but import jury_but
|
||||
from app.models import FormSemestre
|
||||
from app.models.formsemestre import FormSemestreInscription
|
||||
|
||||
import app.scodoc.sco_utils as scu
|
||||
from app.scodoc import html_sco_header
|
||||
from app.scodoc import codes_cursus
|
||||
from app.scodoc.sco_exceptions import ScoValueError
|
||||
|
||||
from app.scodoc import sco_preferences
|
||||
from app.scodoc.gen_tables import GenTable
|
||||
import sco_version
|
||||
from app.scodoc.gen_tables import GenTable
|
||||
|
||||
|
||||
# Titres, ordonnés
|
||||
@ -104,11 +107,13 @@ def formsemestre_but_indicateurs(formsemestre_id: int, fmt="html"):
|
||||
if fmt != "html":
|
||||
return t
|
||||
H = [
|
||||
html_sco_header.sco_header(page_title=title),
|
||||
t,
|
||||
"""<p class="help">
|
||||
</p>""",
|
||||
html_sco_header.sco_footer(),
|
||||
]
|
||||
return render_template("sco_page.j2", title=title, content="\n".join(H))
|
||||
return "\n".join(H)
|
||||
|
||||
|
||||
def but_indicateurs_by_bac(formsemestre: FormSemestre) -> dict[str:dict]:
|
||||
|
@ -40,15 +40,17 @@ sem_set_list()
|
||||
"""
|
||||
|
||||
import flask
|
||||
from flask import g, render_template, url_for
|
||||
from flask import g, url_for
|
||||
|
||||
from app import db, log
|
||||
from app.comp import res_sem
|
||||
from app.comp.res_compat import NotesTableCompat
|
||||
from app.models import FormSemestre
|
||||
from app.scodoc import html_sco_header
|
||||
from app.scodoc import sco_etape_apogee
|
||||
from app.scodoc import sco_formsemestre
|
||||
from app.scodoc import sco_formsemestre_status
|
||||
from app.scodoc import sco_portal_apogee
|
||||
from app.scodoc import sco_preferences
|
||||
from app.scodoc.gen_tables import GenTable
|
||||
from app.scodoc.sco_etape_bilan import EtapeBilan
|
||||
@ -410,7 +412,7 @@ def do_semset_delete(semset_id, dialog_confirmed=False):
|
||||
s = SemSet(semset_id=semset_id)
|
||||
if not dialog_confirmed:
|
||||
return scu.confirm_dialog(
|
||||
f"<h2>Suppression de l'ensemble {s['title']} ?</h2>",
|
||||
"<h2>Suppression de l'ensemble %(title)s ?</h2>" % s,
|
||||
dest_url="",
|
||||
parameters={"semset_id": semset_id},
|
||||
cancel_url="semset_page",
|
||||
@ -419,14 +421,14 @@ def do_semset_delete(semset_id, dialog_confirmed=False):
|
||||
return flask.redirect("semset_page")
|
||||
|
||||
|
||||
def edit_semset_set_title(oid=None, value=None):
|
||||
def edit_semset_set_title(id=None, value=None):
|
||||
"""Change title of semset"""
|
||||
title = value.strip()
|
||||
if not oid:
|
||||
if not id:
|
||||
raise ScoValueError("empty semset_id")
|
||||
SemSet(semset_id=oid)
|
||||
SemSet(semset_id=id)
|
||||
cnx = ndb.GetDBConnexion()
|
||||
semset_edit(cnx, {"semset_id": oid, "title": title})
|
||||
semset_edit(cnx, {"semset_id": id, "title": title})
|
||||
return title
|
||||
|
||||
|
||||
@ -515,18 +517,22 @@ def semset_page(fmt="html"):
|
||||
|
||||
page_title = "Ensembles de semestres"
|
||||
H = [
|
||||
html_sco_header.sco_header(
|
||||
page_title=page_title,
|
||||
javascripts=["libjs/jinplace-1.2.1.min.js"],
|
||||
),
|
||||
"""<script>$(function() {
|
||||
$('.inplace_edit').jinplace();
|
||||
});
|
||||
</script>""",
|
||||
f"<h2>{page_title}</h2>",
|
||||
"<h2>%s</h2>" % page_title,
|
||||
]
|
||||
H.append(tab.html())
|
||||
|
||||
annee_courante = int(scu.annee_scolaire())
|
||||
menu_annee = "\n".join(
|
||||
[
|
||||
f"""<option value="{i}">{i}</option>"""
|
||||
'<option value="%s">%s</option>' % (i, i)
|
||||
for i in range(2014, annee_courante + 1)
|
||||
]
|
||||
)
|
||||
@ -555,8 +561,8 @@ def semset_page(fmt="html"):
|
||||
|
||||
H.append(
|
||||
"""
|
||||
<div class="scobox space-before-24">
|
||||
<div class="scobox-title">Autres opérations :</div>
|
||||
<div>
|
||||
<h4>Autres opérations:</h4>
|
||||
<ul>
|
||||
<li><a class="stdlink" href="scodoc_table_results">
|
||||
Table des résultats de tous les semestres
|
||||
@ -569,9 +575,4 @@ def semset_page(fmt="html"):
|
||||
"""
|
||||
)
|
||||
|
||||
return render_template(
|
||||
"sco_page_dept.j2",
|
||||
title=page_title,
|
||||
javascripts=["libjs/jinplace-1.2.1.min.js"],
|
||||
content="\n".join(H),
|
||||
)
|
||||
return "\n".join(H) + html_sco_header.sco_footer()
|
||||
|
@ -49,6 +49,7 @@ import app.scodoc.sco_utils as scu
|
||||
from app.scodoc.TrivialFormulator import TrivialFormulator
|
||||
from app.scodoc.sco_exceptions import ScoPDFFormatError, ScoValueError
|
||||
from app.scodoc.sco_pdf import SU
|
||||
from app.scodoc import html_sco_header
|
||||
from app.scodoc import htmlutils
|
||||
from app.scodoc import sco_import_etuds
|
||||
from app.scodoc import sco_excel
|
||||
@ -89,7 +90,12 @@ def trombino(
|
||||
return _listeappel_photos_pdf(groups_infos)
|
||||
elif fmt == "doc":
|
||||
return sco_trombino_doc.trombino_doc(groups_infos)
|
||||
raise ValueError("invalid format")
|
||||
else:
|
||||
raise Exception("invalid format")
|
||||
|
||||
|
||||
def _trombino_html_header():
|
||||
return html_sco_header.sco_header(javascripts=["js/trombino.js"])
|
||||
|
||||
|
||||
def trombino_html(groups_infos):
|
||||
@ -245,18 +251,14 @@ def trombino_copy_photos(group_ids=None, dialog_confirmed=False):
|
||||
back_url = "groups_photos?" + str(groups_infos.groups_query_args)
|
||||
|
||||
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:
|
||||
return render_template(
|
||||
"sco_page.j2",
|
||||
content=f"""
|
||||
return f"""{ header }
|
||||
<p>portail non configuré</p>
|
||||
<div>
|
||||
<a class="stdlink" href="{back_url}" class="stdlink">
|
||||
Retour au trombinoscope
|
||||
</a>
|
||||
</div>
|
||||
""",
|
||||
)
|
||||
<p><a href="{back_url}" class="stdlink">Retour au trombinoscope</a></p>
|
||||
{ footer }
|
||||
"""
|
||||
if not dialog_confirmed:
|
||||
return scu.confirm_dialog(
|
||||
f"""<h2>Copier les photos du portail vers ScoDoc ?</h2>
|
||||
@ -283,18 +285,14 @@ def trombino_copy_photos(group_ids=None, dialog_confirmed=False):
|
||||
|
||||
msg.append(f"<b>{nok} photos correctement chargées</b>")
|
||||
|
||||
return render_template(
|
||||
"sco_page.j2",
|
||||
content=f"""
|
||||
return f"""{ header }
|
||||
<h2>Chargement des photos depuis le portail</h2>
|
||||
<ul><li>
|
||||
{ '</li><li>'.join(msg) }
|
||||
</li></ul>
|
||||
<div class="space-before-24">
|
||||
<a class="stdlink" href="{back_url}">retour au trombinoscope</a>
|
||||
</div>
|
||||
""",
|
||||
)
|
||||
<p><a href="{back_url}">retour au trombinoscope</a>
|
||||
{ footer }
|
||||
"""
|
||||
|
||||
|
||||
def _get_etud_platypus_image(t, image_width=2 * cm):
|
||||
@ -508,6 +506,7 @@ def photos_import_files_form(group_ids=()):
|
||||
back_url = f"groups_photos?{groups_infos.groups_query_args}"
|
||||
|
||||
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>
|
||||
<p><b>Vous pouvez aussi charger les photos individuellement via la fiche
|
||||
de chaque étudiant (menu "Étudiant" / "Changer la photo").</b>
|
||||
@ -527,6 +526,7 @@ def photos_import_files_form(group_ids=()):
|
||||
<li style="padding-top: 2em;">
|
||||
""",
|
||||
]
|
||||
F = html_sco_header.sco_footer()
|
||||
vals = scu.get_request_args()
|
||||
vals["group_ids"] = groups_infos.group_ids
|
||||
tf = TrivialFormulator(
|
||||
@ -540,40 +540,37 @@ def photos_import_files_form(group_ids=()):
|
||||
)
|
||||
|
||||
if tf[0] == 0:
|
||||
return render_template(
|
||||
"sco_page.j2",
|
||||
title="Import des photos des étudiants",
|
||||
content="\n".join(H) + tf[1] + "</li></ol>",
|
||||
)
|
||||
if tf[0] == -1:
|
||||
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)
|
||||
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,
|
||||
),
|
||||
)
|
||||
(
|
||||
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):
|
||||
|
@ -59,11 +59,11 @@ div.sco-app-content {
|
||||
}
|
||||
|
||||
.space-before-18 {
|
||||
margin-top: 18px !important;
|
||||
margin-top: 18px;
|
||||
}
|
||||
|
||||
.space-before-24 {
|
||||
margin-top: 24px !important;
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
div.scobox.maxwidth {
|
||||
@ -480,7 +480,7 @@ div.box-chercheetud {
|
||||
}
|
||||
|
||||
div.box-chercheetud form input {
|
||||
max-width: 120px;
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
/* Page accueil général */
|
||||
|
@ -323,179 +323,4 @@ body {
|
||||
|
||||
#tableau-modules-details:not([open]) #tableau_modules {
|
||||
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 ==> */
|
||||
}
|
10
app/static/js/trombino.js
Normal file
10
app/static/js/trombino.js
Normal file
@ -0,0 +1,10 @@
|
||||
// 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
app/static/libjs/bootstrap
Symbolic link
1
app/static/libjs/bootstrap
Symbolic link
@ -0,0 +1 @@
|
||||
bootstrap-5.3.3-dist/
|
4085
app/static/libjs/bootstrap-5.3.3-dist/css/bootstrap-grid.css
vendored
Normal file
4085
app/static/libjs/bootstrap-5.3.3-dist/css/bootstrap-grid.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
6
app/static/libjs/bootstrap-5.3.3-dist/css/bootstrap-grid.min.css
vendored
Normal file
6
app/static/libjs/bootstrap-5.3.3-dist/css/bootstrap-grid.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
4084
app/static/libjs/bootstrap-5.3.3-dist/css/bootstrap-grid.rtl.css
vendored
Normal file
4084
app/static/libjs/bootstrap-5.3.3-dist/css/bootstrap-grid.rtl.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
6
app/static/libjs/bootstrap-5.3.3-dist/css/bootstrap-grid.rtl.min.css
vendored
Normal file
6
app/static/libjs/bootstrap-5.3.3-dist/css/bootstrap-grid.rtl.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
597
app/static/libjs/bootstrap-5.3.3-dist/css/bootstrap-reboot.css
vendored
Normal file
597
app/static/libjs/bootstrap-5.3.3-dist/css/bootstrap-reboot.css
vendored
Normal file
@ -0,0 +1,597 @@
|
||||
/*!
|
||||
* 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
6
app/static/libjs/bootstrap-5.3.3-dist/css/bootstrap-reboot.min.css
vendored
Normal file
6
app/static/libjs/bootstrap-5.3.3-dist/css/bootstrap-reboot.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
594
app/static/libjs/bootstrap-5.3.3-dist/css/bootstrap-reboot.rtl.css
vendored
Normal file
594
app/static/libjs/bootstrap-5.3.3-dist/css/bootstrap-reboot.rtl.css
vendored
Normal file
@ -0,0 +1,594 @@
|
||||
/*!
|
||||
* 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
6
app/static/libjs/bootstrap-5.3.3-dist/css/bootstrap-reboot.rtl.min.css
vendored
Normal file
6
app/static/libjs/bootstrap-5.3.3-dist/css/bootstrap-reboot.rtl.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
5402
app/static/libjs/bootstrap-5.3.3-dist/css/bootstrap-utilities.css
vendored
Normal file
5402
app/static/libjs/bootstrap-5.3.3-dist/css/bootstrap-utilities.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
6
app/static/libjs/bootstrap-5.3.3-dist/css/bootstrap-utilities.min.css
vendored
Normal file
6
app/static/libjs/bootstrap-5.3.3-dist/css/bootstrap-utilities.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
5393
app/static/libjs/bootstrap-5.3.3-dist/css/bootstrap-utilities.rtl.css
vendored
Normal file
5393
app/static/libjs/bootstrap-5.3.3-dist/css/bootstrap-utilities.rtl.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
6
app/static/libjs/bootstrap-5.3.3-dist/css/bootstrap-utilities.rtl.min.css
vendored
Normal file
6
app/static/libjs/bootstrap-5.3.3-dist/css/bootstrap-utilities.rtl.min.css
vendored
Normal file
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
Normal file
12057
app/static/libjs/bootstrap-5.3.3-dist/css/bootstrap.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
6
app/static/libjs/bootstrap-5.3.3-dist/css/bootstrap.min.css
vendored
Normal file
6
app/static/libjs/bootstrap-5.3.3-dist/css/bootstrap.min.css
vendored
Normal file
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
Normal file
12030
app/static/libjs/bootstrap-5.3.3-dist/css/bootstrap.rtl.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
6
app/static/libjs/bootstrap-5.3.3-dist/css/bootstrap.rtl.min.css
vendored
Normal file
6
app/static/libjs/bootstrap-5.3.3-dist/css/bootstrap.rtl.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
6314
app/static/libjs/bootstrap-5.3.3-dist/js/bootstrap.bundle.js
vendored
Normal file
6314
app/static/libjs/bootstrap-5.3.3-dist/js/bootstrap.bundle.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
7
app/static/libjs/bootstrap-5.3.3-dist/js/bootstrap.bundle.min.js
vendored
Normal file
7
app/static/libjs/bootstrap-5.3.3-dist/js/bootstrap.bundle.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
4447
app/static/libjs/bootstrap-5.3.3-dist/js/bootstrap.esm.js
vendored
Normal file
4447
app/static/libjs/bootstrap-5.3.3-dist/js/bootstrap.esm.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
7
app/static/libjs/bootstrap-5.3.3-dist/js/bootstrap.esm.min.js
vendored
Normal file
7
app/static/libjs/bootstrap-5.3.3-dist/js/bootstrap.esm.min.js
vendored
Normal file
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
Normal file
4494
app/static/libjs/bootstrap-5.3.3-dist/js/bootstrap.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
7
app/static/libjs/bootstrap-5.3.3-dist/js/bootstrap.min.js
vendored
Normal file
7
app/static/libjs/bootstrap-5.3.3-dist/js/bootstrap.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
44
app/static/libjs/bootstrap-multiselect-1.1.2/bootstrap-multiselect.min.css
vendored
Normal file
44
app/static/libjs/bootstrap-multiselect-1.1.2/bootstrap-multiselect.min.css
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
/**
|
||||
* 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}
|
44
app/static/libjs/bootstrap-multiselect-1.1.2/bootstrap-multiselect.min.js
vendored
Normal file
44
app/static/libjs/bootstrap-multiselect-1.1.2/bootstrap-multiselect.min.js
vendored
Normal file
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="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="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>
|
@ -102,6 +102,7 @@
|
||||
|
||||
{% block styles %}
|
||||
{{ 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/minitimeline.css">
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
<br />
|
||||
Ces utilisateurs peuvent être réactivés à tout moment.
|
||||
</div>
|
||||
<div class="row space-before-24">
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
{{ wtf.quick_form(form, button_map={'submit':'secondary'}) }}
|
||||
</div>
|
||||
|
@ -14,6 +14,9 @@
|
||||
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"
|
||||
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 %}
|
||||
<link rel="stylesheet" href="{{scu.STATIC_DIR}}/{{css}}">
|
||||
{% endfor %}
|
||||
@ -32,6 +35,8 @@
|
||||
<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-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/qtip/jquery.qtip-3.0.3.min.js"></script>
|
||||
<script src="{{scu.STATIC_DIR}}/libjs/purl.js"></script>
|
||||
|
@ -4,7 +4,6 @@
|
||||
{% block styles %}
|
||||
{{super()}}
|
||||
<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">
|
||||
{% endblock %}
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
{% extends 'sco_page.j2' %}
|
||||
|
||||
{% import 'wtf.j2' as wtf %}
|
||||
|
||||
{% macro render_field(field) %}
|
||||
@ -17,12 +15,6 @@
|
||||
</tr>
|
||||
{% endmacro %}
|
||||
|
||||
{% block app_content %}
|
||||
|
||||
{{ evaluations_description|safe}}
|
||||
|
||||
<h3 class="space-before-24">Placement et émargement des étudiants</h3>
|
||||
|
||||
<div class="saisienote_etape1 form_placement">
|
||||
<form method=post>
|
||||
{{ form.evaluation_id }}
|
||||
@ -86,4 +78,3 @@
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
{% endblock %}
|
@ -4,6 +4,7 @@
|
||||
|
||||
{% block styles %}
|
||||
{{super()}}
|
||||
<link rel="stylesheet" href="{{scu.STATIC_DIR}}/libjs/bootstrap/css/bootstrap.min.css">
|
||||
|
||||
<style>
|
||||
div{
|
||||
|
@ -1,5 +1,5 @@
|
||||
{# -*- mode: jinja-html -*- #}
|
||||
{% extends 'sco_page.j2' %}
|
||||
{% extends 'base.j2' %}
|
||||
|
||||
{% block app_content %}
|
||||
|
||||
|
@ -2,8 +2,8 @@
|
||||
{% macro form_errors(form, hiddens=True) %}
|
||||
{%- if form.errors %}
|
||||
{%- for fieldname, errors in form.errors.items() %}
|
||||
{%- if is_hidden_field(form[fieldname]) and hiddens or
|
||||
not is_hidden_field(form[fieldname]) and hiddens != 'only' %}
|
||||
{%- if bootstrap_is_hidden_field(form[fieldname]) and hiddens or
|
||||
not bootstrap_is_hidden_field(form[fieldname]) and hiddens != 'only' %}
|
||||
{%- for error in errors %}
|
||||
<p class="error">{{error}}</p>
|
||||
{%- endfor %}
|
||||
@ -75,7 +75,7 @@ the necessary fix for required=False attributes, but will also not set the requi
|
||||
<fieldset>
|
||||
<legend>{{field.label}}</legend>
|
||||
{%- for subfield in field %}
|
||||
{% if not is_hidden_field(subfield) -%}
|
||||
{% if not bootstrap_is_hidden_field(subfield) -%}
|
||||
{{ form_field(subfield,
|
||||
form_type=form_type,
|
||||
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') }}
|
||||
|
||||
{%- for field in form %}
|
||||
{% if not is_hidden_field(field) -%}
|
||||
{% if not bootstrap_is_hidden_field(field) -%}
|
||||
{{ form_field(field,
|
||||
form_type=form_type,
|
||||
horizontal_columns=horizontal_columns,
|
||||
|
@ -24,8 +24,7 @@
|
||||
##############################################################################
|
||||
|
||||
"""
|
||||
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"
|
||||
|
||||
"""
|
||||
|
||||
@ -33,7 +32,8 @@ import dateutil
|
||||
import dateutil.parser
|
||||
|
||||
import flask
|
||||
from flask import abort, flash, g, render_template, request, url_for
|
||||
from flask import g, request
|
||||
from flask import abort, flash, url_for
|
||||
from flask_login import current_user
|
||||
|
||||
from app import db, log
|
||||
@ -54,8 +54,11 @@ from app.scodoc import sco_utils as scu
|
||||
from app.scodoc.sco_permissions import Permission
|
||||
from app.scodoc.sco_exceptions import ScoValueError
|
||||
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_abs_billets
|
||||
from app.scodoc import sco_etud
|
||||
from app.scodoc import sco_preferences
|
||||
|
||||
|
||||
@ -74,7 +77,11 @@ from app.scodoc import sco_preferences
|
||||
def index_html():
|
||||
"""Gestionnaire absences, page principale"""
|
||||
|
||||
H = []
|
||||
H = [
|
||||
html_sco_header.sco_header(
|
||||
page_title="Billets d'absences",
|
||||
),
|
||||
]
|
||||
if current_user.has_permission(
|
||||
Permission.AbsChange
|
||||
) and sco_preferences.get_preference("handle_billets_abs"):
|
||||
@ -86,9 +93,8 @@ def index_html():
|
||||
</li></ul>
|
||||
"""
|
||||
)
|
||||
return render_template(
|
||||
"sco_page_dept.j2", title="Billets d'absences", content="\n".join(H)
|
||||
)
|
||||
H.append(html_sco_header.sco_footer())
|
||||
return "\n".join(H)
|
||||
|
||||
|
||||
# ----- Gestion des "billets d'absence": signalement par les etudiants eux mêmes (à travers le portail)
|
||||
@ -152,8 +158,12 @@ def add_billets_absence_form(etudid):
|
||||
"""Formulaire ajout billet (pour tests seulement, le vrai
|
||||
formulaire accessible aux etudiants étant sur le portail étudiant).
|
||||
"""
|
||||
_ = Identite.get_etud(etudid) # check
|
||||
H = ["""<h2>Formulaire ajout billet (pour tests)</h2>"""]
|
||||
etud = sco_etud.get_etud_info(filled=True, etudid=etudid)[0]
|
||||
H = [
|
||||
html_sco_header.sco_header(
|
||||
page_title="Billet d'absence de %s" % etud["nomprenom"]
|
||||
)
|
||||
]
|
||||
tf = TrivialFormulator(
|
||||
request.base_url,
|
||||
scu.get_request_args(),
|
||||
@ -169,11 +179,7 @@ def add_billets_absence_form(etudid):
|
||||
),
|
||||
)
|
||||
if tf[0] == 0:
|
||||
return render_template(
|
||||
"sco_page_dept.j2",
|
||||
title="""Billet d'absence de {etud["nomprenom"]}""",
|
||||
content="\n".join(H) + tf[1],
|
||||
)
|
||||
return "\n".join(H) + tf[1] + html_sco_header.sco_footer()
|
||||
elif tf[0] == -1:
|
||||
return flask.redirect(url_for("scolar.index_html", scodoc_dept=g.scodoc_dept))
|
||||
else:
|
||||
@ -236,8 +242,11 @@ def list_billets():
|
||||
et formulaire recherche d'un billet.
|
||||
"""
|
||||
table = sco_abs_billets.table_billets_etud(etat=False)
|
||||
table_html = table.html()
|
||||
T = table.html()
|
||||
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>",
|
||||
]
|
||||
|
||||
@ -248,18 +257,15 @@ def list_billets():
|
||||
submitbutton=False,
|
||||
)
|
||||
if tf[0] == 0:
|
||||
return render_template(
|
||||
"sco_page.j2",
|
||||
title="Billet d'absence non traités",
|
||||
content="\n".join(H) + tf[1] + table_html,
|
||||
return "\n".join(H) + tf[1] + T + html_sco_header.sco_footer()
|
||||
else:
|
||||
return flask.redirect(
|
||||
url_for(
|
||||
"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"])
|
||||
@ -331,8 +337,7 @@ def _ProcessBilletAbsence(
|
||||
def process_billet_absence_form(billet_id: int):
|
||||
"""Formulaire traitement d'un billet"""
|
||||
if not isinstance(billet_id, int):
|
||||
abort(404, "billet_id invalide")
|
||||
return # safety guard
|
||||
raise abort(404, "billet_id invalide")
|
||||
billet: BilletAbsence = (
|
||||
BilletAbsence.query.filter_by(id=billet_id)
|
||||
.join(Identite)
|
||||
@ -347,6 +352,9 @@ def process_billet_absence_form(billet_id: int):
|
||||
etud = billet.etudiant
|
||||
|
||||
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="{
|
||||
url_for("scolar.fiche_etud", scodoc_dept=g.scodoc_dept, etudid=etud.id)
|
||||
}">{etud.nomprenom}</a></h2>
|
||||
@ -395,11 +403,7 @@ def process_billet_absence_form(billet_id: int):
|
||||
</p>
|
||||
"""
|
||||
|
||||
return render_template(
|
||||
"sco_page.j2",
|
||||
title=f"Traitement billet d'absence de {etud.nomprenom}",
|
||||
content="\n".join(H) + "<br>" + tf[1] + F,
|
||||
)
|
||||
return "\n".join(H) + "<br>" + tf[1] + F + html_sco_header.sco_footer()
|
||||
elif tf[0] == -1:
|
||||
return flask.redirect(url_for("scolar.index_html", scodoc_dept=g.scodoc_dept))
|
||||
else:
|
||||
@ -410,7 +414,7 @@ def process_billet_absence_form(billet_id: int):
|
||||
j = "non justifiées"
|
||||
H.append('<div class="head_message">')
|
||||
if n > 0:
|
||||
H.append(f"{n} absences (1/2 journées) {j} ajoutées")
|
||||
H.append("%d absences (1/2 journées) %s ajoutées" % (n, j))
|
||||
elif n == 0:
|
||||
H.append("Aucun jour d'absence dans les dates indiquées !")
|
||||
elif n < 0:
|
||||
@ -430,8 +434,4 @@ def process_billet_absence_form(billet_id: int):
|
||||
)
|
||||
tab = sco_abs_billets.table_billets(billets, etud=etud)
|
||||
H.append(tab.html())
|
||||
return render_template(
|
||||
"sco_page.j2",
|
||||
title=f"Traitement billet d'absence de {etud.nomprenom}",
|
||||
content="\n".join(H),
|
||||
)
|
||||
return "\n".join(H) + html_sco_header.sco_footer()
|
||||
|
@ -96,6 +96,9 @@ from app.tables.visu_assiduites import TableAssi, etuds_sorted_from_ids
|
||||
from app.scodoc.sco_archives_justificatifs import JustificatifArchiver
|
||||
|
||||
|
||||
CSSSTYLES = html_sco_header.BOOTSTRAP_CSS
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
#
|
||||
# Assiduité (/ScoDoc/<dept>/Scolarite/Assiduites/...)
|
||||
@ -1070,10 +1073,10 @@ def signal_assiduites_group():
|
||||
select_all_when_unspecified=True,
|
||||
)
|
||||
if not groups_infos.members:
|
||||
return render_template(
|
||||
"sco_page.j2",
|
||||
title="Saisie de l'assiduité",
|
||||
content="<h3>Aucun étudiant !</h3>",
|
||||
return (
|
||||
html_sco_header.sco_header(page_title="Saisie de l'assiduité")
|
||||
+ "<h3>Aucun étudiant ! </h3>"
|
||||
+ html_sco_header.sco_footer()
|
||||
)
|
||||
|
||||
# --- Filtrage par formsemestre ---
|
||||
@ -1949,10 +1952,10 @@ def signal_assiduites_hebdo():
|
||||
group_ids, formsemestre_id=formsemestre.id, select_all_when_unspecified=True
|
||||
)
|
||||
if not groups_infos.members:
|
||||
return render_template(
|
||||
"sco_page.j2",
|
||||
title="Assiduité: feuille saisie hebdomadaire",
|
||||
content="<h3>Aucun étudiant !</h3>",
|
||||
return (
|
||||
html_sco_header.sco_header(page_title="Assiduité: saisie hebdomadaire")
|
||||
+ "<h3>Aucun étudiant ! </h3>"
|
||||
+ html_sco_header.sco_footer()
|
||||
)
|
||||
|
||||
# Récupération des étudiants
|
||||
@ -2302,10 +2305,12 @@ def feuille_abs_hebdo():
|
||||
group_ids, formsemestre_id=formsemestre.id, select_all_when_unspecified=True
|
||||
)
|
||||
if not groups_infos.members:
|
||||
return render_template(
|
||||
"sco_page.j2",
|
||||
title="Assiduité: feuille saisie hebdomadaire",
|
||||
content="<h3>Aucun étudiant !</h3>",
|
||||
return (
|
||||
html_sco_header.sco_header(
|
||||
page_title="Assiduité: feuille saisie hebdomadaire"
|
||||
)
|
||||
+ "<h3>Aucun étudiant ! </h3>"
|
||||
+ html_sco_header.sco_footer()
|
||||
)
|
||||
|
||||
# Gestion des jours
|
||||
|
@ -60,6 +60,7 @@ from app.models import (
|
||||
ScoDocSiteConfig,
|
||||
)
|
||||
from app.scodoc import (
|
||||
html_sco_header,
|
||||
sco_bulletins_json,
|
||||
sco_cache,
|
||||
sco_formsemestre_exterieurs,
|
||||
@ -250,23 +251,27 @@ def formsemestre_validation_but(
|
||||
</div>
|
||||
"""
|
||||
|
||||
H = ["""<div class="jury_but">"""]
|
||||
inscription = formsemestre.etuds_inscriptions.get(etudid)
|
||||
if not inscription:
|
||||
raise ScoValueError("étudiant non inscrit au semestre")
|
||||
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),
|
||||
H = [
|
||||
html_sco_header.sco_header(
|
||||
page_title=f"Validation BUT S{formsemestre.semestre_id}",
|
||||
formsemestre_id=formsemestre_id,
|
||||
etudid=etudid,
|
||||
cssstyles=[
|
||||
"css/jury_but.css",
|
||||
"css/cursus_but.css",
|
||||
],
|
||||
javascripts=("js/jury_but.js",),
|
||||
content=(
|
||||
"\n".join(H)
|
||||
+ f"""
|
||||
),
|
||||
"""<div class="jury_but">
|
||||
""",
|
||||
]
|
||||
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 class="bull_head">
|
||||
<div>
|
||||
@ -286,7 +291,7 @@ def formsemestre_validation_but(
|
||||
{navigation_div}
|
||||
</div>
|
||||
"""
|
||||
),
|
||||
+ html_sco_header.sco_footer()
|
||||
)
|
||||
|
||||
deca = jury_but.DecisionsProposeesAnnee(etud, formsemestre)
|
||||
@ -336,7 +341,7 @@ def formsemestre_validation_but(
|
||||
êtes-vous certain de vouloir enregistrer une décision de jury ?
|
||||
</div>"""
|
||||
if read_only:
|
||||
warning += """<div class="warning">Affichage en lecture seule</div>"""
|
||||
warning += f"""<div class="warning">Affichage en lecture seule</div>"""
|
||||
|
||||
if deca.formsemestre_impair:
|
||||
inscription = deca.formsemestre_impair.etuds_inscriptions.get(etud.id)
|
||||
@ -502,17 +507,7 @@ def formsemestre_validation_but(
|
||||
</div>
|
||||
"""
|
||||
)
|
||||
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),
|
||||
)
|
||||
return "\n".join(H) + html_sco_header.sco_footer()
|
||||
|
||||
|
||||
@bp.route(
|
||||
|
@ -88,6 +88,7 @@ from app.scodoc.sco_exceptions import (
|
||||
ScoInvalidIdType,
|
||||
)
|
||||
from app.scodoc import (
|
||||
html_sco_header,
|
||||
sco_apogee_compare,
|
||||
sco_archives_formsemestre,
|
||||
sco_assiduites,
|
||||
@ -769,10 +770,8 @@ def formation_import_xml_form():
|
||||
cancelbutton="Annuler",
|
||||
)
|
||||
if tf[0] == 0:
|
||||
return render_template(
|
||||
"sco_page_dept.j2",
|
||||
title="Import d'une formation",
|
||||
content=f"""
|
||||
return f"""
|
||||
{ html_sco_header.sco_header(page_title="Import d'une formation") }
|
||||
<h2>Import d'une formation</h2>
|
||||
<p>Création d'une formation (avec UE, matières, modules)
|
||||
à partir un fichier XML (réservé aux utilisateurs avertis).
|
||||
@ -784,8 +783,8 @@ def formation_import_xml_form():
|
||||
}">page des référentiels</a>).
|
||||
</p>
|
||||
{ tf[1] }
|
||||
""",
|
||||
)
|
||||
{ html_sco_header.sco_footer() }
|
||||
"""
|
||||
elif tf[0] == -1:
|
||||
return flask.redirect(url_for("notes.index_html", scodoc_dept=g.scodoc_dept))
|
||||
else:
|
||||
@ -793,10 +792,8 @@ def formation_import_xml_form():
|
||||
tf[2]["xmlfile"].read()
|
||||
)
|
||||
|
||||
return render_template(
|
||||
"sco_page_dept.j2",
|
||||
title="Import d'une formation",
|
||||
content=f"""
|
||||
return f"""
|
||||
{ html_sco_header.sco_header(page_title="Import d'une formation") }
|
||||
<h2>Import effectué !</h2>
|
||||
<ul>
|
||||
<li><a class="stdlink" href="{
|
||||
@ -809,8 +806,8 @@ def formation_import_xml_form():
|
||||
(en cas d'erreur, par exemple pour charger auparavant le référentiel de compétences)
|
||||
</li>
|
||||
</ul>
|
||||
""",
|
||||
)
|
||||
{ html_sco_header.sco_footer() }
|
||||
"""
|
||||
|
||||
|
||||
sco_publish("/module_move", sco_edit_formation.module_move, Permission.EditFormation)
|
||||
@ -2185,17 +2182,15 @@ def formsemestre_bulletins_mailetuds(
|
||||
if sent:
|
||||
nb_sent += 1
|
||||
#
|
||||
return render_template(
|
||||
"sco_page.j2",
|
||||
title="Mailing bulletins",
|
||||
content=f"""
|
||||
return f"""
|
||||
{html_sco_header.sco_header()}
|
||||
<p>{nb_sent} bulletins sur {len(inscriptions)} envoyés par mail !</p>
|
||||
<p><a class="stdlink" href="{url_for('notes.formsemestre_status',
|
||||
scodoc_dept=g.scodoc_dept,
|
||||
formsemestre_id=formsemestre_id)
|
||||
}">continuer</a></p>
|
||||
""",
|
||||
)
|
||||
{html_sco_header.sco_footer()}
|
||||
"""
|
||||
|
||||
|
||||
sco_publish(
|
||||
@ -2263,8 +2258,10 @@ def appreciation_add_form(
|
||||
else:
|
||||
action = "Ajout"
|
||||
H = [
|
||||
html_sco_header.sco_header(),
|
||||
f"""<h2>{action} d'une appréciation sur {etud.nomprenom}</h2>""",
|
||||
]
|
||||
F = html_sco_header.sco_footer()
|
||||
descr = [
|
||||
("edit", {"input_type": "hidden", "default": edit}),
|
||||
("etudid", {"input_type": "hidden"}),
|
||||
@ -2289,7 +2286,7 @@ def appreciation_add_form(
|
||||
submitlabel="Ajouter appréciation",
|
||||
)
|
||||
if tf[0] == 0:
|
||||
return render_template("sco_page.j2", content="\n".join(H) + "\n" + tf[1])
|
||||
return "\n".join(H) + "\n" + tf[1] + F
|
||||
elif tf[0] == -1:
|
||||
return flask.redirect(bul_url)
|
||||
else:
|
||||
@ -2646,7 +2643,7 @@ def check_form_integrity(formation_id, fix=False):
|
||||
else:
|
||||
txth = "OK"
|
||||
log("ok")
|
||||
return render_template("sco_page.j2", content=txth)
|
||||
return html_sco_header.sco_header() + txth + html_sco_header.sco_footer()
|
||||
|
||||
|
||||
@bp.route("/check_formsemestre_integrity")
|
||||
@ -2684,4 +2681,6 @@ def check_formsemestre_integrity(formsemestre_id):
|
||||
else:
|
||||
diag = ["OK"]
|
||||
log("ok")
|
||||
return render_template("sco_page.j2", content="<br>".join(diag))
|
||||
return (
|
||||
html_sco_header.sco_header() + "<br>".join(diag) + html_sco_header.sco_footer()
|
||||
)
|
||||
|
@ -64,7 +64,7 @@ from app.decorators import (
|
||||
permission_required,
|
||||
)
|
||||
|
||||
from app.scodoc import sco_import_users, sco_roles_default
|
||||
from app.scodoc import html_sco_header, sco_import_users, sco_roles_default
|
||||
from app.scodoc import sco_users
|
||||
from app.scodoc import sco_utils as scu
|
||||
from app.scodoc import sco_xml
|
||||
@ -74,6 +74,7 @@ from app.scodoc.sco_import_users import generate_password
|
||||
from app.scodoc.sco_permissions_check import can_handle_passwd
|
||||
from app.scodoc.TrivialFormulator import TrivialFormulator, tf_error_message
|
||||
from app.views import users_bp as bp
|
||||
from app.views import scodoc_bp
|
||||
|
||||
|
||||
_ = lambda x: x # sans babel
|
||||
@ -91,7 +92,7 @@ class ChangePasswordForm(FlaskForm):
|
||||
validators=[
|
||||
EqualTo(
|
||||
"new_password",
|
||||
message="Les deux saisies sont différentes, recommencez",
|
||||
message="Les deux saisies sont " "différentes, recommencez",
|
||||
),
|
||||
],
|
||||
)
|
||||
@ -105,9 +106,9 @@ class ChangePasswordForm(FlaskForm):
|
||||
submit = SubmitField()
|
||||
cancel = SubmitField("Annuler")
|
||||
|
||||
def validate_email(self, e_mail):
|
||||
"vérifie que le mail est unique (inline wtf validator)"
|
||||
user = User.query.filter_by(email=e_mail.data.strip()).first()
|
||||
def validate_email(self, email):
|
||||
"vérifie que le mail est unique"
|
||||
user = User.query.filter_by(email=email.data.strip()).first()
|
||||
if user is not None and self.user_name.data != user.user_name:
|
||||
raise ValidationError(
|
||||
_("Cette adresse e-mail est déjà attribuée à un autre compte")
|
||||
@ -119,7 +120,6 @@ class ChangePasswordForm(FlaskForm):
|
||||
raise ValidationError("Mot de passe trop simple, recommencez")
|
||||
|
||||
def validate_old_password(self, old_password):
|
||||
"vérifie password actuel"
|
||||
if not current_user.check_password(old_password.data):
|
||||
raise ValidationError("Mot de passe actuel incorrect, ré-essayez")
|
||||
|
||||
@ -855,7 +855,9 @@ def import_users_generate_excel_sample():
|
||||
@scodoc7func
|
||||
def import_users_form():
|
||||
"""Import utilisateurs depuis feuille Excel"""
|
||||
head = html_sco_header.sco_header(page_title="Import utilisateurs")
|
||||
H = [
|
||||
head,
|
||||
"""<h2>Téléchargement d'une liste d'utilisateurs</h2>
|
||||
<p style="color: red">A utiliser pour importer de <b>nouveaux</b>
|
||||
utilisateurs (enseignants ou secrétaires)
|
||||
@ -884,10 +886,12 @@ def import_users_form():
|
||||
<li><b>Étape 1: </b><a class="stdlink" href="{
|
||||
url_for("users.import_users_generate_excel_sample", scodoc_dept=g.scodoc_dept)
|
||||
}">Obtenir la feuille excel vide à remplir</a>
|
||||
ou bien la liste complète des utilisateurs.
|
||||
</li>
|
||||
<li><b> Étape 2:</b>
|
||||
"""
|
||||
)
|
||||
F = html_sco_header.sco_footer()
|
||||
tf = TrivialFormulator(
|
||||
request.base_url,
|
||||
scu.get_request_args(),
|
||||
@ -911,11 +915,7 @@ def import_users_form():
|
||||
submitlabel="Télécharger",
|
||||
)
|
||||
if tf[0] == 0:
|
||||
return render_template(
|
||||
"sco_page_dept.j2",
|
||||
title="Import utilisateurs",
|
||||
content="\n".join(H) + tf[1] + "</li></ul>" + help_msg,
|
||||
)
|
||||
return "\n".join(H) + tf[1] + "</li></ul>" + help_msg + F
|
||||
elif tf[0] == -1:
|
||||
return flask.redirect(url_for("scolar.index_html", docodc_dept=g.scodoc_dept))
|
||||
|
||||
@ -923,10 +923,8 @@ def import_users_form():
|
||||
ok, diags, nb_created = sco_import_users.import_excel_file(
|
||||
tf[2]["xlsfile"], tf[2]["force"]
|
||||
)
|
||||
H = [
|
||||
"""<h2>Téléchargement d'une liste d'utilisateurs</h2>
|
||||
<ul>"""
|
||||
]
|
||||
H = [html_sco_header.sco_header(page_title="Import utilisateurs")]
|
||||
H.append("<ul>")
|
||||
for diag in diags:
|
||||
H.append(f"<li>{diag}</li>")
|
||||
H.append("</ul>")
|
||||
@ -944,9 +942,7 @@ def import_users_form():
|
||||
<p><a class="stdlink" href="{dest_url}">Continuer</a></p>
|
||||
"""
|
||||
)
|
||||
return render_template(
|
||||
"sco_page_dept.j2", title="Import utilisateurs", content="\n".join(H)
|
||||
)
|
||||
return "\n".join(H) + html_sco_header.sco_footer()
|
||||
|
||||
|
||||
@bp.route("/user_info_page")
|
||||
@ -1065,6 +1061,76 @@ 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"])
|
||||
@scodoc
|
||||
@permission_required(Permission.UsersAdmin)
|
||||
|
@ -30,6 +30,7 @@ class Config:
|
||||
# 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)
|
||||
|
||||
BOOTSTRAP_SERVE_LOCAL = os.environ.get("BOOTSTRAP_SERVE_LOCAL")
|
||||
SCODOC_DIR = os.environ.get("SCODOC_DIR", "/opt/scodoc")
|
||||
SCODOC_VAR_DIR = os.environ.get("SCODOC_VAR_DIR", "/opt/scodoc-data")
|
||||
SCODOC_LOG_FILE = os.path.join(SCODOC_VAR_DIR, "log", "scodoc.log")
|
||||
@ -45,7 +46,6 @@ class Config:
|
||||
|
||||
class ProdConfig(Config):
|
||||
"mode production, normalement derrière nginx/gunicorn"
|
||||
|
||||
FLASK_ENV = "production"
|
||||
DEBUG = False
|
||||
TESTING = False
|
||||
@ -57,7 +57,6 @@ class ProdConfig(Config):
|
||||
|
||||
class DevConfig(Config):
|
||||
"mode développement"
|
||||
|
||||
FLASK_ENV = "development"
|
||||
DEBUG = True
|
||||
TESTING = False
|
||||
@ -71,7 +70,6 @@ class DevConfig(Config):
|
||||
|
||||
class TestConfig(DevConfig):
|
||||
"Pour les tests unitaires"
|
||||
|
||||
TESTING = True
|
||||
DEBUG = False
|
||||
SQLALCHEMY_DATABASE_URI = (
|
||||
@ -84,7 +82,6 @@ class TestConfig(DevConfig):
|
||||
|
||||
class TestAPIConfig(Config):
|
||||
"Pour les tests de l'API"
|
||||
|
||||
FLASK_ENV = "test_api"
|
||||
TESTING = False
|
||||
DEBUG = True
|
||||
|
@ -1,7 +1,7 @@
|
||||
# -*- mode: python -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
SCOVERSION = "9.7.10"
|
||||
SCOVERSION = "9.7.7"
|
||||
|
||||
SCONAME = "ScoDoc"
|
||||
|
||||
|
@ -4,7 +4,7 @@ debian_version=$(cat /etc/debian_version)
|
||||
debian_version=${debian_version%%.*}
|
||||
|
||||
die() {
|
||||
echo
|
||||
echo
|
||||
echo "Erreur: $1"
|
||||
echo
|
||||
exit 1
|
||||
@ -17,8 +17,8 @@ export PATH="${PATH}":/usr/sbin:/sbin
|
||||
umask 0022
|
||||
|
||||
export SCODOC_DIR=/opt/scodoc
|
||||
export SCODOC_VAR_DIR=/opt/scodoc-data
|
||||
export SCODOC_INSTALL_STATUS_FILE="${SCODOC_VAR_DIR}/.install_status"
|
||||
export SCODOC_VAR_DIR=/opt/scodoc-data
|
||||
|
||||
export SCODOC_VERSION_DIR="${SCODOC_VAR_DIR}/config/version"
|
||||
export SCODOC_LOGOS_DIR="${SCODOC_VAR_DIR}/config/logos"
|
||||
|
||||
@ -49,7 +49,7 @@ else
|
||||
fi
|
||||
export PSQL
|
||||
|
||||
# tcp port for SQL server
|
||||
# tcp port for SQL server
|
||||
# Important note: if changed, you should probably also change it in
|
||||
# sco_utils.py (SCO_DEFAULT_SQL_PORT).
|
||||
export POSTGRES_PORT=5432
|
||||
|
@ -3,17 +3,11 @@
|
||||
# Post-installation de scodoc
|
||||
# ici, le répertoire /opt/scodoc vient d'être installé
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
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)
|
||||
|
||||
# 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
|
||||
source /opt/scodoc/tools/config.sh
|
||||
source /opt/scodoc/tools/utils.sh
|
||||
|
||||
# -- Création au besoin de notre utilisateur
|
||||
# adduser --system "${SCODOC_USER}"
|
||||
@ -32,7 +26,7 @@ do
|
||||
then
|
||||
echo adding $locname
|
||||
echo "$locname ${locname##*.}" >> /etc/locale.gen
|
||||
/usr/sbin/locale-gen --keep-existing
|
||||
/usr/sbin/locale-gen --keep-existing
|
||||
fi
|
||||
done
|
||||
echo "debian postinst: scodoc9 systemd service is $(systemctl is-active scodoc9)"
|
||||
@ -50,7 +44,7 @@ then
|
||||
if [[ ! "${SN}" =~ ^[0-9].* ]]
|
||||
then
|
||||
SN='' # fix for invalid previous replies
|
||||
fi
|
||||
fi
|
||||
else
|
||||
# first install
|
||||
echo "mode: install"
|
||||
@ -62,10 +56,10 @@ CMD="curl --fail --connect-timeout 5 --silent https://scodoc.org/scodoc-installm
|
||||
|
||||
SVERSION="$(${CMD})"
|
||||
if [ "$?" == 0 ]; then
|
||||
#echo "answer=${SVERSION}"
|
||||
#echo "answer=${SVERSION}"
|
||||
echo "${SVERSION}" > "${SCODOC_VERSION_DIR}"/scodoc.sn
|
||||
else
|
||||
echo 'Warning: cannot connect to scodoc release server'
|
||||
echo 'Warning: cannot connect to scodoc release server'
|
||||
fi
|
||||
|
||||
# ------------ LIEN VERS .env
|
||||
@ -123,7 +117,7 @@ cp "$SCODOC_DIR"/tools/etc/scodoc-logrotate /etc/logrotate.d/scodoc
|
||||
chmod 644 /etc/logrotate.d/scodoc
|
||||
|
||||
# ------------ CONFIG SERVICE SCODOC
|
||||
echo
|
||||
echo
|
||||
echo "Installation du service systemd scodoc9..."
|
||||
cp "$SCODOC_DIR"/tools/etc/scodoc9.service /etc/systemd/system/
|
||||
systemctl daemon-reload
|
||||
@ -140,6 +134,3 @@ systemctl enable scodoc9
|
||||
|
||||
# --- RESTART SCODOC
|
||||
systemctl restart scodoc9
|
||||
|
||||
# On est arrivé au bout du post-install !
|
||||
create_install_status
|
||||
|
@ -1,19 +0,0 @@
|
||||
#!/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,6 +35,14 @@ server {
|
||||
alias /opt/scodoc/app/static;
|
||||
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 {
|
||||
alias /opt/scodoc/app/static/icons/favicon.ico;
|
||||
}
|
||||
|
@ -1,16 +1,15 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Upgrade ScoDoc installation using APT
|
||||
#
|
||||
#
|
||||
# This script STOP and RESTART ScoDoc and should be runned as root
|
||||
#
|
||||
# Upgrade also the Linux system using apt.
|
||||
#
|
||||
# Script for ScoDoc 9. Lancé automatiquement par scodoc-updater.
|
||||
# Script for ScoDoc 9
|
||||
#
|
||||
# E. Viennet, sep 2013, mar 2017, jun 2019, aug 2020, dec 2020, aug 21
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Le répertoire de ce script:
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||
@ -30,7 +29,7 @@ if [ -z "$SCODOC_UPGRADE_RUNNING" ]
|
||||
# install spécifiquement scodoc9, utile si les dépendances Debian de scodoc9
|
||||
# ont été changées, ce qui peut provoquer un
|
||||
# "packages have been kept back"
|
||||
apt install scodoc9 || alarm_admin "apt install scodoc9 failed"
|
||||
apt install scodoc9
|
||||
fi
|
||||
systemctl restart redis
|
||||
systemctl restart nginx
|
||||
|
@ -2,12 +2,12 @@
|
||||
# Misc utilities for ScoDoc install shell scripts
|
||||
|
||||
to_lower() {
|
||||
echo "$1" | tr "[:upper:]" "[:lower:]"
|
||||
}
|
||||
echo "$1" | tr "[:upper:]" "[:lower:]"
|
||||
}
|
||||
|
||||
to_upper() {
|
||||
echo "$1" | tr "[:lower:]" "[:upper:]"
|
||||
}
|
||||
echo "$1" | tr "[:lower:]" "[:upper:]"
|
||||
}
|
||||
|
||||
norm_ans() {
|
||||
x=$(to_upper "$1" | tr O Y)
|
||||
@ -15,7 +15,7 @@ norm_ans() {
|
||||
}
|
||||
|
||||
check_uid_root() {
|
||||
if [ "$UID" != "0" ]
|
||||
if [ "$UID" != "0" ]
|
||||
then
|
||||
echo "Erreur: le script $1 doit etre lance par root"
|
||||
exit 1
|
||||
@ -24,7 +24,7 @@ check_uid_root() {
|
||||
|
||||
terminate() {
|
||||
status=${2:-1} # default: exit 1
|
||||
echo
|
||||
echo
|
||||
echo "Erreur: $1"
|
||||
echo
|
||||
exit $status
|
||||
@ -95,8 +95,8 @@ set_scodoc_var_dir() {
|
||||
}
|
||||
|
||||
|
||||
# XXX inutilise
|
||||
gen_passwd() {
|
||||
# XXX inutilise
|
||||
gen_passwd() {
|
||||
PASSWORD_LENGTH="8"
|
||||
ALLOWABLE_ASCII="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz@#$%^&*()_+=-?><"
|
||||
SEED=$(head -c4 /dev/urandom | od -t u4 | awk '{ print $2 }')
|
||||
@ -110,26 +110,3 @@ gen_passwd() {
|
||||
done
|
||||
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…
x
Reference in New Issue
Block a user