Nouvelle table recap avec malus.

This commit is contained in:
Emmanuel Viennet 2023-02-02 14:27:15 -03:00
parent b3839dd8fb
commit 79c4a23ab9
6 changed files with 80 additions and 38 deletions

View File

@ -17,8 +17,9 @@ from app.comp.bonus_spo import BonusSport
from app.models import ScoDocSiteConfig
from app.models.moduleimpls import ModuleImpl
from app.models.ues import DispenseUE, UniteEns
from app.scodoc.sco_codes_parcours import UE_SPORT
from app.scodoc import sco_preferences
from app.scodoc.sco_codes_parcours import UE_SPORT
from app.scodoc.sco_utils import ModuleType
class ResultatsSemestreBUT(NotesTableCompat):
@ -185,9 +186,15 @@ class ResultatsSemestreBUT(NotesTableCompat):
modimpls = [
modimpl
for modimpl in self.formsemestre.modimpls_sorted
if modimpl.module.ue.type != UE_SPORT
and (coefs[modimpl.id][ue.id] != 0)
and self.modimpl_inscr_df[modimpl.id][etudid]
if (
modimpl.module.ue.type != UE_SPORT
and (coefs[modimpl.id][ue.id] != 0)
and self.modimpl_inscr_df[modimpl.id][etudid]
)
or (
modimpl.module.module_type == ModuleType.MALUS
and modimpl.module.ue_id == ue.id
)
]
if not with_bonus:
return [

View File

@ -667,7 +667,7 @@ class ResultatsSemestre(ResultatsCache):
"ues_validables",
"UEs",
ue_valid_txt_html,
"col_ues_validables",
group="col_ues_validables",
classes=classes,
raw_content=ue_valid_txt,
data={"order": row.nb_ues_validables}, # tri
@ -719,7 +719,7 @@ class ResultatsSemestre(ResultatsCache):
ue.acronyme,
table.fmt_note(val),
group=f"col_ue_{ue.id}",
classes=["col_ue", note_class],
classes=["col_ue", "col_moy_ue", note_class],
)
row.table.foot_title_row.cells[col_id].target_attrs[
"title"
@ -751,7 +751,11 @@ class ResultatsSemestre(ResultatsCache):
col_id = f"moy_{modimpl.module.type_abbrv()}_{modimpl.id}_{ue.id}"
val_fmt = val_fmt_html = table.fmt_note(val)
if modimpl.module.module_type == scu.ModuleType.MALUS:
val_fmt_html = (scu.EMO_RED_TRIANGLE_DOWN + val_fmt) if val else ""
val_fmt_html = (
(scu.EMO_RED_TRIANGLE_DOWN + val_fmt)
if val and not np.isnan(val)
else ""
)
cell = row.add_cell(
col_id,
modimpl.module.code,
@ -992,22 +996,7 @@ class ResultatsSemestre(ResultatsCache):
)
first_partition = True
for partition in partitions:
col_classes = [] # la classe "partition" sera ajoutée par la table
if not first_partition:
col_classes.append("partition_aux")
first_partition = False
cid = f"part_{partition['partition_id']}"
cell_head, cell_foot = table.add_title(cid, partition["partition_name"])
cell_head.classes += col_classes
cell_foot.classes += col_classes
if partition["bul_show_rank"]:
rg_cid = cid + "_rg" # rang dans la partition
cell_head, cell_foot = table.add_title(
cid, f"Rg {partition['partition_name']}"
)
cell_head.classes.append("partition_rangs")
cell_foot.classes.append("partition_rangs")
partition_etud_groups = partitions_etud_groups[partition["partition_id"]]
for row in table.rows:
@ -1030,9 +1019,12 @@ class ResultatsSemestre(ResultatsCache):
cid,
partition["partition_name"],
gr_name,
"partition",
classes=col_classes,
group="partition",
classes=[] if first_partition else ["partition_aux"],
# la classe "partition" est ajoutée par la Table car c'est le group
# la classe "partition_aux" est ajoutée à partir de la 2eme partition affichée
)
first_partition = False
# Rangs dans groupe
if (
@ -1041,7 +1033,14 @@ class ResultatsSemestre(ResultatsCache):
and (group["id"] in self.moy_gen_rangs_by_group)
):
rang = self.moy_gen_rangs_by_group[group["id"]][0]
row.add_cell(rg_cid, None, rang.get(etudid, ""), "partition")
rg_cid = cid + "_rg" # rang dans la partition
row.add_cell(
rg_cid,
f"Rg {partition['partition_name']}",
rang.get(etudid, ""),
group="partition",
classes=["partition_aux"],
)
def _recap_add_evaluations(self, table: tb.Table):
"""Ajoute les colonnes avec les notes aux évaluations

View File

@ -4,8 +4,6 @@
"""
from app import db
import app.scodoc.notesdb as ndb
import app.scodoc.sco_utils as scu
@ -53,6 +51,13 @@ class NotesNotes(db.Model):
d.pop("_sa_instance_state", None)
return d
def __repr__(self):
"pour debug"
from app.models.evaluations import Evaluation
return f"""<{self.__class__.__name__} {self.id} v={self.value} {self.date.isoformat()
} {Evaluation.query.get(self.evaluation_id) if self.evaluation_id else "X" }>"""
class NotesNotesLog(db.Model):
"""Historique des modifs sur notes (anciennes entrees de notes_notes)"""

