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/scodoc.css" rel="stylesheet" type="text/css" />
<link href="/ScoDoc/static/css/menu.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/menu.js"></script>
<script src="/ScoDoc/static/libjs/sorttable.js"></script>
<script src="/ScoDoc/static/libjs/bubble.js"></script> <script src="/ScoDoc/static/libjs/bubble.js"></script>
<script> <script>
window.onload=function(){enableTooltips("gtrcontent")}; 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;"', "_code_td_attrs": 'style="padding-left: 1em; padding-right: 2em;"',
"etudid": etudid, "etudid": etudid,
"nom": etud["nom"].upper(), "nom": etud["nom"].upper(),
"_nomprenom_target": "formsemestre_bulletinetud?formsemestre_id=%s&etudid=%s" "_nomprenom_target": url_for(
% (modimpl_o["formsemestre_id"], etudid), "notes.formsemestre_bulletinetud",
"_nomprenom_td_attrs": 'id="%s" class="etudinfo"' % (etud["etudid"]), 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(), "prenom": etud["prenom"].lower().capitalize(),
"nomprenom": etud["nomprenom"], "nomprenom": etud["nomprenom"],
"group": grc, "group": grc,
"_group_td_attrs": 'class="group"',
"email": etud["email"], "email": etud["email"],
"emailperso": etud["emailperso"], "emailperso": etud["emailperso"],
"_css_row_class": css_row_class or "", "_css_row_class": css_row_class or "",
@ -574,7 +579,7 @@ def _make_table_notes(
page_title="Notes de " + sem["titremois"], page_title="Notes de " + sem["titremois"],
html_title=html_title, html_title=html_title,
pdf_title=pdf_title, pdf_title=pdf_title,
html_class="table_leftalign notes_evaluation", html_class="notes_evaluation",
preferences=sco_preferences.SemPreferences(modimpl_o["formsemestre_id"]), preferences=sco_preferences.SemPreferences(modimpl_o["formsemestre_id"]),
# html_generate_cells=False # la derniere ligne (moyennes) est incomplete # html_generate_cells=False # la derniere ligne (moyennes) est incomplete
) )

View File

@ -32,8 +32,8 @@ import json
import time import time
from xml.etree import ElementTree from xml.etree import ElementTree
from flask import request from flask import g, request
from flask import make_response from flask import make_response, url_for
from app import log from app import log
from app.but import bulletin_but from app.but import bulletin_but
@ -108,7 +108,7 @@ def formsemestre_recapcomplet(
page_title="Récapitulatif", page_title="Récapitulatif",
no_side_bar=True, no_side_bar=True,
init_qtip=True, init_qtip=True,
javascripts=["libjs/sorttable.js", "js/etud_info.js"], javascripts=["js/etud_info.js"],
), ),
sco_formsemestre_status.formsemestre_status_head( sco_formsemestre_status.formsemestre_status_head(
formsemestre_id=formsemestre_id formsemestre_id=formsemestre_id
@ -600,59 +600,25 @@ def make_formsemestre_recapcomplet(
document.location=loc; document.location=loc;
} }
</script> </script>
<table class="notes_recapcomplet sortable" id="recapcomplet"> <table class="notes_recapcomplet gt_table_searchable" id="recapcomplet">
""" """
] ]
if sortcol: # sort table using JS sorttable if sortcol: # sort table using JS sorttable
H.append( H.append(
"""<script type="text/javascript"> """<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> </script>
""" """
% (int(sortcol)) % (int(sortcol))
) )
cells = '<tr class="recap_row_tit sortbottom" id="recap_trtit">'
for i in range(len(F[0]) - 2): ligne_titres_head = _ligne_titres(
if i in ue_index: ue_index, F, cod2mod, modejury, with_modules_links=False
cls = "recap_tit_ue" )
else: ligne_titres_foot = _ligne_titres(
cls = "recap_tit" ue_index, F, cod2mod, modejury, with_modules_links=True
if ( )
i == 0 or F[0][i] == "classement"
): # Rang: force tri numerique pour sortable H.append("<thead>\n" + ligne_titres_head + "\n</thead>\n<tbody>\n")
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
if disable_etudlink: if disable_etudlink:
etudlink = "%(name)s" etudlink = "%(name)s"
else: else:
@ -663,6 +629,9 @@ def make_formsemestre_recapcomplet(
nblines = len(F) - 1 nblines = len(F) - 1
for l in F[1:]: for l in F[1:]:
etudid = l[-1] etudid = l[-1]
if ir == nblines - 6:
H.append("</tbody>")
H.append("<tfoot>")
if ir >= nblines - 6: if ir >= nblines - 6:
# dernieres lignes: # dernieres lignes:
el = l[1] el = l[1]
@ -692,7 +661,13 @@ def make_formsemestre_recapcomplet(
for i in range(len(nsn)): for i in range(len(nsn)):
if nsn[i] == "NA": if nsn[i] == "NA":
nsn[i] = "-" 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) cells += '<td class="recap_col">%s</td>' % el # nom etud (lien)
if not hidebac: if not hidebac:
cells += '<td class="recap_col_bac">%s</td>' % nsn[2] # bac cells += '<td class="recap_col_bac">%s</td>' % nsn[2] # bac
@ -760,7 +735,8 @@ def make_formsemestre_recapcomplet(
cells += "</td>" cells += "</td>"
H.append(cells + "</tr>") H.append(cells + "</tr>")
H.append(ligne_titres) H.append(ligne_titres_foot)
H.append("</tfoot>")
H.append("</table>") H.append("</table>")
# Form pour choisir partition de classement: # Form pour choisir partition de classement:
@ -828,6 +804,40 @@ def make_formsemestre_recapcomplet(
raise ValueError("unknown format %s" % format) 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]: def _list_notes_evals(evals: list[Evaluation], etudid: int) -> list[str]:
"""Liste des notes des evaluations completes de ce module """Liste des notes des evaluations completes de ce module
(pour table xls avec evals) (pour table xls avec evals)

View File

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

View File

@ -3226,4 +3226,15 @@ span.ext_sem_moy {
font-weight: bold; font-weight: bold;
color: rgb(122, 40, 2); color: rgb(122, 40, 2);
font-size: 120%; 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 // Affiche un message transitoire
function sco_message(msg, color) { function sco_message(msg, color) {
if (color === undefined) { if (color === undefined) {
@ -106,7 +105,7 @@ function get_query_args() {
// Tables (gen_tables) // Tables (gen_tables)
$(function () { $(function () {
$('table.gt_table').DataTable({ var table_options = {
"paging": false, "paging": false,
"searching": false, "searching": false,
"info": false, "info": false,
@ -117,7 +116,10 @@ $(function () {
}, },
"orderCellsTop": true, // cellules ligne 1 pour tri "orderCellsTop": true, // cellules ligne 1 pour tri
"aaSorting": [], // Prevent initial sorting "aaSorting": [], // Prevent initial sorting
}); };
$('table.gt_table').DataTable(table_options);
table_options["searching"] = true;
$('table.gt_table_searchable').DataTable(table_options);
}); });