This commit is contained in:
leonard_montalbano 2021-12-23 08:17:11 +01:00
commit 557e076da2
8 changed files with 141 additions and 14 deletions

97
app/api/logos.py Normal file
View File

@ -0,0 +1,97 @@
# -*- mode: python -*-
# -*- coding: utf-8 -*-
##############################################################################
#
# Gestion scolarite IUT
#
# Copyright (c) 1999 - 2021 Emmanuel Viennet. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# Emmanuel Viennet emmanuel.viennet@viennet.net
#
##############################################################################
"""API: gestion des logos
Contrib @jmp
"""
from datetime import datetime
from flask import jsonify, g, send_file
from app.api import bp
from app.api import requested_format
from app.api.auth import token_auth
from app.api.errors import error_response
from app.models import Departement
from app.scodoc.sco_logos import list_logos, find_logo
from app.scodoc.sco_permissions import Permission
@bp.route("/logos", methods=["GET"])
@token_auth.login_required
def api_get_glob_logos():
if not g.current_user.has_permission(Permission.ScoSuperAdmin, None):
return error_response(401, message="accès interdit")
required_format = requested_format() # json only
if required_format is None:
return error_response(400, "Illegal format")
logos = list_logos()[None]
return jsonify(list(logos.keys()))
@bp.route("/logos/<string:logoname>", methods=["GET"])
@token_auth.login_required
def api_get_glob_logo(logoname):
if not g.current_user.has_permission(Permission.ScoSuperAdmin, None):
return error_response(401, message="accès interdit")
logo = find_logo(logoname=logoname)
if logo is None:
return error_response(404, message="logo not found")
logo.select()
return send_file(
logo.filepath,
mimetype=f"image/{logo.suffix}",
last_modified=datetime.now(),
)
@bp.route("/departements/<string:departement>/logos", methods=["GET"])
@token_auth.login_required
def api_get_local_logos(departement):
dept_id = Departement.from_acronym(departement).id
if not g.current_user.has_permission(Permission.ScoChangePreferences, departement):
return error_response(401, message="accès interdit")
logos = list_logos().get(dept_id, dict())
return jsonify(list(logos.keys()))
@bp.route("/departements/<string:departement>/logos/<string:logoname>", methods=["GET"])
@token_auth.login_required
def api_get_local_logo(departement, logoname):
# format = requested_format("jpg", ['png', 'jpg']) XXX ?
dept_id = Departement.from_acronym(departement).id
if not g.current_user.has_permission(Permission.ScoChangePreferences, departement):
return error_response(401, message="accès interdit")
logo = find_logo(logoname=logoname, dept_id=dept_id)
if logo is None:
return error_response(404, message="logo not found")
logo.select()
return send_file(
logo.filepath,
mimetype=f"image/{logo.suffix}",
last_modified=datetime.now(),
)

View File