View File

@ -1223,6 +1223,7 @@ def partition_move(partition_id, after=0, redirect=1):
partition["numero"], neigh["numero"] = neigh["numero"], partition["numero"]
partitionEditor.edit(cnx, partition)
partitionEditor.edit(cnx, neigh)
sco_cache.invalidate_formsemestre(formsemestre_id=formsemestre_id)
# redirect to partition edit page:
if redirect:
@ -1297,7 +1298,7 @@ def partition_set_name(partition_id, partition_name, redirect=1):
)
if len(r) > 1 or (len(r) == 1 and r[0]["id"] != partition_id):
raise ScoValueError(
"Partition %s déjà existante dans ce semestre !" % partition_name
f"Partition {partition_name} déjà existante dans ce semestre !"
)
if not sco_permissions_check.can_change_groups(formsemestre_id):
@ -1307,6 +1308,7 @@ def partition_set_name(partition_id, partition_name, redirect=1):
partitionEditor.edit(
cnx, {"partition_id": partition_id, "partition_name": partition_name}
)
sco_cache.invalidate_formsemestre(formsemestre_id=formsemestre_id)
# redirect to partition edit page:
if redirect:
@ -1339,6 +1341,7 @@ def group_set_name(group: GroupDescr, group_name: str, redirect=True):
group.group_name = group_name
db.session.add(group)
db.session.commit()
sco_cache.invalidate_formsemestre(formsemestre_id=group.partition.formsemestre_id)
# redirect to partition edit page:
if redirect:
@ -1396,8 +1399,6 @@ def groups_auto_repartition(partition_id=None):
"""Reparti les etudiants dans des groupes dans une partition, en respectant le niveau
et la mixité.
"""
from app.scodoc import sco_formsemestre
partition = get_partition(partition_id)
if not partition["groups_editable"]:
raise AccessDenied("Partition non éditable")

View File

