Update opolka/ScoDoc from ScoDoc/ScoDoc #2

Merged
opolka merged 1272 commits from ScoDoc/ScoDoc:master into master 2024-05-27 09:11:04 +02:00
5 changed files with 139 additions and 76 deletions
Showing only changes of commit bae46c2794 - Show all commits

View File

@ -208,7 +208,7 @@ class FormSemestre(models.ScoDocModel):
return cls.query.filter_by(id=formsemestre_id).first_or_404()
def sort_key(self) -> tuple:
"""clé pour tris par ordre alphabétique
"""clé pour tris par ordre de date_debut, le plus ancien en tête
(pour avoir le plus récent d'abord, sort avec reverse=True)"""
return (self.date_debut, self.semestre_id)

View File

@ -79,21 +79,30 @@ def index_html(showcodes=0, showsemtable=0, export_table_formsemestres=False):
else:
html_table_formsemestres = None
current_formsemestres_by_modalite, modalites = (
sco_modalites.group_formsemestres_by_modalite(current_formsemestres)
)
return render_template(
"scolar/index.j2",
current_user=current_user,
current_formsemestres=current_formsemestres,
current_formsemestres_by_modalite=current_formsemestres_by_modalite,
dept_name=sco_preferences.get_preference("DeptName"),
formsemestres=formsemestres,
html_current_formsemestres=_show_current_formsemestres(
current_formsemestres, showcodes
emptygroupicon=scu.icontag(
"emptygroupicon_img", title="Pas d'inscrits", border="0"
),
formsemestres=formsemestres,
groupicon=scu.icontag("groupicon_img", title="Inscrits", border="0"),
html_table_formsemestres=html_table_formsemestres,
locked_formsemestres=locked_formsemestres,
modalites=modalites,
nb_locked=locked_formsemestres.count(),
nb_user_accounts=sco_users.get_users_count(dept=g.scodoc_dept),
page_title=f"ScoDoc {g.scodoc_dept}",
Permission=Permission,
scolar_news_summary=ScolarNews.scolar_news_summary_html(),
showcodes=showcodes,
showsemtable=showsemtable,
sco=ScoData(),
)
@ -116,6 +125,7 @@ def _convert_formsemestres_to_dicts(
lockicon = "X"
# génère liste de dict
sems = []
formsemestre: FormSemestre
for formsemestre in formsemestres:
nb_inscrits = len(formsemestre.inscriptions)
formation = formsemestre.formation
@ -151,61 +161,6 @@ def _convert_formsemestres_to_dicts(
return sems
def _show_current_formsemestres(formsemestres: Query, showcodes: bool) -> str:
"""html div avec les formsemestres courants de la page d'accueil"""
H = []
if formsemestres.count():
H.append("""<div class="scobox-title">Sessions en cours</div>""")
H.append(_sem_table(_convert_formsemestres_to_dicts(formsemestres, showcodes)))
else:
# aucun semestre courant: affiche aide
H.append(
"""
<div class="scobox-title">Aucune session en cours !</div>
<p>Pour ajouter une session, aller dans <a href="Notes" id="link-programmes">Formations</a>,
choisissez une formation, puis suivez le lien "<em>UE, modules, semestres</em>".
</p>
<p>, en bas de page, suivez le lien
"<em>Mettre en place un nouveau semestre de formation...</em>"
</p>"""
)
return "\n".join(H)
def _sem_table(sems: list[dict]) -> str:
"""Affiche liste des semestres, utilisée pour semestres en cours"""
tmpl = f"""<tr class="%(trclass)s">%(tmpcode)s
<td class="semicon">%(lockimg)s <a href="{
url_for("notes.formsemestre_status", scodoc_dept=g.scodoc_dept)}?formsemestre_id=%(formsemestre_id)s#groupes">%(groupicon)s</a></td>
<td class="datesem">%(mois_debut)s <a title="%(session_id)s">-</a> %(mois_fin)s</td>
<td class="titresem"><a class="stdlink" href="{url_for("notes.formsemestre_status", scodoc_dept=g.scodoc_dept)}?formsemestre_id=%(formsemestre_id)s">%(titre_num)s</a>
<span class="respsem">(%(responsable_name)s)</span>
</td>
</tr>
"""
# Liste des semestres, groupés par modalités
sems_by_mod, modalites = sco_modalites.group_sems_by_modalite(sems)
H = ['<table class="listesems">']
for modalite in modalites:
if len(modalites) > 1:
H.append('<tr><th colspan="3">%s</th></tr>' % modalite["titre"])
if sems_by_mod[modalite["modalite"]]:
cur_idx = sems_by_mod[modalite["modalite"]][0]["semestre_id"]
for sem in sems_by_mod[modalite["modalite"]]:
if cur_idx != sem["semestre_id"]:
sem["trclass"] = "firstsem" # separe les groupes de semestres
cur_idx = sem["semestre_id"]
else:
sem["trclass"] = ""
H.append(tmpl % sem)
H.append("</table>")
return "\n".join(H)
def _sem_table_gt(formsemestres: Query, showcodes=False, fmt="html") -> GenTable:
"""Table des semestres
Utilise une datatables.

View File

@ -36,37 +36,45 @@ Elle n'est pas utilisée pour les parcours, ni pour rien d'autre
import collections
import app.scodoc.notesdb as ndb
from app import log
from app.models import FormSemestre
def list_formsemestres_modalites(sems):
def list_formsemestres_modalites(formsemestres: list[FormSemestre]) -> list[dict]:
"""Liste ordonnée des modalités présentes dans ces formsemestres"""
modalites = {}
for sem in sems:
if sem["modalite"] not in modalites:
m = do_modalite_list(args={"modalite": sem["modalite"]})[0]
for formsemestre in formsemestres:
if formsemestre.modalite not in modalites:
m = do_modalite_list(args={"modalite": formsemestre.modalite})[0]
modalites[m["modalite"]] = m
modalites = list(modalites.values())
modalites.sort(key=lambda x: x["numero"])
return modalites
def group_sems_by_modalite(sems: list[dict]):
def group_formsemestres_by_modalite(
formsemestres: list[FormSemestre],
) -> dict[str, list[FormSemestre]]:
"""Given the list of formsemestre, group them by modalite,
sorted in each one by semestre id and date
"""
sems_by_mod = collections.defaultdict(list)
modalites = list_formsemestres_modalites(sems)
for modalite in modalites:
for sem in sems:
if sem["semestre_id"] < 0: # formations en un semestre
sem["sortkey"] = (-100 * sem["semestre_id"], sem["dateord"])
else:
sem["sortkey"] = (sem["semestre_id"], sem["dateord"])
if sem["modalite"] == modalite["modalite"]:
sems_by_mod[modalite["modalite"]].append(sem)
modalites = list_formsemestres_modalites(formsemestres)
sems_by_mod = {
modalite["modalite"]: [
formsemestre
for formsemestre in formsemestres
if formsemestre.modalite == modalite["modalite"]
]
for modalite in modalites
}
# tri dans chaque modalité par indice de semestre et date debut
for modalite in modalites:
sems_by_mod[modalite["modalite"]].sort(key=lambda x: x["sortkey"])
sems_by_mod[modalite["modalite"]].sort(
key=lambda x: (
x.semestre_id if x.semestre_id > 0 else -1000 * x.semestre_id,
x.date_debut,
)
)
return sems_by_mod, modalites

View File

@ -83,6 +83,70 @@ table.semlist tbody tr td.modalite {
padding-right: 1em;
}
div.modalite {
font-size: 16px;
font-weight: bold;
}
span.effectif {
display: inline-block;
min-width: 24px;
text-align: right;
}
.cur-formsemestres {
width: max-content; /* Fits content, but respects max-width */
max-width: 1024px; /* Maximum width */
margin: 0 auto 0 0; /* Centers divs if they are narrower than 1024px */
}
.cur-formsemestre {
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 1px solid #ddd;
border-left: 1px solid #ddd;
border-right: 1px solid #ddd;;
background-color: rgb(246, 255, 254);
padding: 0px 8px 0px 8px;
margin: 0px;
}
.cur-formsemestre.new-sem {
margin-top: 8px;
border-top: 1px solid #ddd;;
}
.left-section {
display: flex;
align-items: center;
}
.date {
display: flex;
flex-direction: column;
margin-left: 10px;
font-size: 12px;
}
.cur-formsemestre .title {
flex-grow: 1;
text-align: left;
margin: 0 20px;
display: flex;
align-items: center;
font-size: 16px;
}
.right-section {
display: flex;
flex-direction: column;
font-size: 14px;
}
.responsable {
font-weight: bold;
color: navy;
}
</style>
{# News #}
@ -103,7 +167,43 @@ table.semlist tbody tr td.modalite {
{# Les semestres courants (cad non verrouillés) #}
<div class="scobox">
{{html_current_formsemestres|safe}}
{% if current_formsemestres.count() == 0 %}
<div class="scobox-title">Aucune session en cours !</div>
<p>Pour ajouter une session, aller dans <a href="Notes" id="link-programmes">Formations</a>,
choisissez une formation, puis suivez le lien "<em>UE, modules, semestres</em>".
</p>
<p>Là, en bas de page, suivez le lien
"<em>Mettre en place un nouveau semestre de formation...</em>"
</p>
{% else %}
<div class="scobox-title">Sessions en cours</div>
<div class="cur-formsemestres">
{% for modalite in modalites %}
{% if modalites|length > 1 %}
<div class="modalite">{{modalite.titre}}</div>
{% endif %}
{% for formsemestre in current_formsemestres_by_modalite[modalite.modalite] %}
<div class="cur-formsemestre {{'new-sem' if loop.first or formsemestre.semestre_id != loop.previtem.semestre_id}}">
<div class="left-section">
{{groupicon|safe if formsemestre.inscriptions|length else emptygroupicon|safe}}
<div class="date">
<div class="date-begin"><a title="{{formsemestre.session_id()}}">{{formsemestre.mois_debut()}}</a></div>
<div class="date-end">{{formsemestre.mois_fin()}}</div>
</div>
</div>
<div class="title">
<a class="stdlink" href="{{ url_for("notes.formsemestre_status",
scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre.id)}}">{{formsemestre.titre_num()}}</a>
</div>
<div class="right-section">
<div class="responsable">{{formsemestre.responsables_str()}}</div>
<div class="effectif">{{formsemestre.inscriptions|length}} étuds</div>
</div>
</div>
{% endfor %}
{% endfor %}
</div>
{% endif %}
</div>
{# Table de tous les semestres #}

View File

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