From 6baec61e0ea5169dfa66372269b8edc8238bd131 Mon Sep 17 00:00:00 2001 From: lehmann Date: Tue, 21 Dec 2021 22:22:55 +0100 Subject: [PATCH 1/4] =?UTF-8?q?Bulletin=20:=20Liens=20vers=20plus=20bas=20?= =?UTF-8?q?+=20lien=20vers=20fiche=20=C3=A9tudiant?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/static/css/releve-but.css | 7 +++++++ app/static/js/releve-but.js | 30 ++++++++++++++++++++++++------ app/templates/but/bulletin.html | 5 +++-- 3 files changed, 34 insertions(+), 8 deletions(-) diff --git a/app/static/css/releve-but.css b/app/static/css/releve-but.css index 2f9766dede..60d4f01c1e 100644 --- a/app/static/css/releve-but.css +++ b/app/static/css/releve-but.css @@ -98,6 +98,10 @@ section>div:nth-child(1){ /************/ /* Etudiant */ /************/ +.info_etudiant{ + color: #000; + text-decoration: none; +} .etudiant{ display: flex; align-items: center; @@ -194,6 +198,9 @@ h3{ .info{ opacity: 0.9; } +.syntheseModule{ + cursor: pointer; +} .eval, .syntheseModule{ position: relative; display: flex; diff --git a/app/static/js/releve-but.js b/app/static/js/releve-but.js index 9b974fe6fb..126cb219ea 100644 --- a/app/static/js/releve-but.js +++ b/app/static/js/releve-but.js @@ -27,6 +27,10 @@ class releveBUT extends HTMLElement { moduleOnOff(){ this.parentElement.classList.toggle("moduleOnOff"); } + goTo(){ + let module = this.dataset.module; + this.parentElement.parentElement.parentElement.parentElement.querySelector("#Module_" + module).scrollIntoView(); + } set setConfig(config){ this.config.showURL = config.showURL ?? this.config.showURL; @@ -46,6 +50,9 @@ class releveBUT extends HTMLElement { this.shadow.querySelectorAll(".ue, .module").forEach(e => { e.addEventListener("click", this.moduleOnOff) }) + this.shadow.querySelectorAll(".syntheseModule").forEach(e => { + e.addEventListener("click", this.goTo) + }) this.shadow.children[0].classList.add("ready"); } @@ -132,8 +139,15 @@ class releveBUT extends HTMLElement { showInformations(data) { this.shadow.querySelector(".studentPic").src = data.etudiant.photo_url || "default_Student.svg"; - let output = ` -
+ let output = ''; + + if(this.config.showURL){ + output += ``; + } else { + output += `
`; + } + + output += `
${this.civilite(data.etudiant.civilite)} ${data.etudiant.nom} @@ -150,8 +164,12 @@ class releveBUT extends HTMLElement { Code INE : ${data.etudiant.code_ine}
${data.formation.titre}
-
`; + if(this.config.showURL){ + output += `
`; + } else { + 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 url = data.ressources[module]?.url || data.saes[module]?.url; output += ` -
-
${this.URL(url, `${module} - ${titre}`)}
+
+
${module} - ${titre}
${dataModule.moyenne} Coef. ${dataModule.coef} @@ -249,7 +267,7 @@ class releveBUT extends HTMLElement { let output = ""; Object.entries(module).forEach(([numero, content]) => { output += ` -
+

${this.URL(content.url, `${numero} - ${content.titre}`)}

diff --git a/app/templates/but/bulletin.html b/app/templates/but/bulletin.html index 727a144d78..27146ed4a9 100644 --- a/app/templates/but/bulletin.html +++ b/app/templates/but/bulletin.html @@ -22,9 +22,10 @@ .dateInscription, .numerosEtudiant, .dateNaissance{ - display: none; + display: none; }`; releve.shadowRoot.appendChild(style); - }) + }); + document.querySelector("html").style.scrollBehavior = "smooth"; {% endblock %} \ No newline at end of file From d12db963895cf274d8b97d0b6b2e4b854199e2be Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Wed, 22 Dec 2021 14:31:44 +0100 Subject: [PATCH 2/4] typo --- app/views/scodoc.py | 2 +- sco_version.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/scodoc.py b/app/views/scodoc.py index c098f0347d..dfd8bcfe96 100644 --- a/app/views/scodoc.py +++ b/app/views/scodoc.py @@ -134,7 +134,7 @@ def get_etud_dept(): last_etud = None last_date = None 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: date_fin = FormSemestre.query.get(ins.formsemestre_id).date_fin if (last_date is None) or date_fin > last_date: diff --git a/sco_version.py b/sco_version.py index 811be2497e..e2e05e134c 100644 --- a/sco_version.py +++ b/sco_version.py @@ -1,7 +1,7 @@ # -*- mode: python -*- # -*- coding: utf-8 -*- -SCOVERSION = "9.1.13" +SCOVERSION = "9.1.14" SCONAME = "ScoDoc" From 429820b7865f4747476f089a1ef13d4f11324a62 Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Thu, 23 Dec 2021 00:18:05 +0100 Subject: [PATCH 3/4] 9.1.15 --- sco_version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sco_version.py b/sco_version.py index e2e05e134c..3de53222aa 100644 --- a/sco_version.py +++ b/sco_version.py @@ -1,7 +1,7 @@ # -*- mode: python -*- # -*- coding: utf-8 -*- -SCOVERSION = "9.1.14" +SCOVERSION = "9.1.15" SCONAME = "ScoDoc" From 2d2b2b2f39e29662acc1d3ebe3e41e1486c39ea3 Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Thu, 23 Dec 2021 16:03:30 +0100 Subject: [PATCH 4/4] =?UTF-8?q?Form=20cr=C3=A9ation=20dept=20+=20d=C3=A9pl?= =?UTF-8?q?ace=20form=20logos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/config_forms.py} | 3 +- app/forms/main/create_dept.py | 64 +++++++++++++++++++ app/models/departements.py | 12 ++++ app/templates/create_dept.html | 14 ++++ app/templates/scodoc.html | 3 + app/views/scodoc.py | 27 ++++++-- sco_version.py | 2 +- scodoc.py | 7 +- 8 files changed, 121 insertions(+), 11 deletions(-) rename app/{scodoc/sco_config_form.py => forms/main/config_forms.py} (99%) create mode 100644 app/forms/main/create_dept.py create mode 100644 app/templates/create_dept.html diff --git a/app/scodoc/sco_config_form.py b/app/forms/main/config_forms.py similarity index 99% rename from app/scodoc/sco_config_form.py rename to app/forms/main/config_forms.py index 993382de2b..609066c518 100644 --- a/app/scodoc/sco_config_form.py +++ b/app/forms/main/config_forms.py @@ -89,7 +89,8 @@ CSSSTYLES = html_sco_header.BOOTSTRAP_MULTISELECT_CSS # - only one operation found: execute and go to main page # - more than 1 operation found. asked form confirmation (and execution if confirmed) # -# Someday we'll have time to refactor as abstract classes but Abstract FieldList makes this a bit complicated +# Someday we'll have time to refactor as abstract classes but Abstract FieldList makes this +# a bit complicated # """ # Terminology: diff --git a/app/forms/main/create_dept.py b/app/forms/main/create_dept.py new file mode 100644 index 0000000000..11b361294b --- /dev/null +++ b/app/forms/main/create_dept.py @@ -0,0 +1,64 @@ +# -*- mode: python -*- +# -*- coding: utf-8 -*- + +############################################################################## +# +# ScoDoc +# +# 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 +# +############################################################################## + +""" +Formulaires création département +""" + +from flask import flash, url_for, redirect, render_template +from flask_wtf import FlaskForm +from wtforms import SelectField, SubmitField, FormField, validators, FieldList +from wtforms.fields.simple import StringField, HiddenField + +from app import AccessDenied +from app.models import Departement +from app.models import ScoPreference +from app.models import SHORT_STR_LEN +from app.scodoc import sco_utils as scu + +from flask_login import current_user + + +class CreateDeptForm(FlaskForm): + """Formulaire permettant l'ajout d'un département""" + + acronym = StringField( + label="Acronyme", + validators=[ + validators.regexp( + r"^[a-zA-Z0-9_\-]*$", + message="Ne doit comporter que lettres, chiffres ou -", + ), + validators.Length( + max=SHORT_STR_LEN, + message=f"L'acronyme ne doit pas dépasser {SHORT_STR_LEN} caractères", + ), + validators.DataRequired("acronyme du département requis"), + ], + ) + submit = SubmitField("Valider") + cancel = SubmitField("Annuler", render_kw={"formnovalidate": True}) diff --git a/app/models/departements.py b/app/models/departements.py index 95167383e7..0734e35b0d 100644 --- a/app/models/departements.py +++ b/app/models/departements.py @@ -47,3 +47,15 @@ class Departement(db.Model): def from_acronym(cls, acronym): dept = cls.query.filter_by(acronym=acronym).first_or_404() return dept + + +def create_dept(acronym: str) -> Departement: + "Create new departement" + from app.models import ScoPreference + + departement = Departement(acronym=acronym) + p1 = ScoPreference(name="DeptName", value=acronym, departement=departement) + db.session.add(p1) + db.session.add(departement) + db.session.commit() + return departement diff --git a/app/templates/create_dept.html b/app/templates/create_dept.html new file mode 100644 index 0000000000..4e3f8a4679 --- /dev/null +++ b/app/templates/create_dept.html @@ -0,0 +1,14 @@ +{% extends "base.html" %} +{% import 'bootstrap/wtf.html' as wtf %} + +{% block app_content %} +

Créer un département

+ +
+
+ {{ wtf.quick_form(form) }} +
+
+ + +{% endblock %} \ No newline at end of file diff --git a/app/templates/scodoc.html b/app/templates/scodoc.html index c0e1edddaf..2aaf9e22ca 100644 --- a/app/templates/scodoc.html +++ b/app/templates/scodoc.html @@ -22,6 +22,9 @@ Aucun département défini ! {% endfor %} + {% if current_user.is_administrator() %} +
  • créer un nouveau département
  • + {% endif %} diff --git a/app/views/scodoc.py b/app/views/scodoc.py index dfd8bcfe96..815de175d6 100644 --- a/app/views/scodoc.py +++ b/app/views/scodoc.py @@ -53,11 +53,13 @@ from wtforms.fields.simple import BooleanField, StringField, TextAreaField, Hidd from wtforms.validators import ValidationError, DataRequired, Email, EqualTo import app +from app.forms.main import config_forms +from app.forms.main.create_dept import CreateDeptForm from app.models import Departement, Identite +from app.models import departements from app.models import FormSemestre, FormSemestreInscription -from app.models import ScoDocSiteConfig import sco_version -from app.scodoc import sco_logos, sco_config_form +from app.scodoc import sco_logos from app.scodoc import sco_find_etud from app.scodoc import sco_utils as scu from app.decorators import ( @@ -67,7 +69,6 @@ from app.decorators import ( permission_required_compat_scodoc7, permission_required, ) -from app.scodoc.sco_config_form import configuration from app.scodoc.sco_exceptions import AccessDenied from app.scodoc.sco_logos import find_logo from app.scodoc.sco_permissions import Permission @@ -99,6 +100,24 @@ def index_dept(scodoc_dept): return redirect(url_for("scolar.index_html", scodoc_dept=scodoc_dept)) +@bp.route("/ScoDoc/create_dept", methods=["GET", "POST"]) +@admin_required +def create_dept(): + """Form création département""" + form = CreateDeptForm() + if request.method == "POST" and form.cancel.data: # cancel button + return redirect(url_for("scodoc.index")) + if form.validate_on_submit(): + departements.create_dept(form.acronym.data) + flash(f"Département {form.acronym.data} créé.") + return redirect(url_for("scodoc.index")) + return render_template( + "create_dept.html", + form=form, + title="Création d'un nouveau département", + ) + + @bp.route("/ScoDoc/table_etud_in_accessible_depts", methods=["POST"]) @login_required def table_etud_in_accessible_depts(): @@ -207,7 +226,7 @@ def configuration(): auth_name = str(current_user) if not current_user.is_administrator(): raise AccessDenied("invalid user (%s) must be SuperAdmin" % auth_name) - return sco_config_form.configuration() + return config_forms.configuration() SMALL_SIZE = (200, 200) diff --git a/sco_version.py b/sco_version.py index 3de53222aa..bc906576bb 100644 --- a/sco_version.py +++ b/sco_version.py @@ -1,7 +1,7 @@ # -*- mode: python -*- # -*- coding: utf-8 -*- -SCOVERSION = "9.1.15" +SCOVERSION = "9.1.16" SCONAME = "ScoDoc" diff --git a/scodoc.py b/scodoc.py index 482501e0eb..94c8a7f09c 100755 --- a/scodoc.py +++ b/scodoc.py @@ -27,6 +27,7 @@ from app.models import Formation, UniteEns, Module from app.models import FormSemestre, FormSemestreInscription from app.models import ModuleImpl, ModuleImplInscription from app.models import Identite +from app.models import departements from app.models.evaluations import Evaluation from app.scodoc.sco_etud import identite_create from app.scodoc.sco_permissions import Permission @@ -306,11 +307,7 @@ def delete_dept(dept): # delete-dept @click.argument("dept") def create_dept(dept): # create-dept "Create new departement" - d = models.Departement(acronym=dept) - p1 = ScoPreference(name="DeptName", value=dept, departement=d) - db.session.add(p1) - db.session.add(d) - db.session.commit() + _ = departements.create_dept(dept) return 0