1
0
forked from ScoDoc/ScoDoc

recap_complet avec DataTables. + closes #295

This commit is contained in:
Emmanuel Viennet 2022-03-23 22:30:22 +01:00
parent 72a91f645f
commit 9497c20a9d
6 changed files with 86 additions and 58 deletions

View File

@ -105,7 +105,6 @@ _HTML_BEGIN = """<!DOCTYPE html>
<link href="/ScoDoc/static/css/scodoc.css" rel="stylesheet" type="text/css" />
<link href="/ScoDoc/static/css/menu.css" rel="stylesheet" type="text/css" />
<script src="/ScoDoc/static/libjs/menu.js"></script>
<script src="/ScoDoc/static/libjs/sorttable.js"></script>
<script src="/ScoDoc/static/libjs/bubble.js"></script>
<script>
window.onload=function(){enableTooltips("gtrcontent")};

View File

@ -340,12 +340,17 @@ def _make_table_notes(
"_code_td_attrs": 'style="padding-left: 1em; padding-right: 2em;"',
"etudid": etudid,
"nom": etud["nom"].upper(),
"_nomprenom_target": "formsemestre_bulletinetud?formsemestre_id=%s&etudid=%s"
% (modimpl_o["formsemestre_id"], etudid),
"_nomprenom_td_attrs": 'id="%s" class="etudinfo"' % (etud["etudid"]),
"_nomprenom_target": url_for(
"notes.formsemestre_bulletinetud",
scodoc_dept=g.scodoc_dept,
formsemestre_id=modimpl_o["formsemestre_id"],
etudid=etudid,
),
"_nomprenom_td_attrs": f"""id="{etudid}" class="etudinfo" data-sort="{etud.get('nom', '').upper()}" """,
"prenom": etud["prenom"].lower().capitalize(),
"nomprenom": etud["nomprenom"],
"group": grc,
"_group_td_attrs": 'class="group"',
"email": etud["email"],
"emailperso": etud["emailperso"],
"_css_row_class": css_row_class or "",
@ -574,7 +579,7 @@ def _make_table_notes(
page_title="Notes de " + sem["titremois"],
html_title=html_title,
pdf_title=pdf_title,
html_class="table_leftalign notes_evaluation",
html_class="notes_evaluation",
preferences=sco_preferences.SemPreferences(modimpl_o["formsemestre_id"]),
# html_generate_cells=False # la derniere ligne (moyennes) est incomplete
)

View File

@ -32,8 +32,8 @@ import json
import time
from xml.etree import ElementTree
from flask import request
from flask import make_response
from flask import g, request
from flask import make_response, url_for
from app import log
from app.but import bulletin_but
@ -108,7 +108,7 @@ def formsemestre_recapcomplet(
page_title="Récapitulatif",
no_side_bar=True,
init_qtip=True,
javascripts=["libjs/sorttable.js", "js/etud_info.js"],
javascripts=["js/etud_info.js"],
),
sco_formsemestre_status.formsemestre_status_head(
formsemestre_id=formsemestre_id
@ -600,59 +600,25 @@ def make_formsemestre_recapcomplet(
document.location=loc;
}
</script>
<table class="notes_recapcomplet sortable" id="recapcomplet">
<table class="notes_recapcomplet gt_table_searchable" id="recapcomplet">
"""
]
if sortcol: # sort table using JS sorttable
H.append(
"""<script type="text/javascript">
function resort_recap() {
var clid = %d;
// element <a place par sorttable (ligne de titre)
lnk = document.getElementById("recap_trtit").childNodes[clid].childNodes[0];
ts_resortTable(lnk,clid);
// Scroll window:
eid = document.location.hash;
if (eid) {
var eid = eid.substring(1); // remove #
var e = document.getElementById(eid);
if (e) {
var y = e.offsetTop + e.offsetParent.offsetTop;
window.scrollTo(0,y);
}
}
}
addEvent(window, "load", resort_recap);
</script>
"""
% (int(sortcol))
)
cells = '<tr class="recap_row_tit sortbottom" id="recap_trtit">'
for i in range(len(F[0]) - 2):
if i in ue_index:
cls = "recap_tit_ue"
else:
cls = "recap_tit"
if (
i == 0 or F[0][i] == "classement"
): # Rang: force tri numerique pour sortable
cls = cls + " sortnumeric"
if F[0][i] in cod2mod: # lien vers etat module
modimpl = cod2mod[F[0][i]]
cells += '<td class="%s"><a href="moduleimpl_status?moduleimpl_id=%s" title="%s (%s)">%s</a></td>' % (
cls,
modimpl.id,
modimpl.module.titre,
sco_users.user_info(modimpl.responsable_id)["nomcomplet"],
F[0][i],
)
else:
cells += '<td class="%s">%s</td>' % (cls, F[0][i])
if modejury:
cells += '<td class="recap_tit">Décision</td>'
ligne_titres = cells + "</tr>"
H.append(ligne_titres) # titres
ligne_titres_head = _ligne_titres(
ue_index, F, cod2mod, modejury, with_modules_links=False
)
ligne_titres_foot = _ligne_titres(
ue_index, F, cod2mod, modejury, with_modules_links=True
)
H.append("<thead>\n" + ligne_titres_head + "\n</thead>\n<tbody>\n")
if disable_etudlink:
etudlink = "%(name)s"
else:
@ -663,6 +629,9 @@ def make_formsemestre_recapcomplet(
nblines = len(F) - 1
for l in F[1:]:
etudid = l[-1]
if ir == nblines - 6:
H.append("</tbody>")
H.append("<tfoot>")
if ir >= nblines - 6:
# dernieres lignes:
el = l[1]
@ -692,7 +661,13 @@ def make_formsemestre_recapcomplet(
for i in range(len(nsn)):
if nsn[i] == "NA":
nsn[i] = "-"
cells += '<td class="recap_col">%s</td>' % nsn[0] # rang
try:
order = int(nsn[0].split()[0])
except:
order = 99999
cells += (
f'<td class="recap_col" data-order="{order:05d}">{nsn[0]}</td>' # rang
)
cells += '<td class="recap_col">%s</td>' % el # nom etud (lien)
if not hidebac:
cells += '<td class="recap_col_bac">%s</td>' % nsn[2] # bac
@ -760,7 +735,8 @@ def make_formsemestre_recapcomplet(
cells += "</td>"
H.append(cells + "</tr>")
H.append(ligne_titres)
H.append(ligne_titres_foot)
H.append("</tfoot>")
H.append("</table>")
# Form pour choisir partition de classement:
@ -828,6 +804,40 @@ def make_formsemestre_recapcomplet(
raise ValueError("unknown format %s" % format)
def _ligne_titres(ue_index, F, cod2mod, modejury, with_modules_links=True):
"""Cellules de la ligne de titre (haut ou bas)"""
cells = '<tr class="recap_row_tit sortbottom" id="recap_trtit">'
for i in range(len(F[0]) - 2):
if i in ue_index:
cls = "recap_tit_ue"
else:
cls = "recap_tit"
attr = f'class="{cls}"'
if i == 0 or F[0][i] == "classement": # Rang: force tri numerique
try:
order = int(F[0][i].split()[0])
except:
order = 99999
attr += f' data-order="{order:05d}"'
if F[0][i] in cod2mod: # lien vers etat module
modimpl = cod2mod[F[0][i]]
if with_modules_links:
href = url_for(
"notes.moduleimpl_status",
scodoc_dept=g.scodoc_dept,
moduleimpl_id=modimpl.id,
)
else:
href = ""
cells += f"""<td {attr}><a href="{href}" title="{modimpl.module.titre} ({
sco_users.user_info(modimpl.responsable_id)["nomcomplet"]})">{F[0][i]}</a></td>"""
else:
cells += f"<td {attr}>{F[0][i]}</td>"
if modejury:
cells += '<td class="recap_tit">Décision</td>'
return cells + "</tr>"
def _list_notes_evals(evals: list[Evaluation], etudid: int) -> list[str]:
"""Liste des notes des evaluations completes de ce module
(pour table xls avec evals)

View File

@ -225,7 +225,8 @@ def formsemestre_list_saisies_notes(formsemestre_id, format="html"):
columns_ids=columns_ids,
rows=r,
html_title="<h2>Saisies de notes dans %s</h2>" % sem["titreannee"],
html_class="table_leftalign table_coldate",
html_class="table_leftalign table_coldate gt_table_searchable",
html_class_ignore_default=True,
html_sortable=True,
caption="Saisies de notes dans %s" % sem["titreannee"],
preferences=sco_preferences.SemPreferences(formsemestre_id),

View File

@ -3226,4 +3226,15 @@ span.ext_sem_moy {
font-weight: bold;
color: rgb(122, 40, 2);
font-size: 120%;
}
/* DataTables */
table.dataTable tr.odd td {
background-color: #ecf5f4;
}
table.dataTable tr.gt_lastrow th {
text-align: right;
}
table.dataTable td.etudinfo, table.dataTable td.group {
text-align: left;
}

View File

@ -67,7 +67,6 @@ $(function () {
}
});
// Affiche un message transitoire
function sco_message(msg, color) {
if (color === undefined) {
@ -106,7 +105,7 @@ function get_query_args() {
// Tables (gen_tables)
$(function () {
$('table.gt_table').DataTable({
var table_options = {
"paging": false,
"searching": false,
"info": false,
@ -117,7 +116,10 @@ $(function () {
},
"orderCellsTop": true, // cellules ligne 1 pour tri
"aaSorting": [], // Prevent initial sorting
});
};
$('table.gt_table').DataTable(table_options);
table_options["searching"] = true;
$('table.gt_table_searchable').DataTable(table_options);
});