1
0
forked from ScoDoc/ScoDoc

Tableau bord module: avertissement si poids d'évaluation nuls. Début de #411.

This commit is contained in:
Emmanuel Viennet 2022-10-01 18:55:32 +02:00
parent 268b75d441
commit 06cbd65365
3 changed files with 348 additions and 283 deletions

View File

@ -44,7 +44,9 @@ class Evaluation(db.Model):
ues = db.relationship("UniteEns", secondary="evaluation_ue_poids", viewonly=True) ues = db.relationship("UniteEns", secondary="evaluation_ue_poids", viewonly=True)
def __repr__(self): def __repr__(self):
return f"""<Evaluation {self.id} {self.jour.isoformat() if self.jour else ''} "{self.description[:16] if self.description else ''}">""" return f"""<Evaluation {self.id} {
self.jour.isoformat() if self.jour else ''} "{
self.description[:16] if self.description else ''}">"""
def to_dict(self) -> dict: def to_dict(self) -> dict:
"Représentation dict, pour json" "Représentation dict, pour json"
@ -74,6 +76,17 @@ class Evaluation(db.Model):
if k != "_sa_instance_state" and k != "id" and k in data: if k != "_sa_instance_state" and k != "id" and k in data:
setattr(self, k, data[k]) setattr(self, k, data[k])
def descr_heure(self) -> str:
"Description de la plage horaire pour affichages"
if self.heure_debut and (
not self.heure_fin or self.heure_fin == self.heure_debut
):
return f"""à {self.heure_debut.strftime("%H:%M")}"""
elif self.heure_debut and self.heure_fin:
return f"""de {self.heure_debut.strftime("%H:%M")} à {self.heure_fin.strftime("%H:%M")}"""
else:
return ""
def clone(self, not_copying=()): def clone(self, not_copying=()):
"""Clone, not copying the given attrs """Clone, not copying the given attrs
Attention: la copie n'a pas d'id avant le prochain commit Attention: la copie n'a pas d'id avant le prochain commit
@ -164,7 +177,7 @@ class EvaluationUEPoids(db.Model):
# Fonction héritée de ScoDoc7 à refactorer # Fonction héritée de ScoDoc7 à refactorer
def evaluation_enrich_dict(e): def evaluation_enrich_dict(e: dict):
"""add or convert some fields in an evaluation dict""" """add or convert some fields in an evaluation dict"""
# For ScoDoc7 compat # For ScoDoc7 compat
heure_debut_dt = e["heure_debut"] or datetime.time( heure_debut_dt = e["heure_debut"] or datetime.time(

View File

@ -37,6 +37,7 @@ from app.comp import res_sem
from app.comp.res_compat import NotesTableCompat from app.comp.res_compat import NotesTableCompat
from app.models import ModuleImpl from app.models import ModuleImpl
from app.models.evaluations import Evaluation from app.models.evaluations import Evaluation
from app.models.ues import UniteEns
import app.scodoc.sco_utils as scu import app.scodoc.sco_utils as scu
from app.scodoc.sco_exceptions import ScoInvalidIdType from app.scodoc.sco_exceptions import ScoInvalidIdType
from app.scodoc.sco_cursus_dut import formsemestre_has_decisions from app.scodoc.sco_cursus_dut import formsemestre_has_decisions
@ -425,16 +426,93 @@ def moduleimpl_status(moduleimpl_id=None, partition_id=None):
H.append("""<table class="moduleimpl_evaluations">""") H.append("""<table class="moduleimpl_evaluations">""")
eval_index = len(mod_evals) - 1 eval_index = len(mod_evals) - 1
first_eval = True first_eval = True
for eval in mod_evals: for eval_dict in mod_evals:
evaluation: Evaluation = Evaluation.query.get( H.append(
eval["evaluation_id"] _ligne_evaluation(
) # TODO unifier modimpl,
eval_dict,
first_eval=first_eval,
partition_id=partition_id,
arrow_down=arrow_down,
arrow_none=arrow_none,
arrow_up=arrow_up,
can_edit_evals=can_edit_evals,
can_edit_notes=can_edit_notes,
eval_index=eval_index,
has_expression=has_expression,
nb_evals=len(mod_evals),
)
)
eval_index -= 1
first_eval = False
#
H.append("""<tr><td colspan="8">""")
if sem_locked:
H.append(f"""{scu.icontag("lock32_img")} semestre verrouillé""")
elif can_edit_evals:
H.append(top_table_links)
H.append(
f"""</td></tr>
</table>
</div>
<!-- LEGENDE -->
<hr>
<h4>Légende</h4>
<ul>
<li>{scu.icontag("edit_img")} : modifie description de l'évaluation
(date, heure, coefficient, ...)
</li>
<li>{scu.icontag("notes_img")} : saisie des notes</li>
<li>{scu.icontag("delete_img")} : indique qu'il n'y a aucune note
entrée (cliquer pour supprimer cette évaluation)
</li>
<li>{scu.icontag("status_orange_img")} : indique qu'il manque
quelques notes dans cette évaluation
</li>
<li>{scu.icontag("status_green_img")} : toutes les notes sont
entrées (cliquer pour les afficher)
</li>
<li>{scu.icontag("status_visible_img")} : indique que cette évaluation
sera mentionnée dans les bulletins au format "intermédiaire"
</li>
</ul>
<p>Rappel : seules les notes des évaluations complètement saisies
(affichées en vert) apparaissent dans les bulletins.
</p>
"""
)
H.append(html_sco_header.sco_footer())
return "".join(H)
def _ligne_evaluation(
modimpl: ModuleImpl,
eval_dict: dict,
first_eval: bool = True,
partition_id=None,
arrow_down=None,
arrow_none=None,
arrow_up=None,
can_edit_evals: bool = False,
can_edit_notes: bool = False,
eval_index: int = 0,
has_expression: bool = False,
nb_evals: int = 0,
) -> str:
"""Ligne <tr> décrivant une évaluation dans le tableau de bord moduleimpl."""
H = []
# TODO unifier pour ne plus utiliser eval_dict
evaluation: Evaluation = Evaluation.query.get(eval_dict["evaluation_id"])
etat = sco_evaluations.do_evaluation_etat( etat = sco_evaluations.do_evaluation_etat(
eval["evaluation_id"], evaluation.id,
partition_id=partition_id, partition_id=partition_id,
select_first_partition=True, select_first_partition=True,
) )
if eval["evaluation_type"] in ( if evaluation.evaluation_type in (
scu.EVALUATION_RATTRAPAGE, scu.EVALUATION_RATTRAPAGE,
scu.EVALUATION_SESSION2, scu.EVALUATION_SESSION2,
): ):
@ -445,63 +523,79 @@ def moduleimpl_status(moduleimpl_id=None, partition_id=None):
if not first_eval: if not first_eval:
H.append("""<tr><td colspan="8">&nbsp;</td></tr>""") H.append("""<tr><td colspan="8">&nbsp;</td></tr>""")
tr_class_1 += " mievr_spaced" tr_class_1 += " mievr_spaced"
H.append("""<tr class="%s"><td class="mievr_tit" colspan="8">""" % tr_class_1) H.append(f"""<tr class="{tr_class_1}"><td class="mievr_tit" colspan="8">""")
if eval["jour"]: if evaluation.jour:
H.append("""Le %(jour)s%(descrheure)s""" % eval) H.append(
f"""Le {evaluation.jour.strftime("%d/%m/%Y")} {evaluation.descr_heure()}"""
)
else: else:
H.append( H.append(
"""<a href="evaluation_edit?evaluation_id=%(evaluation_id)s" class="mievr_evalnodate">Evaluation sans date</a>""" f"""<a href="{url_for("notes.evaluation_edit",
% eval scodoc_dept=g.scodoc_dept, evaluation_id=evaluation.id)
}" class="mievr_evalnodate">Évaluation sans date</a>"""
) )
H.append("&nbsp;&nbsp;&nbsp; <em>%(description)s</em>" % eval) H.append(f"&nbsp;&nbsp;&nbsp; <em>{evaluation.description or ''}</em>")
if eval["evaluation_type"] == scu.EVALUATION_RATTRAPAGE: if evaluation.evaluation_type == scu.EVALUATION_RATTRAPAGE:
H.append( H.append(
"""<span class="mievr_rattr" title="remplace si meilleure note">rattrapage</span>""" """<span class="mievr_rattr" title="remplace si meilleure note">rattrapage</span>"""
) )
elif eval["evaluation_type"] == scu.EVALUATION_SESSION2: elif evaluation.evaluation_type == scu.EVALUATION_SESSION2:
H.append( H.append(
"""<span class="mievr_rattr" title="remplace autres notes">session 2</span>""" """<span class="mievr_rattr" title="remplace autres notes">session 2</span>"""
) )
# Avertissement si coefs/poids nuls
if (
evaluation.coefficient * sum(evaluation.get_ue_poids_dict().values())
< scu.NOTES_PRECISION
):
H.append("""<span class="eval_warning_coef">coef. nul !</span>""")
#
if etat["last_modif"]: if etat["last_modif"]:
H.append( H.append(
"""<span class="mievr_lastmodif">(dernière modif le %s)</span>""" f"""<span class="mievr_lastmodif">(dernière modif le {
% etat["last_modif"].strftime("%d/%m/%Y à %Hh%M") etat["last_modif"].strftime("%d/%m/%Y à %Hh%M")})</span>"""
) )
#
H.append('<span class="evalindex_cont">') H.append('<span class="evalindex_cont">')
if has_expression or True: if has_expression or True:
H.append( H.append(
"""<span class="evalindex" title="Indice dans les vecteurs (formules)">%2d</span>""" f"""<span class="evalindex" title="Indice dans les vecteurs (formules)">{
% eval_index eval_index:2}</span>"""
) )
# Fleches: # Fleches:
H.append('<span class="eval_arrows_chld">') H.append('<span class="eval_arrows_chld">')
if eval_index != (len(mod_evals) - 1) and can_edit_evals: if eval_index != (nb_evals - 1) and can_edit_evals:
H.append( H.append(
'<a href="module_evaluation_move?evaluation_id=%s&after=0" class="aud">%s</a>' '<a href="module_evaluation_move?evaluation_id=%s&after=0" class="aud">%s</a>'
% (eval["evaluation_id"], arrow_up) % (evaluation.id, arrow_up)
) )
else: else:
H.append(arrow_none) H.append(arrow_none)
if (eval_index > 0) and can_edit_evals: if (eval_index > 0) and can_edit_evals:
H.append( H.append(
'<a href="module_evaluation_move?evaluation_id=%s&after=1" class="aud">%s</a>' '<a href="module_evaluation_move?evaluation_id=%s&after=1" class="aud">%s</a>'
% (eval["evaluation_id"], arrow_down) % (evaluation.id, arrow_down)
) )
else: else:
H.append(arrow_none) H.append(arrow_none)
H.append("</span></span>")
eval_index -= 1
H.append("""</td></tr>""")
H.append( H.append(
"""<tr class="%s"><th class="moduleimpl_evaluations" colspan="2">&nbsp;</th><th class="moduleimpl_evaluations">Durée</th><th class="moduleimpl_evaluations">Coef.</th><th class="moduleimpl_evaluations">Notes</th><th class="moduleimpl_evaluations">Abs</th><th class="moduleimpl_evaluations">N</th><th class="moduleimpl_evaluations">Moyenne """ f"""</span></span></td>
% tr_class </tr>
<tr class="{tr_class}">
<th class="moduleimpl_evaluations" colspan="2">&nbsp;</th>
<th class="moduleimpl_evaluations">Durée</th>
<th class="moduleimpl_evaluations">Coef.</th>
<th class="moduleimpl_evaluations">Notes</th>
<th class="moduleimpl_evaluations">Abs</th>
<th class="moduleimpl_evaluations">N</th>
<th class="moduleimpl_evaluations">Moyenne """
) )
if etat["evalcomplete"]: if etat["evalcomplete"]:
etat_txt = """(prise en compte)""" etat_txt = """(prise en compte)"""
etat_descr = "notes utilisées dans les moyennes" etat_descr = "notes utilisées dans les moyennes"
elif eval["publish_incomplete"]: elif eval_dict["publish_incomplete"]:
etat_txt = """(prise en compte <b>immédiate</b>)""" etat_txt = """(prise en compte <b>immédiate</b>)"""
etat_descr = ( etat_descr = (
"il manque des notes, mais la prise en compte immédiate a été demandée" "il manque des notes, mais la prise en compte immédiate a été demandée"
@ -512,71 +606,62 @@ def moduleimpl_status(moduleimpl_id=None, partition_id=None):
else: else:
etat_txt = "" etat_txt = ""
if can_edit_evals and etat_txt: if can_edit_evals and etat_txt:
etat_txt = ( etat_txt = f"""<a href="{ url_for("notes.evaluation_edit",
'<a href="evaluation_edit?evaluation_id=%s" title="%s">%s</a>' scodoc_dept=g.scodoc_dept, evaluation_id=evaluation.id)
% (eval["evaluation_id"], etat_descr, etat_txt) }" title="{etat_descr}">{etat_txt}</a>"""
)
H.append(etat_txt)
H.append("""</th></tr>""")
H.append("""<tr class="%s"><td class="mievr">""" % tr_class) H.append(
f"""{etat_txt}</th>
</tr>
<tr class="{tr_class}"><td class="mievr">"""
)
if can_edit_evals: if can_edit_evals:
H.append( H.append(
"""<a class="smallbutton" href="evaluation_edit?evaluation_id=%s">%s</a>""" f"""<a class="smallbutton" href="{url_for('notes.evaluation_edit',
% ( scodoc_dept=g.scodoc_dept, evaluation_id=evaluation.id)
eval["evaluation_id"], }">{scu.icontag("edit_img", alt="modifier", title="Modifier informations")}</a>"""
scu.icontag(
"edit_img", alt="modifier", title="Modifier informations"
),
)
) )
if can_edit_notes: if can_edit_notes:
H.append( H.append(
"""<a class="smallbutton" href="saisie_notes?evaluation_id=%s">%s</a>""" f"""<a class="smallbutton" href="{url_for('notes.saisie_notes',
% ( scodoc_dept=g.scodoc_dept, evaluation_id=evaluation.id)
eval["evaluation_id"], }">{scu.icontag("notes_img", alt="saisie notes", title="Saisie des notes")}</a>"""
scu.icontag(
"notes_img", alt="saisie notes", title="Saisie des notes"
),
)
) )
if etat["nb_notes"] == 0: if etat["nb_notes"] == 0:
if can_edit_evals: if can_edit_evals:
H.append( H.append(
"""<a class="smallbutton" href="evaluation_delete?evaluation_id=%(evaluation_id)s">""" f"""<a class="smallbutton" href="{url_for('notes.evaluation_delete',
% eval scodoc_dept=g.scodoc_dept, evaluation_id=evaluation.id)
}">"""
) )
H.append(scu.icontag("delete_img", alt="supprimer", title="Supprimer")) H.append(scu.icontag("delete_img", alt="supprimer", title="Supprimer"))
if can_edit_evals: if can_edit_evals:
H.append("""</a>""") H.append("""</a>""")
elif etat["evalcomplete"]: elif etat["evalcomplete"]:
H.append( H.append(
"""<a class="smallbutton" href="evaluation_listenotes?evaluation_id=%s">%s</a>""" f"""<a class="smallbutton" href="{url_for('notes.evaluation_listenotes',
% (eval["evaluation_id"], scu.icontag("status_green_img", title="ok")) scodoc_dept=g.scodoc_dept, evaluation_id=evaluation.id)
}">{scu.icontag("status_green_img", title="ok")}</a>"""
) )
else: else:
if etat["evalattente"]: if etat["evalattente"]:
H.append( H.append(
"""<a class="smallbutton" href="evaluation_listenotes?evaluation_id=%s">%s</a>""" f"""<a class="smallbutton" href="{url_for('notes.evaluation_listenotes',
% ( scodoc_dept=g.scodoc_dept, evaluation_id=evaluation.id)
eval["evaluation_id"], }">{scu.icontag(
scu.icontag(
"status_greenorange_img", "status_greenorange_img",
file_format="gif", file_format="gif",
title="notes en attente", title="notes en attente",
), )}</a>"""
)
) )
else: else:
H.append( H.append(
"""<a class="smallbutton" href="evaluation_listenotes?evaluation_id=%s">%s</a>""" f"""<a class="smallbutton" href="{url_for('notes.evaluation_listenotes',
% ( scodoc_dept=g.scodoc_dept, evaluation_id=evaluation.id)
eval["evaluation_id"], }">{scu.icontag("status_orange_img", title="il manque des notes")}</a>"""
scu.icontag("status_orange_img", title="il manque des notes"),
)
) )
# #
if eval["visibulletin"]: if eval_dict["visibulletin"]:
H.append( H.append(
scu.icontag( scu.icontag(
"status_visible_img", title="visible dans bulletins intermédiaires" "status_visible_img", title="visible dans bulletins intermédiaires"
@ -588,16 +673,15 @@ def moduleimpl_status(moduleimpl_id=None, partition_id=None):
if can_edit_notes: if can_edit_notes:
H.append( H.append(
moduleimpl_evaluation_menu( moduleimpl_evaluation_menu(
eval["evaluation_id"], evaluation.id,
nbnotes=etat["nb_notes"], nbnotes=etat["nb_notes"],
) )
) )
H.append("</td>")
# #
H.append( H.append(
""" """</td>
<td class="mievr_dur">%s</td><td class="rightcell mievr_coef">%s</td>""" <td class="mievr_dur">%s</td><td class="rightcell mievr_coef">%s</td>"""
% (eval["duree"], "%g" % eval["coefficient"]) % (eval_dict["duree"], "%g" % eval_dict["coefficient"])
) )
H.append( H.append(
"""<td class="rightcell mievr_nbnotes">%(nb_notes)s / %(nb_inscrits)s</td> """<td class="rightcell mievr_nbnotes">%(nb_notes)s / %(nb_inscrits)s</td>
@ -607,20 +691,23 @@ def moduleimpl_status(moduleimpl_id=None, partition_id=None):
% etat % etat
) )
if etat["moy"]: if etat["moy"]:
H.append("<b>%s / %g</b>" % (etat["moy"], eval["note_max"])) H.append("<b>%s / %g</b>" % (etat["moy"], eval_dict["note_max"]))
H.append( H.append(
"""&nbsp; (<a href="evaluation_listenotes?evaluation_id=%s">afficher</a>)""" f"""&nbsp; (<a href="{url_for('notes.evaluation_listenotes',
% (eval["evaluation_id"],) scodoc_dept=g.scodoc_dept, evaluation_id=evaluation.id)
}">afficher</a>)"""
) )
else: else:
H.append( H.append(
"""<a class="redlink" href="saisie_notes?evaluation_id=%s">saisir notes</a>""" f"""<a class="redlink" href="{url_for('notes.saisie_notes',
% (eval["evaluation_id"]) scodoc_dept=g.scodoc_dept, evaluation_id=evaluation.id)
}">saisir notes</a>
"""
) )
H.append("""</td></tr>""") H.append("""</td></tr>""")
# #
if etat["nb_notes"] == 0: if etat["nb_notes"] == 0:
H.append("""<tr class="%s"><td></td>""" % tr_class) H.append(f"""<tr class="{tr_class}"><td></td>""")
if modimpl.module.is_apc(): if modimpl.module.is_apc():
H.append( H.append(
f"""<td colspan="7" class="eval_poids">{ f"""<td colspan="7" class="eval_poids">{
@ -633,8 +720,7 @@ def moduleimpl_status(moduleimpl_id=None, partition_id=None):
gr_moyennes = etat["gr_moyennes"] gr_moyennes = etat["gr_moyennes"]
first_group = True first_group = True
for gr_moyenne in gr_moyennes: for gr_moyenne in gr_moyennes:
H.append("""<tr class="%s">""" % tr_class) H.append(f"""<tr class="{tr_class}"><td>&nbsp;</td>""")
H.append("""<td>&nbsp;</td>""")
if first_group and modimpl.module.is_apc(): if first_group and modimpl.module.is_apc():
H.append( H.append(
f"""<td class="eval_poids" colspan="3">{ f"""<td class="eval_poids" colspan="3">{
@ -646,32 +732,29 @@ def moduleimpl_status(moduleimpl_id=None, partition_id=None):
if gr_moyenne["group_name"] is None: if gr_moyenne["group_name"] is None:
name = "Tous" # tous name = "Tous" # tous
else: else:
name = "Groupe %s" % gr_moyenne["group_name"] name = f"""Groupe {gr_moyenne["group_name"]}"""
H.append( H.append(f"""<td colspan="3" class="mievr_grtit">{name} &nbsp;</td><td>""")
"""<td colspan="3" class="mievr_grtit">%s &nbsp;</td><td>""" % name
)
if gr_moyenne["gr_nb_notes"] > 0: if gr_moyenne["gr_nb_notes"] > 0:
H.append("%(gr_moy)s" % gr_moyenne)
H.append( H.append(
"""&nbsp; (<a href="evaluation_listenotes?tf_submitted=1&evaluation_id=%s&group_ids%%3Alist=%s">%s notes</a>""" f"""{gr_moyenne["gr_moy"]}&nbsp; (<a href="{
% ( url_for('notes.evaluation_listenotes',
eval["evaluation_id"], scodoc_dept=g.scodoc_dept, evaluation_id=evaluation.id,
gr_moyenne["group_id"], tf_submitted=1, **{'group_ids:list': gr_moyenne["group_id"]})
gr_moyenne["gr_nb_notes"], }">{gr_moyenne["gr_nb_notes"]} notes</a>"""
)
) )
if gr_moyenne["gr_nb_att"] > 0: if gr_moyenne["gr_nb_att"] > 0:
H.append( H.append(
""", <span class="redboldtext">%s en attente</span>""" f""", <span class="redboldtext">{gr_moyenne["gr_nb_att"]} en attente</span>"""
% gr_moyenne["gr_nb_att"]
) )
H.append(""")""") H.append(""")""")
if gr_moyenne["group_id"] in etat["gr_incomplets"]: if gr_moyenne["group_id"] in etat["gr_incomplets"]:
H.append("""[<font color="red">""") H.append("""[<font color="red">""")
if can_edit_notes: if can_edit_notes:
H.append( H.append(
"""<a class="redlink" href="saisie_notes?evaluation_id=%s&group_ids:list=%s">incomplet</a></font>]""" f"""<a class="redlink" href="{url_for('notes.saisie_notes',
% (eval["evaluation_id"], gr_moyenne["group_id"]) scodoc_dept=g.scodoc_dept, evaluation_id=evaluation.id,
**{'group_ids:list': gr_moyenne["group_id"]})
}">incomplet</a></font>]"""
) )
else: else:
H.append("""incomplet</font>]""") H.append("""incomplet</font>]""")
@ -679,53 +762,14 @@ def moduleimpl_status(moduleimpl_id=None, partition_id=None):
H.append("""<span class="redboldtext">&nbsp; """) H.append("""<span class="redboldtext">&nbsp; """)
if can_edit_notes: if can_edit_notes:
H.append( H.append(
"""<a class="redlink" href="saisie_notes?evaluation_id=%s&group_ids:list=%s">""" f"""<a class="redlink" href="{url_for('notes.saisie_notes',
% (eval["evaluation_id"], gr_moyenne["group_id"]) scodoc_dept=g.scodoc_dept, evaluation_id=evaluation.id,
**{'group_ids:list': gr_moyenne["group_id"]})
}"""
) )
H.append("pas de notes") H.append("pas de notes")
if can_edit_notes: if can_edit_notes:
H.append("""</a>""") H.append("""</a>""")
H.append("</span>") H.append("</span>")
H.append("""</td></tr>""") H.append("""</td></tr>""")
first_eval = False return "\n".join(H)
#
H.append("""<tr><td colspan="8">""")
if sem_locked:
H.append(f"""{scu.icontag("lock32_img")} semestre verrouillé""")
elif can_edit_evals:
H.append(top_table_links)
H.append(
"""</td></tr>
</table>
</div>
<!-- LEGENDE -->
<hr>
<h4>Légende</h4>
<ul>
<li>%s : modifie description de l'évaluation (date, heure, coefficient, ...)</li>
<li>%s : saisie des notes</li>
<li>%s : indique qu'il n'y a aucune note entrée (cliquer pour supprimer cette évaluation)</li>
<li>%s : indique qu'il manque quelques notes dans cette évaluation</li>
<li>%s : toutes les notes sont entrées (cliquer pour les afficher)</li>
<li>%s : indique que cette évaluation sera mentionnée dans les bulletins au format "intermédiaire"
</ul>
<p>Rappel : seules les notes des évaluations complètement saisies (affichées en vert) apparaissent dans les bulletins.
</p>
"""
% (
scu.icontag("edit_img"),
scu.icontag("notes_img"),
scu.icontag("delete_img"),
scu.icontag("status_orange_img"),
scu.icontag("status_green_img"),
scu.icontag("status_visible_img"),
)
)
H.append(html_sco_header.sco_footer())
return "".join(H)

View File

@ -1862,6 +1862,14 @@ a.mievr_evalnodate:hover {
text-decoration: underline; text-decoration: underline;
} }
span.eval_warning_coef {
color: red;
margin: 2px;
padding-left: 3px;
padding-right: 3px;
background-color: rgb(255, 225, 0);
}
span.evalindex_cont { span.evalindex_cont {
float: right; float: right;
} }