@ -39,8 +39,10 @@ from app.scodoc.sco_permissions import Permission
def sidebar_common(): def sidebar_common():
"partie commune à toutes les sidebar" "partie commune à toutes les sidebar"
home_link = url_for("scodoc.index", scodoc_dept=g.scodoc_dept)
H = [ H = [
f"""<a class="scodoc_title" href="{url_for("scodoc.index", scodoc_dept=g.scodoc_dept)}">ScoDoc 9.1</a> f"""<a class="scodoc_title" href="{home_link}">ScoDoc 9.1</a><br>
<a href="{home_link}" class="sidebar">Accueil</a> <br>
<div id="authuser"><a id="authuserlink" href="{ <div id="authuser"><a id="authuserlink" href="{
url_for("users.user_info_page", url_for("users.user_info_page",
scodoc_dept=g.scodoc_dept, user_name=current_user.user_name) scodoc_dept=g.scodoc_dept, user_name=current_user.user_name)

View File

@ -98,6 +98,10 @@ section>div:nth-child(1){
/************/ /************/
/* Etudiant */ /* Etudiant */
/************/ /************/
.info_etudiant{
color: #000;
text-decoration: none;
}
.etudiant{ .etudiant{
display: flex; display: flex;
align-items: center; align-items: center;
@ -194,6 +198,9 @@ h3{
.info{ .info{
opacity: 0.9; opacity: 0.9;
} }
.syntheseModule{
cursor: pointer;
}
.eval, .syntheseModule{ .eval, .syntheseModule{
position: relative; position: relative;
display: flex; display: flex;

View File

@ -27,6 +27,10 @@ class releveBUT extends HTMLElement {
moduleOnOff(){ moduleOnOff(){
this.parentElement.classList.toggle("moduleOnOff"); this.parentElement.classList.toggle("moduleOnOff");
} }
goTo(){
let module = this.dataset.module;
this.parentElement.parentElement.parentElement.parentElement.querySelector("#Module_" + module).scrollIntoView();
}
set setConfig(config){ set setConfig(config){
this.config.showURL = config.showURL ?? this.config.showURL; this.config.showURL = config.showURL ?? this.config.showURL;
@ -46,6 +50,9 @@ class releveBUT extends HTMLElement {
this.shadow.querySelectorAll(".ue, .module").forEach(e => { this.shadow.querySelectorAll(".ue, .module").forEach(e => {
e.addEventListener("click", this.moduleOnOff) e.addEventListener("click", this.moduleOnOff)
}) })
this.shadow.querySelectorAll(".syntheseModule").forEach(e => {
e.addEventListener("click", this.goTo)
})
this.shadow.children[0].classList.add("ready"); this.shadow.children[0].classList.add("ready");
} }
@ -132,8 +139,15 @@ class releveBUT extends HTMLElement {
showInformations(data) { showInformations(data) {
this.shadow.querySelector(".studentPic").src = data.etudiant.photo_url || "default_Student.svg"; this.shadow.querySelector(".studentPic").src = data.etudiant.photo_url || "default_Student.svg";
let output = ` let output = '';
<div class=info_etudiant>
if(this.config.showURL){
output += `<a href="${data.etudiant.fiche_url}" class=info_etudiant>`;
} else {
output += `<div class=info_etudiant>`;
}
output += `
<div class=civilite> <div class=civilite>
${this.civilite(data.etudiant.civilite)} ${this.civilite(data.etudiant.civilite)}
${data.etudiant.nom} ${data.etudiant.nom}
@ -150,8 +164,12 @@ class releveBUT extends HTMLElement {
Code INE : ${data.etudiant.code_ine} Code INE : ${data.etudiant.code_ine}
</div> </div>
<div>${data.formation.titre}</div> <div>${data.formation.titre}</div>
</div>
`; `;
if(this.config.showURL){
output += `</a>`;
} else {
output += `</div>`;
}
this.shadow.querySelector(".infoEtudiant").innerHTML = output; this.shadow.querySelector(".infoEtudiant").innerHTML = output;
} }
@ -226,8 +244,8 @@ class releveBUT extends HTMLElement {
let titre = data.ressources[module]?.titre || data.saes[module]?.titre; let titre = data.ressources[module]?.titre || data.saes[module]?.titre;
let url = data.ressources[module]?.url || data.saes[module]?.url; let url = data.ressources[module]?.url || data.saes[module]?.url;
output += ` output += `
<div class=syntheseModule> <div class=syntheseModule data-module="${module.replace(/[^a-zA-Z0-9]/g, "")}">
<div>${this.URL(url, `${module}&nbsp;- ${titre}`)}</div> <div>${module}&nbsp;- ${titre}</div>
<div> <div>
${dataModule.moyenne} ${dataModule.moyenne}
<em>Coef.&nbsp;${dataModule.coef}</em> <em>Coef.&nbsp;${dataModule.coef}</em>
@ -249,7 +267,7 @@ class releveBUT extends HTMLElement {
let output = ""; let output = "";
Object.entries(module).forEach(([numero, content]) => { Object.entries(module).forEach(([numero, content]) => {
output += ` output += `
<div> <div id="Module_${numero.replace(/[^a-zA-Z0-9]/g, "")}">
<div class=module> <div class=module>
<h3>${this.URL(content.url, `${numero} - ${content.titre}`)}</h3> <h3>${this.URL(content.url, `${numero} - ${content.titre}`)}</h3>
<div> <div>

View File

@ -22,9 +22,10 @@
.dateInscription, .dateInscription,
.numerosEtudiant, .numerosEtudiant,
.dateNaissance{ .dateNaissance{
display: none; display: none;
}`; }`;
releve.shadowRoot.appendChild(style); releve.shadowRoot.appendChild(style);
}) });
document.querySelector("html").style.scrollBehavior = "smooth";
</script> </script>
{% endblock %} {% endblock %}

View File

@ -1,7 +1,9 @@
<h2 class="insidebar">Dépt. {{ prefs["DeptName"] }}</h2> <h2 class="insidebar"><a href="{{
<a href="{{ url_for('scolar.index_html', scodoc_dept=g.scodoc_dept) }}" class="sidebar">Accueil</a> <br /> url_for('scolar.index_html', scodoc_dept=g.scodoc_dept)
}}">Dépt. {{ prefs["DeptName"] }}</a>
</h2>
{% if prefs["DeptIntranetURL"] %} {% if prefs["DeptIntranetURL"] %}
<a href="{{ prefs["DeptIntranetURL"] }}" class="sidebar"> <a href="{{ prefs['DeptIntranetURL'] }}" class="sidebar">
{{ prefs["DeptIntranetTitle"] }}</a> {{ prefs["DeptIntranetTitle"] }}</a>
{% endif %} {% endif %}
<br /> <br />

View File

@ -134,7 +134,7 @@ def get_etud_dept():
last_etud = None last_etud = None
last_date = None last_date = None
for etud in etuds: for etud in etuds:
inscriptions = FormsemestreInscription.query.filter_by(etudid=etud.id).all() inscriptions = FormSemestreInscription.query.filter_by(etudid=etud.id).all()
for ins in inscriptions: for ins in inscriptions:
date_fin = FormSemestre.query.get(ins.formsemestre_id).date_fin date_fin = FormSemestre.query.get(ins.formsemestre_id).date_fin
if (last_date is None) or date_fin > last_date: if (last_date is None) or date_fin > last_date:

View File

@ -1,7 +1,7 @@
# -*- mode: python -*- # -*- mode: python -*-
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
SCOVERSION = "9.1.12" SCOVERSION = "9.1.15"
SCONAME = "ScoDoc" SCONAME = "ScoDoc"