@ -227,7 +227,11 @@ class Table(Element):
if col_id not in self.titles:
self.titles[col_id] = title
self.head_title_row.cells[col_id] = self.head_title_row.add_cell(
col_id, None, title, classes=classes
col_id,
None,
title,
classes=classes,
group=self.column_group.get(col_id),
)
self.foot_title_row.cells[col_id] = self.foot_title_row.add_cell(
col_id, None, title, classes=classes
@ -276,9 +280,14 @@ class Row(Element):
group: groupe de colonnes
classes is a list of css class names
"""
if (classes is None) or (group not in classes):
# ajoute le nom de groupe aux classes
classes = [group or ""] + (classes or [])
else:
classes = classes.copy()
cell = Cell(
content,
(classes or []) + [group or ""], # ajoute le nom de groupe aux classes
classes,
elt=elt or self.cell_elt,
attrs=attrs,
data=data,
@ -294,7 +303,7 @@ class Row(Element):
"""Add a cell to the row.
Si title est None, il doit avoir été ajouté avec table.add_title().
"""
cell.data["group"] = column_group
cell.data["group"] = column_group or ""
self.cells[col_id] = cell
if col_id not in self.table.column_ids:
self.table.column_ids.append(col_id)
@ -375,7 +384,7 @@ class Cell(Element):
if self.elt == "th":
self.attrs["scope"] = "row"
self.data = data or {}
self.data = data.copy() if data else {}
self.raw_content = raw_content or content
self.target = target
self.target_attrs = target_attrs or {}

View File

@ -1,7 +1,11 @@
// Tableau recap notes
$(function () {
$(function () {
let hidden_colums = ["etud_codes", "identite_detail", "partition_aux", "partition_rangs", "admission", "col_empty"];
let hidden_colums = [
"etud_codes", "identite_detail",
"partition_aux", "partition_rangs", "admission",
"col_empty"
];
let mode_jury_but_bilan = $('table.table_recap').hasClass("table_jury_but_bilan");
if (mode_jury_but_bilan) {
// table bilan décisions: cache les notes
@ -30,6 +34,7 @@ $(function () {
// Les colonnes visibles étant mémorisé, il faut initialiser les titres des boutons
function update_buttons_labels(dt) {
console.log("update_buttons_labels");
dt.buttons('toggle_ident:name').text(dt.columns(".identite_detail").visible()[0] ? "Nom seul" : "Civ/Nom/Prénom");
dt.buttons('toggle_partitions:name').text(dt.columns(".partition_aux").visible()[0] ? "Cacher les groupes" : "Montrer groupes");
if (!$('table.table_recap').hasClass("table_jury_but")) {
@ -106,7 +111,7 @@ $(function () {
$('table.table_recap').hasClass("apc") ?
{
name: "toggle_res",
text: "Visilité ressources",
text: "Visibilité ressources",
action: function (e, dt, node, config) {
let visible = dt.columns(".col_res").visible()[0];
dt.columns(".col_res").visible(!visible);
@ -159,6 +164,14 @@ $(function () {
}
});
}
buttons.push({
name: "reset_table_display",
text: "Rétablir affichage par défaut",
action: function (e, dt, node, config) {
localStorage.clear();
location.reload();
}
});
try {
let table = $('table.table_recap').DataTable(
{
@ -182,7 +195,7 @@ $(function () {
},
{
// Elimine les 0 à gauche pour les exports excel et les "copy"
targets: ["col_mod", "col_moy_gen", "col_ue", "col_res", "col_sae", "evaluation", "col_rcue"],
targets: ["col_mod", "col_moy_gen", "col_moy_ue", "col_res", "col_sae", "evaluation", "col_rcue"],
render: function (data, type, row) {
return type === 'export' ? data.replace(/0(\d\..*)/, '$1') : data;
}
@ -194,6 +207,14 @@ $(function () {
return type === 'export' ? data.replace(/.*(\d\d\.\d\d)/, '$1').replace(/0(\d\..*)/, '$1') : data;
}
},
{
// Elimine emoji warning sur UEs
targets: ["col_ues_validables"],
render: function (data, type, row) {
return type === 'export' ? data.replace(/(\d+\/\d+).*/, '$1') : data;
}
}
],
dom: 'Bfrtip',
buttons: [
@ -235,6 +256,7 @@ $(function () {
"order": order_info,
}
);
update_buttons_labels(table);
} catch (error) {
// l'erreur peut etre causee par un ancien storage:
localStorage.removeItem(etudids_key);
@ -242,7 +264,6 @@ $(function () {
localStorage.removeItem(order_info_key);
location.reload();
}
update_buttons_labels(table);
});
$('table.table_recap tbody').on('click', 'tr', function () {
if ($(this).hasClass('selected')) {