Templates jinja2 pour pages ScoDoc

This commit is contained in:
Emmanuel Viennet 2021-12-04 21:06:32 +01:00
parent b1bc8b3f41
commit 2e1ec1c5ea
11 changed files with 332 additions and 50 deletions

View File

@ -128,7 +128,7 @@ _HTML_BEGIN = """<!DOCTYPE html>
def scodoc_top_html_header(page_title="ScoDoc: bienvenue"):
H = [
_HTML_BEGIN % {"page_title": page_title, "encoding": scu.SCO_ENCODING},
"""</head><body class="gtrcontent" id="gtrcontent">""",
"""</head><body id="gtrcontent">""",
scu.CUSTOM_HTML_HEADER_CNX,
]
return "\n".join(H)
@ -143,8 +143,6 @@ def sco_header(
javascripts=[], # additionals JS filenames to load
scripts=[], # script to put in page header
bodyOnLoad="", # JS
init_jquery=True, # load and init jQuery
init_jquery_ui=True, # include all stuff for jquery-ui and initialize scripts
init_qtip=False, # include qTip
init_google_maps=False, # Google maps
init_datatables=True,
@ -179,9 +177,6 @@ def sco_header(
else:
params["margin_left"] = "140px"
if init_jquery_ui or init_qtip or init_datatables:
init_jquery = True
H = [
"""<!DOCTYPE html><html lang="fr">
<head>
@ -194,11 +189,10 @@ def sco_header(
% params
]
# jQuery UI
if init_jquery_ui:
# can modify loaded theme here
H.append(
'<link type="text/css" rel="stylesheet" href="/ScoDoc/static/libjs/jquery-ui-1.10.4.custom/css/smoothness/jquery-ui-1.10.4.custom.min.css" />\n'
)
# can modify loaded theme here
H.append(
'<link type="text/css" rel="stylesheet" href="/ScoDoc/static/libjs/jquery-ui-1.10.4.custom/css/smoothness/jquery-ui-1.10.4.custom.min.css" />\n'
)
if init_google_maps:
# It may be necessary to add an API key:
H.append('<script src="https://maps.google.com/maps/api/js"></script>')
@ -227,12 +221,11 @@ def sco_header(
)
# jQuery
if init_jquery:
H.append(
"""<script src="/ScoDoc/static/jQuery/jquery.js"></script>
"""
)
H.append('<script src="/ScoDoc/static/libjs/jquery.field.min.js"></script>')
H.append(
"""<script src="/ScoDoc/static/jQuery/jquery.js"></script>
"""
)
H.append('<script src="/ScoDoc/static/libjs/jquery.field.min.js"></script>')
# qTip
if init_qtip:
H.append(
@ -242,12 +235,11 @@ def sco_header(
'<link type="text/css" rel="stylesheet" href="/ScoDoc/static/libjs/qtip/jquery.qtip-3.0.3.min.css" />'
)
if init_jquery_ui:
H.append(
'<script src="/ScoDoc/static/libjs/jquery-ui-1.10.4.custom/js/jquery-ui-1.10.4.custom.min.js"></script>'
)
# H.append('<script src="/ScoDoc/static/libjs/jquery-ui/js/jquery-ui-i18n.js"></script>')
H.append('<script src="/ScoDoc/static/js/scodoc.js"></script>')
H.append(
'<script src="/ScoDoc/static/libjs/jquery-ui-1.10.4.custom/js/jquery-ui-1.10.4.custom.min.js"></script>'
)
H.append('<script src="/ScoDoc/static/js/scodoc.js"></script>')
if init_google_maps:
H.append(
'<script src="/ScoDoc/static/libjs/jquery.ui.map.full.min.js"></script>'
@ -263,7 +255,7 @@ def sco_header(
H.append(
"""<style>
.gtrcontent {
#gtrcontent {
margin-left: %(margin_left)s;
height: 100%%;
margin-bottom: 10px;
@ -287,7 +279,7 @@ def sco_header(
#
if not no_side_bar:
H.append(html_sidebar.sidebar())
H.append("""<div class="gtrcontent" id="gtrcontent">""")
H.append("""<div id="gtrcontent">""")
#
# Barre menu semestre:
H.append(formsemestre_page_title())

View File

@ -31,6 +31,12 @@ div#gtrcontent {
margin-bottom: 4ex;
}
.gtrcontent_std {
margin-left: 140px;
height: 100%;
margin-bottom: 10px;
}
.scotext {
font-family : TimesNewRoman, "Times New Roman", Times, Baskerville, Georgia, serif;
}
@ -161,6 +167,9 @@ p.footer {
margin-top: 15px;
border-top: 1px solid rgb(60,60,60);
}
div.part2 {
margin-top: 3ex;
}
/* ---- (left) SIDEBAR ----- */
@ -262,6 +271,7 @@ div.logo-logo {
text-align: center ;
}
div.logo-logo img {
box-sizing: content-box;
margin-top: 20px;
width: 55px; /* 100px */
padding-right: 50px;
@ -378,24 +388,24 @@ table.semlist tr td.modalite {
text-align: left;
padding-right: 1em;
}
div.gtrcontent table.semlist tr.css_S-1 {
div#gtrcontent table.semlist tr.css_S-1 {
background-color: rgb(251, 250, 216);
}
div.gtrcontent table.semlist tr.css_S1 {
div#gtrcontent table.semlist tr.css_S1 {
background-color: rgb(92%,95%,94%);
}
div.gtrcontent table.semlist tr.css_S2 {
div#gtrcontent table.semlist tr.css_S2 {
background-color: rgb(214, 223, 236);
}
div.gtrcontent table.semlist tr.css_S3 {
div#gtrcontent table.semlist tr.css_S3 {
background-color: rgb(167, 216, 201);
}
div.gtrcontent table.semlist tr.css_S4 {
div#gtrcontent table.semlist tr.css_S4 {
background-color: rgb(131, 225, 140);
}
div.gtrcontent table.semlist tr.css_MEXT {
div#gtrcontent table.semlist tr.css_MEXT {
color: #0b6e08;
}
@ -1048,7 +1058,7 @@ table.notes_evaluation td.moy_ue {
color:rgb(1, 116, 96);
}
h2.formsemestre, .gtrcontent h2 {
h2.formsemestre, #gtrcontent h2 {
margin-top: 2px;
font-size: 130%;
}

View File

@ -1,17 +1,34 @@
{% extends "base.html" %}
{% extends "sco_page.html" %}
{% import 'bootstrap/wtf.html' as wtf %}
{% block app_content %}
<h1>Référentiels de compétences chargés</h1>
<h2>Référentiels de compétences chargés</h2>
<div class="row">
{{tab.html() | safe}}
</div>
<div>
<a href="{{url_for(
'notes.refcomp_load', scodoc_dept=g.scodoc_dept)
}}">charger un nouveau référentiel de compétences Orébut</a>.
<div class="part2">
<ul>
<li>
<a class="stdlink" href="{{url_for(
'notes.refcomp_load', scodoc_dept=g.scodoc_dept)
}}">Charger un nouveau référentiel de compétences Orébut</a>
</li>
</ul>
</div>
<p class="help">
Les référentiels de compétences sont généralement saisis dans une application
externe, comme Orébut pour le Bachelor Universitaire de Technologie.
</p>
<p class="help">
Il sont importés dans ScoDoc et peuvent être liés à une formation pour
permettre à ScoDoc de présenter les <em>compétences</em> et leurs
<em>apprentissages critiques</em>.
</p>
<p class="help">
ScoDoc importe le format XML généré par Orébut, et peut exporter une représentation JSON.
</p>
{% endblock %}

View File

@ -0,0 +1,35 @@
{# Description un semestre (barre de menu et infos) #}
<!-- formsemestre_header -->
<div class="formsemestre_page_title">
<div class="infos">
<span class="semtitle"><a class="stdlink" title="{{sco.sem.session_id()}}"
href="{{
url_for('notes.formsemestre_status',
scodoc_dept=g.scodoc_dept, formsemestre_id=sco.sem.id)
}}">{{sco.sem.titre}}</a>
<a title="{{sco.sem.etapes_apo_str()}}">
{% if sco.sem.semestre_id != -1 %}, {{sco.sem.formation.get_parcours().SESSION_NAME}} {{sco.sem.semestre_id}}
{% endif %}</a>
{% if sco.sem.modalite %} en {{sco.sem.modalite}}{% endif %}</span>
<span class="dates">
<a title="du {{sco.sem.date_debut.strftime('%d/%m/%Y')}}
au {{sco.sem.date_fin.strftime('%d/%m/%Y')}} ">{{sco.scu.MONTH_NAMES_ABBREV[ sco.sem.date_debut.month]}} {{sco.sem.date_debut.year}} - {{sco.scu.MONTH_NAMES_ABBREV[sco.sem.date_fin.month]}} {{sco.sem.date_fin.year}}</a></span>
<span class="resp"><a
title="{{sco.sem.responsables_str(abbrev_prenom=False)}}">{{sco.sem.responsables_str()}}</a></span>
<span class="nbinscrits"><a class="discretelink"
href="{{url_for('scolar.groups_view', scodoc_dept=g.scodoc_dept,
formsemestre_id=sco.sem.id)}}">{{sco.sem.inscriptions|length}} inscrits</a></span><span class="lock">{% if sco.sem.etat %}<a href="{{url_for("notes.formsemestre_change_lock", scodoc_dept=g.scodoc_dept, formsemestre_id=sco.sem.id)}}">{{sco.scu.icontag("lock_img", border="0", title="Semestre verrouillé")|safe}}</a>{% endif %}</span><span class="eye">
{% if sco.prefs["bul_display_publication"] %}
<a href="{{url_for("notes.formsemestre_change_publication_bul", scodoc_dept=g.scodoc_dept, formsemestre_id=sco.sem.id)}}">
{% if sco.sem.bul_hide_xml %}
{{ sco.scu.icontag("hide_img", border="0", title="Bulletins NON publiés")|safe}}
{% else %}
{{ sco.scu.icontag("eye_img", border="0", title="Bulletins publiés")|safe }}
{% endif %}
{% endif %}
</span>
</div>
{{ sco.sem_menu_bar|safe }}
</div>
<!-- end of formsemestre_header -->

View File

@ -0,0 +1,51 @@
{% extends 'bootstrap/base.html' %}
{% block styles %}
{{super()}}
<link type="text/css" rel="stylesheet" href="/ScoDoc/static/libjs/jquery-ui-1.10.4.custom/css/smoothness/jquery-ui-1.10.4.custom.min.css" />
<link rel="stylesheet" href="/ScoDoc/static/css/scodoc.css">
<link href="/ScoDoc/static/css/menu.css" rel="stylesheet" type="text/css" />
<link href="/ScoDoc/static/css/gt_table.css" rel="stylesheet" type="text/css" />
<link type="text/css" rel="stylesheet" href="/ScoDoc/static/libjs/qtip/jquery.qtip-3.0.3.min.css" />
<link rel="stylesheet" type="text/css" href="/ScoDoc/static/DataTables/datatables.min.css"/>
{% endblock %}
{% block title %}
{% if title %}{{ title }} - ScoDoc{% else %}Welcome to ScoDoc{% endif %}
{% endblock %}
{% block content %}
{% block scodoc_sidebar %}
{% include "sidebar.html" %}
{% endblock %}
<div id="gtrcontent" class="gtrcontent_std">
{% if sco.sem %}
{% block formsemestre_header %}
{% include "formsemestre_header.html" %}
{% endblock %}
{% endif %}
{% block app_content %}
page vide
{% endblock %}
</div>
{% endblock %}
{% block scripts %}
{{ super() }}
{{ moment.include_moment() }}
{{ moment.lang(g.locale) }}
<script src="/ScoDoc/static/libjs/menu.js"></script>
<script src="/ScoDoc/static/libjs/bubble.js"></script>
<script src="/ScoDoc/static/libjs/qtip/jquery.qtip-3.0.3.min.js"></script>
<script src="/ScoDoc/static/libjs/jquery-ui-1.10.4.custom/js/jquery-ui-1.10.4.custom.min.js"></script>
<script src="/ScoDoc/static/js/scodoc.js"></script>
<script src="/ScoDoc/static/DataTables/datatables.min.js"></script>
<script>
window.onload=function(){enableTooltips("gtrcontent")};
var SCO_URL="{{ url_for('scolar.index_html', scodoc_dept=g.scodoc_dept)[:-11] }}";
</script>
{% endblock %}

View File

@ -0,0 +1,98 @@
{# Barre marge gauche ScoDoc #}
<!-- sidebar -->
<div class="sidebar">
{# sidebar_common #}
<a class="scodoc_title" href="{{
url_for("scodoc.index", scodoc_dept=g.scodoc_dept)
}}">ScoDoc 9.1</a>
<div id="authuser"><a id="authuserlink" href="{{
url_for("users.user_info_page",
scodoc_dept=g.scodoc_dept, user_name=current_user.user_name)
}}">{{current_user.user_name}}</a>
<br/><a id="deconnectlink" href="{{url_for("auth.logout")}}">déconnexion</a>
</div>
{% block sidebar_dept %}
<h2 class="insidebar">Dépt. {{ sco.prefs["DeptName"] }}</h2>
<a href="{{ url_for('scolar.index_html', scodoc_dept=g.scodoc_dept) }}" class="sidebar">Accueil</a> <br />
{% if sco.prefs["DeptIntranetURL"] %}
<a href="{{ sco.prefs["DeptIntranetURL"] }}" class="sidebar">
{{ sco.prefs["DeptIntranetTitle"] }}</a>
{% endif %}
<br />
{% endblock %}
<h2 class="insidebar">Scolarité</h2>
<a href="{{url_for("scolar.index_html", scodoc_dept=g.scodoc_dept)}}" class="sidebar">Semestres</a> <br/>
<a href="{{url_for("notes.index_html", scodoc_dept=g.scodoc_dept)}}" class="sidebar">Programmes</a> <br/>
<a href="{{url_for("absences.index_html", scodoc_dept=g.scodoc_dept)}}" class="sidebar">Absences</a> <br/>
{% if current_user.has_permission(sco.Permission.ScoUsersAdmin)
or current_user.has_permission(sco.Permission.ScoUsersView)
%}
<a href="{{url_for("users.index_html", scodoc_dept=g.scodoc_dept)}}" class="sidebar">Utilisateurs</a> <br/>
{% endif %}
{% if current_user.has_permission(sco.Permission.ScoChangePreferences) %}
<a href="{{url_for("scolar.edit_preferences", scodoc_dept=g.scodoc_dept)}}"
class="sidebar">Paramétrage</a> <br/>
{% endif %}
{# /sidebar_common #}
<div class="box-chercheetud">Chercher étudiant:<br/>
<form method="get" id="form-chercheetud"
action="{{ url_for('scolar.search_etud_in_dept', scodoc_dept=g.scodoc_dept) }}">
<div>
<input type="text" size="12" id="in-expnom" name="expnom" spellcheck="false"/>
</div>
</form>
</div>
<div class="etud-insidebar">
{% if sco.etud %}
<h2 id="insidebar-etud"><a href="{{url_for(
"scolar.ficheEtud", scodoc_dept=g.scodoc_dept, etudid=sco.etud.id
)}}" class="sidebar">
<span class="fontred">{{sco.etud.civilite_str()}} {{sco.etud.nom_disp()}}</span></a>
</h2>
<b>Absences</b>
{% if sco.etud_cur_sem %}
<span title="absences du {{ sco.etud_cur_sem['date_debut'] }}
au {{ sco.etud_cur_sem['date_fin'] }}">(1/2 j.)
<br/>{{sco.nbabsjust}} J., {{sco.nbabsnj}} N.J.</span>
{% endif %}
<ul>
{% if current_user.has_permission(sco.Permission.ScoAbsChange) %}
<li><a href="{{ url_for('absences.SignaleAbsenceEtud', scodoc_dept=g.scodoc_dept,
etudid=sco.etud.id) }}">Ajouter</a></li>
<li><a href="{{ url_for('absences.JustifAbsenceEtud', scodoc_dept=g.scodoc_dept,
etudid=sco.etud.id) }}">Justifier</a></li>
<li><a href="{{ url_for('absences.AnnuleAbsenceEtud', scodoc_dept=g.scodoc_dept,
etudid=sco.etud.id) }}">Supprimer</a></li>
{% if sco.prefs["handle_billets_abs"] %}
<li><a href="{{ url_for('absences.listeBilletsEtud', scodoc_dept=g.scodoc_dept,
etudid=sco.etud.id) }}">Billets</a></li>
{% endif %}
{% endif %}
<li><a href="{{ url_for('absences.CalAbs', scodoc_dept=g.scodoc_dept,
etudid=sco.etud.id) }}">Calendrier</a></li>
<li><a href="{{ url_for('absences.ListeAbsEtud', scodoc_dept=g.scodoc_dept,
etudid=sco.etud.id) }}">Liste</a></li>
</ul>
{% endif %}
</div> {# /etud-insidebar #}
{# LOGO #}
<div class="logo-insidebar">
<div class="sidebar-bottom"><a href="{{ url_for( 'scodoc.about',
scodoc_dept=g.scodoc_dept ) }}" class="sidebar">À propos</a>
<br/>
<a href="{{ sco.scu.SCO_USER_MANUAL }}" target="_blank" class="sidebar">Aide</a>
</div>
</div>
<div class="logo-logo">
<a href="{{ url_for( 'scodoc.about', scodoc_dept=g.scodoc_dept ) }}">
{{ sco.scu.icontag("scologo_img", no_size=True) | safe}}</a>
</div>
</div>
<!-- end of sidebar -->

View File

@ -4,11 +4,18 @@
import datetime
from flask import Blueprint
from flask import g, current_app
from flask import g, current_app, request
from flask_login import current_user
from app import db
from app.models import Identite
from app.models.formsemestre import FormSemestre
from app.scodoc import notesdb as ndb
from app.scodoc import sco_abs
from app.scodoc import sco_formsemestre_status
from app.scodoc import sco_preferences
from app.scodoc.sco_permissions import Permission
from app.scodoc import sco_utils as scu
scodoc_bp = Blueprint("scodoc", __name__)
scolar_bp = Blueprint("scolar", __name__)
@ -16,8 +23,6 @@ notes_bp = Blueprint("notes", __name__)
users_bp = Blueprint("users", __name__)
absences_bp = Blueprint("absences", __name__)
from app.views import scodoc, notes, scolar, absences, users, pn_modules, refcomp
# Cette fonction est bien appelée avant toutes les requêtes
# de tous les blueprints
@ -39,3 +44,51 @@ def start_scodoc_request():
def close_dept_db_connection(arg):
# current_app.logger.info("close_db_connection")
ndb.close_db_connection()
class ScoData:
"""Classe utilisée pour passer des valeurs aux vues (templates)"""
def __init__(self):
# Champs utilisés par toutes les pages ScoDoc (sidebar, en-tête)
self.Permission = Permission
self.scu = scu
# -- Informations étudiant courant, si sélectionné:
etudid = g.get("etudid", None)
if not etudid:
if request.method == "GET":
etudid = request.args.get("etudid", None)
elif request.method == "POST":
etudid = request.form.get("etudid", None)
if etudid:
# Infos sur l'étudiant courant
self.etud = Identite.query.get_or_404(etudid)
ins = self.etud.inscription_courante()
if ins:
self.etud_cur_sem = ins.formsemestre
self.nbabs, self.nbabsjust = sco_abs.get_abs_count_in_interval(
etudid,
self.etud_cur_sem.date_debut.isoformat(),
self.etud_cur_sem.date_fin.isoformat(),
)
self.nbabsnj = self.nbabs - self.nbabsjust
else:
self.etud_cur_sem = None
else:
self.etud = None
# --- Informations sur semestre courant, si sélectionné
formsemestre_id = sco_formsemestre_status.retreive_formsemestre_from_request()
if formsemestre_id is None:
self.sem = None
self.sem_menu_bar = None
else:
self.sem = FormSemestre.query.get_or_404(formsemestre_id)
self.sem_menu_bar = sco_formsemestre_status.formsemestre_status_menubar(
self.sem.to_dict()
)
# --- Préférences
self.prefs = sco_preferences.SemPreferences(formsemestre_id)
from app.views import scodoc, notes, scolar, absences, users, pn_modules, refcomp

View File

@ -466,9 +466,24 @@ def index_html():
if editable:
H.append(
"""<p><a class="stdlink" href="formation_create" id="link-create-formation">Créer une formation</a></p>
<p><a class="stdlink" href="formation_import_xml_form">Importer une formation (xml)</a></p>
<p class="help">Une "formation" est un programme pédagogique structuré en UE, matières et modules. Chaque semestre se réfère à une formation. La modification d'une formation affecte tous les semestres qui s'y réfèrent.</p>
f"""
<p class="help">Une "formation" est un programme pédagogique structuré
en UE, matières et modules. Chaque semestre se réfère à une formation.
La modification d'une formation affecte tous les semestres qui s'y
réfèrent.</p>
<ul>
<li><a class="stdlink" href="formation_create" id="link-create-formation">Créer une formation</a>
</li>
<li><a class="stdlink" href="formation_import_xml_form">Importer une formation (xml)</a>
</li>
</ul>
<h3>Référentiels de compétences</h3>
<ul>
<li><a class="stdlink" href="{url_for('notes.refcomp_table', scodoc_dept=g.scodoc_dept)}">Liste des référentiels chargés</a>
</li>
</ul>
"""
)

View File

@ -23,9 +23,11 @@ from app.models.but_refcomp import ApcReferentielCompetences
from app.but.import_refcomp import orebut_import_refcomp
from app.but.forms.refcomp_forms import FormationRefCompForm, RefCompLoadForm
from app.scodoc.gen_tables import GenTable
from app.scodoc import html_sidebar
from app.scodoc.sco_exceptions import ScoFormatError
from app.scodoc.sco_permissions import Permission
from app.views import notes_bp as bp
from app.views import ScoData
@bp.route("/referentiel/comp/get/<int:refcomp_id>")
@ -58,13 +60,20 @@ def refcomp_table():
for ref in refs
],
)
return render_template("but/refcomp_table.html", tab=tab)
return render_template(
"but/refcomp_table.html",
tab=tab,
title="Référentiels de compétences",
sco=ScoData(),
)
@bp.route("/refcomp_assoc/<int:formation_id>", methods=["GET", "POST"])
@bp.route(
"/referentiel/comp/assoc_formation/<int:formation_id>", methods=["GET", "POST"]
)
@scodoc
@permission_required(Permission.ScoChangeFormation)
def refcomp_assoc(formation_id: int):
def refcomp_assoc_formation(formation_id: int):
"""Formulaire association ref. compétence"""
formation = Formation.query.get_or_404(formation_id)
form = FormationRefCompForm()
@ -97,6 +106,7 @@ def refcomp_assoc(formation_id: int):
form=form,
referentiel_competence_id=formation.referentiel_competence_id,
formation=formation,
title="Association réf. compétences",
)
@ -129,7 +139,7 @@ def refcomp_load(formation_id=None):
if formation is not None:
return redirect(
url_for(
"notes.refcomp_assoc",
"notes.refcomp_assoc_formation",
scodoc_dept=g.scodoc_dept,
formation_id=formation.formation_id,
)
@ -141,4 +151,5 @@ def refcomp_load(formation_id=None):
"but/refcomp_load.html",
form=form,
formation=formation,
title="Chargement réf. compétences",
)

View File

@ -1150,7 +1150,7 @@ def etudident_edit_form():
def _etudident_create_or_edit_form(edit):
"Le formulaire HTML"
H = [html_sco_header.sco_header(init_jquery_ui=True)]
H = [html_sco_header.sco_header()]
F = html_sco_header.sco_footer()
vals = scu.get_request_args()
etudid = vals.get("etudid", None)

View File

@ -640,7 +640,7 @@ td.colcomment, span.colcomment {
color: rgb(80,100,80);
}
h2.formsemestre, .gtrcontent h2 {
h2.formsemestre, #gtrcontent h2 {
margin-top: 2px;
font-size: 130%;
}