forked from ScoDoc/ScoDoc
EDT: filtrage par groupe scodoc
This commit is contained in:
parent
b0daccb32e
commit
1f319dfeba
@ -565,11 +565,14 @@ def save_groups_auto_assignment(formsemestre_id: int):
|
|||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
@as_json
|
@as_json
|
||||||
def formsemestre_edt(formsemestre_id: int):
|
def formsemestre_edt(formsemestre_id: int):
|
||||||
"""l'emploi du temps du semestre
|
"""l'emploi du temps du semestre.
|
||||||
Si ok, une liste d'évènements. Sinon, une chaine indiquant un message d'erreur.
|
Si ok, une liste d'évènements. Sinon, une chaine indiquant un message d'erreur.
|
||||||
|
|
||||||
|
group_ids permet de filtrer sur les groupes ScoDoc.
|
||||||
"""
|
"""
|
||||||
query = FormSemestre.query.filter_by(id=formsemestre_id)
|
query = FormSemestre.query.filter_by(id=formsemestre_id)
|
||||||
if g.scodoc_dept:
|
if g.scodoc_dept:
|
||||||
query = query.filter_by(dept_id=g.scodoc_dept_id)
|
query = query.filter_by(dept_id=g.scodoc_dept_id)
|
||||||
formsemestre: FormSemestre = query.first_or_404(formsemestre_id)
|
formsemestre: FormSemestre = query.first_or_404(formsemestre_id)
|
||||||
return sco_edt_cal.formsemestre_edt_dict(formsemestre)
|
group_ids = request.args.getlist("group_ids", int)
|
||||||
|
return sco_edt_cal.formsemestre_edt_dict(formsemestre, group_ids=group_ids)
|
||||||
|
@ -111,11 +111,17 @@ _COLOR_PALETTE = [
|
|||||||
_EVENT_DEFAULT_COLOR = "rgb(214, 233, 248)"
|
_EVENT_DEFAULT_COLOR = "rgb(214, 233, 248)"
|
||||||
|
|
||||||
|
|
||||||
def formsemestre_edt_dict(formsemestre: FormSemestre) -> list[dict]:
|
def formsemestre_edt_dict(
|
||||||
|
formsemestre: FormSemestre, group_ids: list[int] = None
|
||||||
|
) -> list[dict]:
|
||||||
"""EDT complet du semestre, comme une liste de dict serialisable en json.
|
"""EDT complet du semestre, comme une liste de dict serialisable en json.
|
||||||
Fonction appellée par l'API /formsemestre/<int:formsemestre_id>/edt
|
Fonction appelée par l'API /formsemestre/<int:formsemestre_id>/edt
|
||||||
|
group_ids indiquer les groupes ScoDoc à afficher (les autres sont filtrés).
|
||||||
|
Les évènements pour lesquels le groupe ScoDoc n'est pas reconnu sont
|
||||||
|
toujours présents.
|
||||||
TODO: spécifier intervalle de dates start et end
|
TODO: spécifier intervalle de dates start et end
|
||||||
"""
|
"""
|
||||||
|
group_ids_set = set(group_ids) if group_ids else set()
|
||||||
try:
|
try:
|
||||||
events_scodoc = _load_and_convert_ics(formsemestre)
|
events_scodoc = _load_and_convert_ics(formsemestre)
|
||||||
except ScoValueError as exc:
|
except ScoValueError as exc:
|
||||||
@ -138,9 +144,12 @@ def formsemestre_edt_dict(formsemestre: FormSemestre) -> list[dict]:
|
|||||||
{scu.EMO_WARNING} non reconnu</span>
|
{scu.EMO_WARNING} non reconnu</span>
|
||||||
</div>"""
|
</div>"""
|
||||||
)
|
)
|
||||||
|
if group and group_ids_set and group.id not in group_ids_set:
|
||||||
|
continue # ignore cet évènement
|
||||||
modimpl: ModuleImpl | bool = event["modimpl"]
|
modimpl: ModuleImpl | bool = event["modimpl"]
|
||||||
if modimpl is False:
|
if modimpl is False:
|
||||||
mod_disp = f"""<div class="module-edt" title="extraction emploi du temps non configurée">
|
mod_disp = f"""<div class="module-edt"
|
||||||
|
title="extraction emploi du temps non configurée">
|
||||||
{scu.EMO_WARNING} non configuré
|
{scu.EMO_WARNING} non configuré
|
||||||
</div>"""
|
</div>"""
|
||||||
else:
|
else:
|
||||||
|
@ -290,8 +290,9 @@ def get_group_members(group_id, etat=None):
|
|||||||
return r
|
return r
|
||||||
|
|
||||||
|
|
||||||
def get_group_infos(group_id, etat=None): # was _getlisteetud
|
def get_group_infos(group_id, etat: str | None = None): # was _getlisteetud
|
||||||
"""legacy code: used by group_list and trombino"""
|
"""legacy code: used by group_list and trombino.
|
||||||
|
etat: état de l'inscription."""
|
||||||
from app.scodoc import sco_formsemestre
|
from app.scodoc import sco_formsemestre
|
||||||
|
|
||||||
cnx = ndb.GetDBConnexion()
|
cnx = ndb.GetDBConnexion()
|
||||||
|
@ -153,63 +153,79 @@ def groups_view(
|
|||||||
return "\n".join(H)
|
return "\n".join(H)
|
||||||
|
|
||||||
|
|
||||||
def form_groups_choice(groups_infos, with_selectall_butt=False, submit_on_change=False):
|
def form_groups_choice(
|
||||||
|
groups_infos,
|
||||||
|
with_selectall_butt=False,
|
||||||
|
with_deselect_butt=False,
|
||||||
|
submit_on_change=False,
|
||||||
|
default_deselect_others=True,
|
||||||
|
):
|
||||||
"""form pour selection groupes
|
"""form pour selection groupes
|
||||||
group_ids est la liste des groupes actuellement sélectionnés
|
group_ids est la liste des groupes actuellement sélectionnés
|
||||||
et doit comporter au moins un élément, sauf si formsemestre_id est spécifié.
|
et doit comporter au moins un élément, sauf si formsemestre_id est spécifié.
|
||||||
(utilisé pour retrouver le semestre et proposer la liste des autres groupes)
|
(utilisé pour retrouver le semestre et proposer la liste des autres groupes)
|
||||||
|
|
||||||
Si submit_on_change, ajoute une classe "submit_on_change" qui est utilisee en JS
|
Si submit_on_change, soumet (recharge la page) à chaque modif.
|
||||||
|
Si default_deselect_others, désélectionne le groupe "Tous" quand on sélectionne un autre groupe.
|
||||||
|
|
||||||
|
Ces deux options ajoutent des classes utilisées en JS pour la gestion du formulaire.
|
||||||
"""
|
"""
|
||||||
default_group_id = sco_groups.get_default_group(groups_infos.formsemestre_id)
|
default_group_id = sco_groups.get_default_group(groups_infos.formsemestre_id)
|
||||||
|
|
||||||
H = [
|
H = [
|
||||||
"""<form id="group_selector" method="get">
|
f"""
|
||||||
<input type="hidden" name="formsemestre_id" id="formsemestre_id" value="%s"/>
|
<form id="group_selector" method="get">
|
||||||
<input type="hidden" name="default_group_id" id="default_group_id" value="%s"/>
|
<input type="hidden" name="formsemestre_id" id="formsemestre_id"
|
||||||
|
value="{groups_infos.formsemestre_id}"/>
|
||||||
|
<input type="hidden" name="default_group_id" id="default_group_id"
|
||||||
|
value="{default_group_id}"/>
|
||||||
Groupes:
|
Groupes:
|
||||||
|
{
|
||||||
|
menu_groups_choice(
|
||||||
|
groups_infos,
|
||||||
|
submit_on_change=submit_on_change,
|
||||||
|
default_deselect_others=default_deselect_others,
|
||||||
|
)
|
||||||
|
}
|
||||||
"""
|
"""
|
||||||
% (groups_infos.formsemestre_id, default_group_id)
|
|
||||||
]
|
]
|
||||||
|
|
||||||
H.append(menu_groups_choice(groups_infos, submit_on_change=submit_on_change))
|
|
||||||
|
|
||||||
if with_selectall_butt:
|
if with_selectall_butt:
|
||||||
H.append(
|
H.append(
|
||||||
"""<input type="button" value="sélectionner tous" onmousedown="select_tous();"/>"""
|
"""<input type="button" value="sélectionner tous" onmousedown="select_groupe_tous();"/>"""
|
||||||
|
)
|
||||||
|
if with_deselect_butt:
|
||||||
|
H.append(
|
||||||
|
"""<input type="button" value="ne pas filtrer" onmousedown="remove_group_filter();"/>"""
|
||||||
)
|
)
|
||||||
H.append("</form>")
|
H.append("</form>")
|
||||||
|
|
||||||
return "\n".join(H)
|
return "\n".join(H)
|
||||||
|
|
||||||
|
|
||||||
def menu_groups_choice(groups_infos, submit_on_change=False):
|
def menu_groups_choice(
|
||||||
|
groups_infos, submit_on_change=False, default_deselect_others=True
|
||||||
|
):
|
||||||
"""menu pour selection groupes
|
"""menu pour selection groupes
|
||||||
group_ids est la liste des groupes actuellement sélectionnés
|
group_ids est la liste des groupes actuellement sélectionnés
|
||||||
et doit comporter au moins un élément, sauf si formsemestre_id est spécifié.
|
et doit comporter au moins un élément, sauf si formsemestre_id est spécifié.
|
||||||
(utilisé pour retrouver le semestre et proposer la liste des autres groupes)
|
(utilisé pour retrouver le semestre et proposer la liste des autres groupes)
|
||||||
"""
|
"""
|
||||||
default_group_id = sco_groups.get_default_group(groups_infos.formsemestre_id)
|
default_group_id = sco_groups.get_default_group(groups_infos.formsemestre_id)
|
||||||
|
|
||||||
if submit_on_change:
|
|
||||||
klass = "submit_on_change"
|
|
||||||
else:
|
|
||||||
klass = ""
|
|
||||||
H = [
|
|
||||||
"""<select name="group_ids" id="group_ids_sel" class="multiselect %s" multiple="multiple">
|
|
||||||
"""
|
|
||||||
% (klass,)
|
|
||||||
]
|
|
||||||
|
|
||||||
n_members = len(sco_groups.get_group_members(default_group_id))
|
n_members = len(sco_groups.get_group_members(default_group_id))
|
||||||
if default_group_id in groups_infos.group_ids:
|
|
||||||
selected = "selected"
|
H = [
|
||||||
else:
|
f"""<select name="group_ids" id="group_ids_sel"
|
||||||
selected = ""
|
class="multiselect
|
||||||
H.append(
|
{'submit_on_change' if submit_on_change else ''}
|
||||||
'<option class="default_group" value="%s" %s>%s (%s)</option>'
|
{'default_deselect_others' if default_deselect_others else ''}
|
||||||
% (default_group_id, selected, "Tous", n_members)
|
"
|
||||||
)
|
multiple="multiple">
|
||||||
|
<option class="default_group"
|
||||||
|
value="{default_group_id}"
|
||||||
|
{'selected' if default_group_id in groups_infos.group_ids else ''}
|
||||||
|
>Tous ({n_members})</option>
|
||||||
|
"""
|
||||||
|
]
|
||||||
|
|
||||||
for partition in groups_infos.partitions:
|
for partition in groups_infos.partitions:
|
||||||
H.append('<optgroup label="%s">' % partition["partition_name"])
|
H.append('<optgroup label="%s">' % partition["partition_name"])
|
||||||
@ -289,14 +305,19 @@ class DisplayedGroupsInfos:
|
|||||||
.formsemestre_id : semestre "principal" (en fait celui du 1er groupe de la liste)
|
.formsemestre_id : semestre "principal" (en fait celui du 1er groupe de la liste)
|
||||||
.members
|
.members
|
||||||
.groups_titles
|
.groups_titles
|
||||||
|
|
||||||
|
etat: filtrage selon l'état de l'inscription
|
||||||
|
select_all_when_unspecified : sélectionne le groupe "tous" si aucun groupe n'est indiqué.
|
||||||
|
empty_list_select_all: si vrai (défaut) on sélectionne le groupe tous si aucun groupe indiqué.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
group_ids=(), # groupes specifies dans l'URL, ou un seul int
|
group_ids=(), # groupes specifies dans l'URL, ou un seul int
|
||||||
formsemestre_id=None,
|
formsemestre_id: int | None = None,
|
||||||
etat=None,
|
etat: str | None = None,
|
||||||
select_all_when_unspecified=False,
|
select_all_when_unspecified=False,
|
||||||
|
empty_list_select_all=True,
|
||||||
moduleimpl_id=None, # used to find formsemestre when unspecified
|
moduleimpl_id=None, # used to find formsemestre when unspecified
|
||||||
):
|
):
|
||||||
if isinstance(group_ids, int):
|
if isinstance(group_ids, int):
|
||||||
@ -317,10 +338,13 @@ class DisplayedGroupsInfos:
|
|||||||
|
|
||||||
if not group_ids: # appel sans groupe (eg page accueil)
|
if not group_ids: # appel sans groupe (eg page accueil)
|
||||||
if not formsemestre_id:
|
if not formsemestre_id:
|
||||||
raise Exception("missing parameter formsemestre_id or group_ids")
|
raise ValueError("missing parameter formsemestre_id or group_ids")
|
||||||
|
if empty_list_select_all:
|
||||||
if select_all_when_unspecified:
|
if select_all_when_unspecified:
|
||||||
group_ids = [
|
group_ids = [
|
||||||
sco_groups.get_default_group(formsemestre_id, fix_if_missing=True)
|
sco_groups.get_default_group(
|
||||||
|
formsemestre_id, fix_if_missing=True
|
||||||
|
)
|
||||||
]
|
]
|
||||||
else:
|
else:
|
||||||
# selectionne le premier groupe trouvé, s'il y en a un
|
# selectionne le premier groupe trouvé, s'il y en a un
|
||||||
@ -332,6 +356,8 @@ class DisplayedGroupsInfos:
|
|||||||
group_ids = [groups[0]["group_id"]]
|
group_ids = [groups[0]["group_id"]]
|
||||||
else:
|
else:
|
||||||
group_ids = [sco_groups.get_default_group(formsemestre_id)]
|
group_ids = [sco_groups.get_default_group(formsemestre_id)]
|
||||||
|
else:
|
||||||
|
group_ids = []
|
||||||
|
|
||||||
gq = []
|
gq = []
|
||||||
for group_id in group_ids:
|
for group_id in group_ids:
|
||||||
@ -375,7 +401,8 @@ class DisplayedGroupsInfos:
|
|||||||
|
|
||||||
if not self.formsemestre: # aucun groupe selectionne
|
if not self.formsemestre: # aucun groupe selectionne
|
||||||
self.formsemestre = sco_formsemestre.get_formsemestre(formsemestre_id)
|
self.formsemestre = sco_formsemestre.get_formsemestre(formsemestre_id)
|
||||||
|
if formsemestre_id not in self.sems:
|
||||||
|
self.sems[formsemestre_id] = self.formsemestre
|
||||||
self.sortuniq()
|
self.sortuniq()
|
||||||
|
|
||||||
if len(self.sems) > 1:
|
if len(self.sems) > 1:
|
||||||
|
@ -5,46 +5,54 @@ $().ready(function () {
|
|||||||
for (var i = 0; i < spans.length; i++) {
|
for (var i = 0; i < spans.length; i++) {
|
||||||
var sp = spans[i];
|
var sp = spans[i];
|
||||||
var etudid = sp.id;
|
var etudid = sp.id;
|
||||||
$(sp).load(SCO_URL + '/etud_photo_html?etudid=' + etudid);
|
$(sp).load(SCO_URL + "/etud_photo_html?etudid=" + etudid);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
// L'URL pour recharger l'état courant de la page (groupes et tab selectionnes)
|
// L'URL pour recharger l'état courant de la page (groupes et tab selectionnes)
|
||||||
// (ne fonctionne que pour les requetes GET: manipule la query string)
|
// (ne fonctionne que pour les requetes GET: manipule la query string)
|
||||||
|
|
||||||
function groups_view_url() {
|
function groups_view_url() {
|
||||||
var url = $.url();
|
var url = $.url();
|
||||||
delete url.param()['group_ids']; // retire anciens groupes de l'URL
|
delete url.param()["group_ids"]; // retire anciens groupes de l'URL
|
||||||
delete url.param()['curtab']; // retire ancien tab actif
|
delete url.param()["curtab"]; // retire ancien tab actif
|
||||||
if (CURRENT_TAB_HASH) {
|
if (CURRENT_TAB_HASH) {
|
||||||
url.param()['curtab'] = CURRENT_TAB_HASH;
|
url.param()["curtab"] = CURRENT_TAB_HASH;
|
||||||
}
|
}
|
||||||
delete url.param()['formsemestre_id'];
|
delete url.param()["formsemestre_id"];
|
||||||
url.param()['formsemestre_id'] = $("#group_selector")[0].formsemestre_id.value;
|
url.param()["formsemestre_id"] =
|
||||||
|
$("#group_selector")[0].formsemestre_id.value;
|
||||||
|
|
||||||
var selected_groups = $("#group_selector select").val();
|
var selected_groups = $("#group_selector select").val();
|
||||||
url.param()['group_ids'] = selected_groups; // remplace par groupes selectionnes
|
url.param()["group_ids"] = selected_groups; // remplace par groupes selectionnes
|
||||||
|
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Selectionne tous les etudiants et recharge la page:
|
// Sélectionne le groupe "tous" et recharge la page:
|
||||||
function select_tous() {
|
function select_groupe_tous() {
|
||||||
var url = groups_view_url();
|
var url = groups_view_url();
|
||||||
var default_group_id = $("#group_selector")[0].default_group_id.value;
|
var default_group_id = $("#group_selector")[0].default_group_id.value;
|
||||||
delete url.param()['group_ids'];
|
delete url.param()["group_ids"];
|
||||||
url.param()['group_ids'] = [default_group_id];
|
url.param()["group_ids"] = [default_group_id];
|
||||||
|
|
||||||
var query_string = $.param(url.param(), traditional = true);
|
var query_string = $.param(url.param(), (traditional = true));
|
||||||
window.location = url.attr('base') + url.attr('path') + '?' + query_string;
|
window.location = url.attr("base") + url.attr("path") + "?" + query_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recharge la page sans arguments group_ids
|
||||||
|
function remove_group_filter() {
|
||||||
|
var url = groups_view_url();
|
||||||
|
delete url.param()["group_ids"];
|
||||||
|
var query_string = $.param(url.param(), (traditional = true));
|
||||||
|
window.location = url.attr("base") + url.attr("path") + "?" + query_string;
|
||||||
}
|
}
|
||||||
|
|
||||||
// L'URL pour l'état courant de la page:
|
// L'URL pour l'état courant de la page:
|
||||||
function get_current_url() {
|
function get_current_url() {
|
||||||
var url = groups_view_url();
|
var url = groups_view_url();
|
||||||
var query_string = $.param(url.param(), traditional = true);
|
var query_string = $.param(url.param(), (traditional = true));
|
||||||
return url.attr('base') + url.attr('path') + '?' + query_string;
|
return url.attr("base") + url.attr("path") + "?" + query_string;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recharge la page en changeant les groupes selectionnés et en conservant le tab actif:
|
// Recharge la page en changeant les groupes selectionnés et en conservant le tab actif:
|
||||||
@ -53,13 +61,15 @@ function submit_group_selector() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function show_current_tab() {
|
function show_current_tab() {
|
||||||
$('.nav-tabs [href="#' + CURRENT_TAB_HASH + '"]').tab('show');
|
if (document.getElementsByClassName("nav-tabs").length < 0) {
|
||||||
|
$('.nav-tabs [href="#' + CURRENT_TAB_HASH + '"]').tab("show");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var CURRENT_TAB_HASH = $.url().param()['curtab'];
|
var CURRENT_TAB_HASH = $.url().param()["curtab"];
|
||||||
|
|
||||||
$().ready(function () {
|
$().ready(function () {
|
||||||
$('.nav-tabs a').on('shown.bs.tab', function (e) {
|
$(".nav-tabs a").on("shown.bs.tab", function (e) {
|
||||||
CURRENT_TAB_HASH = e.target.hash.slice(1); // sans le #
|
CURRENT_TAB_HASH = e.target.hash.slice(1); // sans le #
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -69,7 +79,13 @@ $().ready(function () {
|
|||||||
function change_list_options() {
|
function change_list_options() {
|
||||||
var url = groups_view_url();
|
var url = groups_view_url();
|
||||||
var selected_options = $("#group_list_options").val();
|
var selected_options = $("#group_list_options").val();
|
||||||
var options = ["with_paiement", "with_archives", "with_annotations", "with_codes", "with_bourse"];
|
var options = [
|
||||||
|
"with_paiement",
|
||||||
|
"with_archives",
|
||||||
|
"with_annotations",
|
||||||
|
"with_codes",
|
||||||
|
"with_bourse",
|
||||||
|
];
|
||||||
for (var i = 0; i < options.length; i++) {
|
for (var i = 0; i < options.length; i++) {
|
||||||
var option = options[i];
|
var option = options[i];
|
||||||
delete url.param()[option];
|
delete url.param()[option];
|
||||||
@ -77,8 +93,8 @@ function change_list_options() {
|
|||||||
url.param()[option] = 1;
|
url.param()[option] = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var query_string = $.param(url.param(), traditional = true);
|
var query_string = $.param(url.param(), (traditional = true));
|
||||||
window.location = url.attr('base') + url.attr('path') + '?' + query_string;
|
window.location = url.attr("base") + url.attr("path") + "?" + query_string;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Menu choix groupe:
|
// Menu choix groupe:
|
||||||
@ -95,64 +111,87 @@ function toggle_visible_etuds() {
|
|||||||
var input_eval = $("#formnotes_evaluation_id");
|
var input_eval = $("#formnotes_evaluation_id");
|
||||||
if (input_eval.length > 0) {
|
if (input_eval.length > 0) {
|
||||||
var evaluation_id = input_eval[0].value;
|
var evaluation_id = input_eval[0].value;
|
||||||
$("#menu_saisie_tableur a").attr("href", "saisie_notes_tableur?evaluation_id=" + evaluation_id + qargs);
|
$("#menu_saisie_tableur a").attr(
|
||||||
|
"href",
|
||||||
|
"saisie_notes_tableur?evaluation_id=" + evaluation_id + qargs
|
||||||
|
);
|
||||||
// lien feuille excel:
|
// lien feuille excel:
|
||||||
$("#lnk_feuille_saisie").attr("href", "feuille_saisie_notes?evaluation_id=" + evaluation_id + qargs);
|
$("#lnk_feuille_saisie").attr(
|
||||||
|
"href",
|
||||||
|
"feuille_saisie_notes?evaluation_id=" + evaluation_id + qargs
|
||||||
|
);
|
||||||
}
|
}
|
||||||
// Update champs form group_ids_str
|
// Update champs form group_ids_str
|
||||||
let group_ids_str = Array.from(
|
let group_ids_str = Array.from(
|
||||||
document.querySelectorAll("#group_ids_sel option:checked")
|
document.querySelectorAll("#group_ids_sel option:checked")
|
||||||
).map(
|
)
|
||||||
function (elem) { return elem.value; }
|
.map(function (elem) {
|
||||||
).join();
|
return elem.value;
|
||||||
document.querySelectorAll("input.group_ids_str").forEach(elem => elem.value = group_ids_str);
|
})
|
||||||
|
.join();
|
||||||
|
document
|
||||||
|
.querySelectorAll("input.group_ids_str")
|
||||||
|
.forEach((elem) => (elem.value = group_ids_str));
|
||||||
}
|
}
|
||||||
|
|
||||||
$().ready(function () {
|
$().ready(function () {
|
||||||
$('#group_ids_sel').multiselect(
|
$("#group_ids_sel").multiselect({
|
||||||
{
|
|
||||||
includeSelectAllOption: false,
|
includeSelectAllOption: false,
|
||||||
nonSelectedText: 'choisir...',
|
nonSelectedText: "choisir...",
|
||||||
// buttonContainer: '<div id="group_ids_sel_container"/>',
|
// buttonContainer: '<div id="group_ids_sel_container"/>',
|
||||||
onChange: function (element, checked) {
|
onChange: function (element, checked) {
|
||||||
if (checked == true) {
|
// Gestion du groupe "tous"
|
||||||
|
if (
|
||||||
|
checked == true &&
|
||||||
|
$("#group_ids_sel").hasClass("default_deselect_others")
|
||||||
|
) {
|
||||||
var default_group_id = $(".default_group")[0].value;
|
var default_group_id = $(".default_group")[0].value;
|
||||||
|
|
||||||
if (element.hasClass("default_group")) {
|
if (element.hasClass("default_group")) {
|
||||||
// click sur groupe "tous"
|
// click sur groupe "tous"
|
||||||
// deselectionne les autres
|
// deselectionne les autres
|
||||||
$("#group_ids_sel option:selected").each(function (index, opt) {
|
$("#group_ids_sel option:selected").each(function (
|
||||||
|
index,
|
||||||
|
opt
|
||||||
|
) {
|
||||||
if (opt.value != default_group_id) {
|
if (opt.value != default_group_id) {
|
||||||
$("#group_ids_sel").multiselect('deselect', opt.value);
|
$("#group_ids_sel").multiselect(
|
||||||
|
"deselect",
|
||||||
|
opt.value
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// click sur un autre item
|
// click sur un autre item
|
||||||
// si le groupe "tous" est selectionne et que l'on coche un autre, le deselectionner
|
// si le groupe "tous" est selectionne et que l'on coche un autre, le deselectionner
|
||||||
var default_is_selected = false;
|
var default_is_selected = false;
|
||||||
$("#group_ids_sel option:selected").each(function (index, opt) {
|
$("#group_ids_sel option:selected").each(function (
|
||||||
|
index,
|
||||||
|
opt
|
||||||
|
) {
|
||||||
if (opt.value == default_group_id) {
|
if (opt.value == default_group_id) {
|
||||||
default_is_selected = true;
|
default_is_selected = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (default_is_selected) {
|
if (default_is_selected) {
|
||||||
$("#group_ids_sel").multiselect('deselect', default_group_id);
|
$("#group_ids_sel").multiselect(
|
||||||
|
"deselect",
|
||||||
|
default_group_id
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
toggle_visible_etuds();
|
toggle_visible_etuds();
|
||||||
// referme le menu apres chaque choix:
|
// referme le menu apres chaque choix:
|
||||||
$("#group_selector .btn-group").removeClass('open');
|
$("#group_selector .btn-group").removeClass("open");
|
||||||
|
|
||||||
if ($("#group_ids_sel").hasClass("submit_on_change")) {
|
if ($("#group_ids_sel").hasClass("submit_on_change")) {
|
||||||
submit_group_selector();
|
submit_group_selector();
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
|
||||||
// initial setup
|
// initial setup
|
||||||
toggle_visible_etuds();
|
toggle_visible_etuds();
|
||||||
@ -160,27 +199,27 @@ $().ready(function () {
|
|||||||
|
|
||||||
// Trombinoscope
|
// Trombinoscope
|
||||||
$().ready(function () {
|
$().ready(function () {
|
||||||
|
|
||||||
var elems = $(".trombi-photo");
|
var elems = $(".trombi-photo");
|
||||||
for (var i = 0; i < elems.length; i++) {
|
for (var i = 0; i < elems.length; i++) {
|
||||||
$(elems[i]).qtip(
|
$(elems[i]).qtip({
|
||||||
{
|
|
||||||
content: {
|
content: {
|
||||||
ajax: {
|
ajax: {
|
||||||
url: SCO_URL + "/etud_info_html?with_photo=0&etudid=" + get_etudid_from_elem(elems[i])
|
url:
|
||||||
|
SCO_URL +
|
||||||
|
"/etud_info_html?with_photo=0&etudid=" +
|
||||||
|
get_etudid_from_elem(elems[i]),
|
||||||
},
|
},
|
||||||
text: "Loading..."
|
text: "Loading...",
|
||||||
},
|
},
|
||||||
position: {
|
position: {
|
||||||
at: "right",
|
at: "right",
|
||||||
my: "left top"
|
my: "left top",
|
||||||
},
|
},
|
||||||
style: {
|
style: {
|
||||||
classes: 'qtip-etud'
|
classes: "qtip-etud",
|
||||||
},
|
},
|
||||||
// utile pour debugguer le css:
|
// utile pour debugguer le css:
|
||||||
// hide: { event: 'unfocus' }
|
// hide: { event: 'unfocus' }
|
||||||
}
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -3,8 +3,9 @@
|
|||||||
|
|
||||||
{% block styles %}
|
{% block styles %}
|
||||||
{{super()}}
|
{{super()}}
|
||||||
<link href="{{scu.STATIC_DIR}}/libjs/tui.calendar/toastui-calendar.min.css" rel="stylesheet" type="text/css" />
|
<link rel="stylesheet" href="{{scu.STATIC_DIR}}/libjs/tui.calendar/toastui-calendar.min.css"/>
|
||||||
<link rel="stylesheet" href="{{ scu.STATIC_DIR }}/css/edt.css" type="text/css">
|
<link rel="stylesheet" href="{{scu.STATIC_DIR}}/libjs/bootstrap-multiselect-1.1.2/bootstrap-multiselect.min.css"/>
|
||||||
|
<link rel="stylesheet" href="{{scu.STATIC_DIR}}/css/edt.css">
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
@ -13,6 +14,8 @@
|
|||||||
<div class="tab-content">
|
<div class="tab-content">
|
||||||
<h2>Expérimental: emploi du temps</h2>
|
<h2>Expérimental: emploi du temps</h2>
|
||||||
|
|
||||||
|
{{ form_groups_choice|safe }}
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<span id="menu-navi">
|
<span id="menu-navi">
|
||||||
<button type="button" class="btn btn-default btn-sm move-today"
|
<button type="button" class="btn btn-default btn-sm move-today"
|
||||||
@ -28,12 +31,24 @@
|
|||||||
</div>
|
</div>
|
||||||
<div id="calendar" style="height: calc(100vh - 180px);"></div>
|
<div id="calendar" style="height: calc(100vh - 180px);"></div>
|
||||||
|
|
||||||
|
<div class="help">
|
||||||
|
<ul>
|
||||||
|
<li>Les heures sont toujours affichées dans le fuseau horaire du serveur,
|
||||||
|
qui est en principe celui des étudiants.
|
||||||
|
</li>
|
||||||
|
<li>Si vous filtrez par groupe, les évènements dont le groupe n'est pas reconnu seront affichés.
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock app_content %}
|
{% endblock app_content %}
|
||||||
|
|
||||||
{% block scripts %}
|
{% block scripts %}
|
||||||
{{ super() }}
|
{{ super() }}
|
||||||
|
<script src="{{scu.STATIC_DIR}}/libjs/bootstrap-multiselect-1.1.2/bootstrap-multiselect.min.js"></script>
|
||||||
|
<script src="{{scu.STATIC_DIR}}/libjs/purl.js"></script>
|
||||||
<script src="{{scu.STATIC_DIR}}/libjs/tui.calendar/toastui-calendar.min.js"></script>
|
<script src="{{scu.STATIC_DIR}}/libjs/tui.calendar/toastui-calendar.min.js"></script>
|
||||||
|
<script src="{{scu.STATIC_DIR}}/js/groups_view.js"></script>
|
||||||
<script>
|
<script>
|
||||||
let hm_formatter = new Intl.DateTimeFormat('default', {
|
let hm_formatter = new Intl.DateTimeFormat('default', {
|
||||||
hour: '2-digit',
|
hour: '2-digit',
|
||||||
@ -92,7 +107,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
|
|
||||||
const calendar = new Calendar(container, options);
|
const calendar = new Calendar(container, options);
|
||||||
|
|
||||||
fetch(`${SCO_URL}/../api/formsemestre/{{formsemestre.id}}/edt`)
|
fetch(`${SCO_URL}/../api/formsemestre/{{formsemestre.id}}/edt?{{groups_query_args|safe}}`)
|
||||||
.then(r=>{return r.json()})
|
.then(r=>{return r.json()})
|
||||||
.then(events=>{
|
.then(events=>{
|
||||||
if (typeof events == 'string') {
|
if (typeof events == 'string') {
|
||||||
|
@ -40,6 +40,7 @@ from app.decorators import (
|
|||||||
from app.forms.formsemestre import change_formation, edit_modimpls_codes_apo
|
from app.forms.formsemestre import change_formation, edit_modimpls_codes_apo
|
||||||
from app.models import Formation, FormSemestre, ScoDocSiteConfig
|
from app.models import Formation, FormSemestre, ScoDocSiteConfig
|
||||||
from app.scodoc import sco_formations, sco_formation_versions
|
from app.scodoc import sco_formations, sco_formation_versions
|
||||||
|
from app.scodoc import sco_groups_view
|
||||||
from app.scodoc.sco_permissions import Permission
|
from app.scodoc.sco_permissions import Permission
|
||||||
from app.views import notes_bp as bp
|
from app.views import notes_bp as bp
|
||||||
from app.views import ScoData
|
from app.views import ScoData
|
||||||
@ -162,10 +163,23 @@ def formsemestre_edt(formsemestre_id: int):
|
|||||||
hour_start = cfg.value.split(":")[0].lstrip(" 0") if cfg else "7"
|
hour_start = cfg.value.split(":")[0].lstrip(" 0") if cfg else "7"
|
||||||
cfg = ScoDocSiteConfig.query.filter_by(name="assi_afternoon_time").first()
|
cfg = ScoDocSiteConfig.query.filter_by(name="assi_afternoon_time").first()
|
||||||
hour_end = cfg.value.split(":")[0].lstrip(" 0") if cfg else "18"
|
hour_end = cfg.value.split(":")[0].lstrip(" 0") if cfg else "18"
|
||||||
|
group_ids = request.args.getlist("group_ids", int)
|
||||||
|
groups_infos = sco_groups_view.DisplayedGroupsInfos(
|
||||||
|
group_ids=group_ids,
|
||||||
|
formsemestre_id=formsemestre_id,
|
||||||
|
empty_list_select_all=False,
|
||||||
|
)
|
||||||
return render_template(
|
return render_template(
|
||||||
"formsemestre/edt.j2",
|
"formsemestre/edt.j2",
|
||||||
formsemestre=formsemestre,
|
formsemestre=formsemestre,
|
||||||
hour_start=hour_start,
|
hour_start=hour_start,
|
||||||
hour_end=hour_end,
|
hour_end=hour_end,
|
||||||
|
form_groups_choice=sco_groups_view.form_groups_choice(
|
||||||
|
groups_infos,
|
||||||
|
submit_on_change=True,
|
||||||
|
default_deselect_others=False,
|
||||||
|
with_deselect_butt=True,
|
||||||
|
),
|
||||||
|
groups_query_args=groups_infos.groups_query_args,
|
||||||
sco=ScoData(formsemestre=formsemestre),
|
sco=ScoData(formsemestre=formsemestre),
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user