Utilisation systématique du nouvel éditeur de partition

This commit is contained in:
Emmanuel Viennet 2023-07-21 09:25:39 +02:00
parent 8be0ab0678
commit a58919d8b4
7 changed files with 428 additions and 383 deletions

View File

@ -926,9 +926,10 @@ def _make_listes_sem(formsemestre: FormSemestre, with_absences=True):
H.append('<p class="help indent">Aucun groupe peuplé dans cette partition')
if sco_groups.sco_permissions_check.can_change_groups(formsemestre.id):
H.append(
f""" (<a href="{url_for("scolar.affect_groups",
f""" (<a href="{url_for("scolar.partition_editor",
scodoc_dept=g.scodoc_dept,
partition_id=partition["partition_id"])
formsemestre_id=formsemestre.id,
edit_partition=1)
}" class="stdlink">créer</a>)"""
)
H.append("</p>")

View File

@ -415,8 +415,8 @@ def formsemestre_inscr_passage(
): # il y a au moins une vraie partition
H.append(
f"""<li><a class="stdlink" href="{
url_for("scolar.affect_groups",
scodoc_dept=g.scodoc_dept, partition_id=partition["partition_id"])
url_for("scolar.partition_editor", scodoc_dept=g.scodoc_dept,
formsemestre_id=formsemestre_id)
}">Répartir les groupes de {partition["partition_name"]}</a></li>
"""
)

View File

@ -55,6 +55,7 @@ EKEY_APO = "nip"
EKEY_SCO = "code_nip"
EKEY_NAME = "code NIP"
# view:
def formsemestre_synchro_etuds(
formsemestre_id,
@ -270,10 +271,9 @@ def formsemestre_synchro_etuds(
if partitions: # il y a au moins une vraie partition
H.append(
f"""<li><a class="stdlink" href="{
url_for("scolar.affect_groups",
scodoc_dept=g.scodoc_dept,
partition_id=partitions[0]["partition_id"]
)}">Répartir les groupes de {partitions[0]["partition_name"]}</a></li>
url_for("scolar.partition_editor",
scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre_id)
}">Répartir les groupes de {partitions[0]["partition_name"]}</a></li>
"""
)
@ -407,6 +407,7 @@ def list_synch(sem, anneeapogee=None):
)
#
cnx = ndb.GetDBConnexion()
# Tri listes
def set_to_sorted_list(etudset, etud_apo=False, is_inscrit=False):
def key2etud(key, etud_apo=False):

View File

@ -1,10 +1,9 @@
/* -*- mode: javascript -*-
*
* ScoDoc: Affectation des groupes de TD
* re-ecriture utilisant jQuery de l'ancien code
* OBSOLETE: Page ScoDoc 7 avec jQuery, remplacée par partition_editor
*/
/* --- Globals ---- */
var EtudColors = ["#E8EEF7", "#ffffff"]; // [ "#E8EEF7", "#E0ECFF", "#E5E6BE", "#F3EAE2", "#E3EAE1" ];
var EtudColorsIdx = 0;
@ -16,18 +15,22 @@ var groups_unsaved = false;
var groups = new Object(); // Liste des groupes
function loadGroupes() {
$("#gmsg")[0].innerHTML = 'Chargement des groupes en cours...';
$("#gmsg")[0].innerHTML = "Chargement des groupes en cours...";
$("#gmsg")[0].style.display = "block";
var partition_id = document.formGroup.partition_id.value;
$.get(SCO_URL + '/XMLgetGroupsInPartition', { partition_id: partition_id })
.done(
function (data) {
var nodes = data.getElementsByTagName('group');
$.get(SCO_URL + "/XMLgetGroupsInPartition", {
partition_id: partition_id,
}).done(function (data) {
var nodes = data.getElementsByTagName("group");
if (nodes) {
var nbgroups = nodes.length;
// put last group at first (etudiants sans groupes)
if (nodes.length > 1 && nodes[nbgroups - 1].attributes.getNamedItem("group_id").value == '_none_') {
if (
nodes.length > 1 &&
nodes[nbgroups - 1].attributes.getNamedItem("group_id").value ==
"_none_"
) {
populateGroup(nodes[nodes.length - 1]);
nbgroups -= 1;
}
@ -36,22 +39,23 @@ function loadGroupes() {
populateGroup(nodes[i]);
}
}
$("#gmsg")[0].innerHTML = '';
$("#gmsg")[0].innerHTML = "";
$("#gmsg")[0].style.display = "none";
updateginfo();
}
)
});
}
function populateGroup(node) {
var group_id = node.attributes.getNamedItem("group_id").value;
var group_name = node.attributes.getNamedItem("group_name").value;
var groups_editable = Boolean(parseInt(node.attributes.getNamedItem("groups_editable").value));
var groups_editable = Boolean(
parseInt(node.attributes.getNamedItem("groups_editable").value)
);
// CREE LA BOITE POUR CE GROUPE
if (group_id) {
var gbox = new CGroupBox(group_id, group_name, groups_editable);
var etuds = node.getElementsByTagName('etud');
var x = '';
var etuds = node.getElementsByTagName("etud");
var x = "";
gbox.sorting = false; // disable to speedup
EtudColorsIdx = 0; // repart de la premiere couleur
for (var j = 0; j < etuds.length; j++) {
@ -68,7 +72,6 @@ function populateGroup(node) {
}
}
/* --- Boite pour un groupe --- */
var groupBoxes = new Object(); // assoc group_id : groupBox
@ -101,11 +104,10 @@ var CGroupBox = function (group_id, group_name, groups_editable) {
titleDiv.className = "groupTitle0";
titleDiv.appendChild(this.groupTitle());
this.groupBox.appendChild(titleDiv);
var gdiv = document.getElementById('groups');
var gdiv = document.getElementById("groups");
gdiv.appendChild(this.groupBox);
this.updateTitle();
$(this.groupBox).droppable(
{
$(this.groupBox).droppable({
accept: ".box",
activeClass: "activatedPanel",
drop: function (event, ui) {
@ -114,32 +116,41 @@ var CGroupBox = function (group_id, group_name, groups_editable) {
var etud = ETUDS[etudid];
var newGroupName = this.id;
var oldGroupName = ETUD_GROUP[etudid];
$(groupBoxes[newGroupName].groupBox).append(ui.draggable)
$(groupBoxes[newGroupName].groupBox).append(ui.draggable);
ui.draggable[0].style.left = ""; // fix style (?)
ui.draggable[0].style.top = "";
etud.changeGroup(oldGroupName, newGroupName);
etud.htmlElement.style.fontStyle = 'italic'; // italic pour les etudiants deplaces
}
etud.htmlElement.style.fontStyle = "italic"; // italic pour les etudiants deplaces
},
});
/* On peut s'amuser a deplacer tout un groupe (visuellement: pas droppable) */
$(this.groupBox).draggable({
cursor: 'move',
containment: '#groups'
cursor: "move",
containment: "#groups",
});
groupBoxes[group_id] = this; // register
updateginfo();
}
};
$.extend(CGroupBox.prototype, {
// menu for group title
groupTitle: function () {
let menuSpan = document.createElement("span");
menuSpan.className = "barrenav";
let h = "<table><tr><td><ul class=\"nav\"><li onmouseover=\"MenuDisplay(this)\" onmouseout=\"MenuHide(this)\"><a href=\"#\" class=\"menu custommenu\"><span id=\"titleSpan" + this.group_id + "\" class=\"groupTitle\">menu</span></a><ul>";
if (this.groups_editable && (this.group_id != '_none_')) {
h += "<li><a href=\"#\" onClick=\"suppressGroup('" + this.group_id + "');\">Supprimer</a></li>";
h += "<li><a href=\"#\" onClick=\"renameGroup('" + this.group_id + "');\">Renommer</a></li>";
let h =
'<table><tr><td><ul class="nav"><li onmouseover="MenuDisplay(this)" onmouseout="MenuHide(this)"><a href="#" class="menu custommenu"><span id="titleSpan' +
this.group_id +
'" class="groupTitle">menu</span></a><ul>';
if (this.groups_editable && this.group_id != "_none_") {
h +=
'<li><a href="#" onClick="suppressGroup(\'' +
this.group_id +
"');\">Supprimer</a></li>";
h +=
'<li><a href="#" onClick="renameGroup(\'' +
this.group_id +
"');\">Renommer</a></li>";
}
h += "</ul></li></ul></td></tr></table>";
menuSpan.innerHTML = h;
@ -166,23 +177,36 @@ $.extend(CGroupBox.prototype, {
},
// Update counter display
updateTitle: function () {
var tclass = '';
var tclass = "";
if (this.isNew) {
tclass = ' class="newgroup"'
tclass = ' class="newgroup"';
}
var titleSpan = document.getElementById('titleSpan' + this.group_id);
if (this.group_id != '_none_')
titleSpan.innerHTML = '<span' + tclass + '>Groupe ' + this.group_name + ' (' + this.nbetuds + ')</span>';
var titleSpan = document.getElementById("titleSpan" + this.group_id);
if (this.group_id != "_none_")
titleSpan.innerHTML =
"<span" +
tclass +
">Groupe " +
this.group_name +
" (" +
this.nbetuds +
")</span>";
else
titleSpan.innerHTML = '<span' + tclass + '>Etudiants sans groupe' + ' (' + this.nbetuds + ')</span>';
titleSpan.innerHTML =
"<span" +
tclass +
">Etudiants sans groupe" +
" (" +
this.nbetuds +
")</span>";
this.sortList(); // maintient toujours la liste triee
},
// Tri de la boite par nom
sortList: function () {
if (!this.sorting)
return;
if (!this.sorting) return;
var newRows = new Array();
for (var i = 1; i < this.groupBox.childNodes.length; i++) { // 1 car div titre
for (var i = 1; i < this.groupBox.childNodes.length; i++) {
// 1 car div titre
newRows[i - 1] = this.groupBox.childNodes[i];
}
var sortfn = function (a, b) {
@ -190,10 +214,8 @@ $.extend(CGroupBox.prototype, {
var nom_a = a.childNodes[1].childNodes[0].nodeValue;
var nom_b = b.childNodes[1].childNodes[0].nodeValue;
// console.log( 'comp( %s, %s )', nom_a, nom_b );
if (nom_a == nom_b)
return 0;
if (nom_a < nom_b)
return -1;
if (nom_a == nom_b) return 0;
if (nom_a < nom_b) return -1;
return 1;
};
newRows.sort(sortfn);
@ -202,27 +224,25 @@ $.extend(CGroupBox.prototype, {
newRows[i].style.backgroundColor = EtudColors[EtudColorsIdx];
EtudColorsIdx = (EtudColorsIdx + 1) % EtudColors.length;
}
}
},
});
function suppressGroup(group_id) {
// 1- associate all members to group _none_
if (!groupBoxes['_none_']) {
if (!groupBoxes["_none_"]) {
// create group _none_
var gbox = new CGroupBox('_none_', 'Etudiants sans groupe', true);
var gbox = new CGroupBox("_none_", "Etudiants sans groupe", true);
}
var dst_group_id = groupBoxes['_none_'].group_id;
var dst_group_id = groupBoxes["_none_"].group_id;
var src_box_etuds = groupBoxes[group_id].etuds;
for (var etudid in src_box_etuds) {
var etud = src_box_etuds[etudid];
etud.changeGroup(group_id, dst_group_id);
groupBoxes['_none_'].groupBox.appendChild(etud.htmlElement);
groupBoxes["_none_"].groupBox.appendChild(etud.htmlElement);
}
groupBoxes['_none_'].updateTitle();
groupBoxes["_none_"].updateTitle();
// 2- add group to list of groups to be removed (unless it's a new group)
if (!groupBoxes[group_id].isNew)
groupsToDelete[group_id] = true;
if (!groupBoxes[group_id].isNew) groupsToDelete[group_id] = true;
// 3- delete objects and remove from DOM
var div = document.getElementById(group_id);
div.remove();
@ -231,14 +251,13 @@ function suppressGroup(group_id) {
updateginfo();
}
function renameGroup(group_id) {
// 1-- save modifications
if (groups_unsaved) {
alert("Enregistrez ou annulez vos changement avant !");
} else {
// 2- form rename
document.location = 'group_rename?group_id=' + group_id;
document.location = "group_rename?group_id=" + group_id;
}
}
@ -246,7 +265,7 @@ var createdGroupId = 0;
function newGroupId() {
var gid;
do {
gid = 'NG' + createdGroupId.toString();
gid = "NG" + createdGroupId.toString();
createdGroupId += 1;
} while (gid in groupBoxes);
return gid;
@ -259,13 +278,14 @@ function createGroup() {
alert("Nom de groupe vide !");
return false;
}
if (group_name.length >= 32) { // SHORT_STR_LEN
if (group_name.length >= 32) {
// SHORT_STR_LEN
alert("Nom de groupe trop long !");
return false;
}
// check name:
for (var group_id in groupBoxes) {
if (group_id != 'extend') {
if (group_id != "extend") {
if (groupBoxes[group_id].group_name == group_name) {
alert("Nom de groupe déja existant !");
return false;
@ -282,7 +302,7 @@ function createGroup() {
/* --- Etudiant draggable --- */
var CDraggableEtud = function (nom, prenom, sexe, origin, etudid) {
this.type = 'Custom';
this.type = "Custom";
this.name = etudid;
this.etudid = etudid;
this.nom = nom;
@ -292,11 +312,21 @@ var CDraggableEtud = function (nom, prenom, sexe, origin, etudid) {
this.createNode();
ETUDS[etudid] = this;
NbEtuds++;
}
};
$.extend(CDraggableEtud.prototype, {
repr: function () {
return this.sexe + ' ' + this.prenom + ' <span class="nom">' + this.nom + '</span> ' + '<b>' + this.origin + '</b>';
return (
this.sexe +
" " +
this.prenom +
' <span class="nom">' +
this.nom +
"</span> " +
"<b>" +
this.origin +
"</b>"
);
},
createNode: function () {
// Create DOM element for student
@ -311,10 +341,10 @@ $.extend(CDraggableEtud.prototype, {
e.innerHTML = this.repr();
// declare as draggable
$(e).draggable({
cursor: 'move',
stack: '#groups div',
containment: '#groups',
revert: 'invalid'
cursor: "move",
stack: "#groups div",
containment: "#groups",
revert: "invalid",
});
},
endDrag: function () {
@ -322,7 +352,7 @@ $.extend(CDraggableEtud.prototype, {
var p = el.parentNode;
// alert("endDrag: [" + this.name +"] " + p.id );
this.changeGroup(this.group_id, p.id);
this.htmlElement.style.fontStyle = 'italic'; // italic pour les etudiants deplaces
this.htmlElement.style.fontStyle = "italic"; // italic pour les etudiants deplaces
},
// Move a student from a group to another
changeGroup: function (oldGroupName, newGroupName) {
@ -337,55 +367,53 @@ $.extend(CDraggableEtud.prototype, {
}
var newGroupBox = groupBoxes[newGroupName];
newGroupBox.addEtudToGroup(this);
if (oldGroupBox)
oldGroupBox.removeEtud(this);
if (oldGroupBox) oldGroupBox.removeEtud(this);
groups_unsaved = true;
updatesavedinfo();
}
},
});
/* --- Upload du resultat --- */
function processResponse(value) {
location.reload(); // necessaire pour reinitialiser les id des groupes créés
}
function handleError(msg) {
alert('Error: ' + msg);
console.log('Error: ' + msg);
alert("Error: " + msg);
console.log("Error: " + msg);
}
function submitGroups() {
var url = SCO_URL + '/setGroups';
var url = SCO_URL + "/setGroups";
// build post request body: groupname \n etudid; ...
var groupsLists = '';
var groupsToCreate = '';
var groupsLists = "";
var groupsToCreate = "";
for (var group_id in groupBoxes) {
if (group_id != 'extend') { // je ne sais pas ce dont il s'agit ???
if (group_id != '_none_') { // ne renvoie pas le groupe des sans-groupes
if (group_id != "extend") {
// je ne sais pas ce dont il s'agit ???
if (group_id != "_none_") {
// ne renvoie pas le groupe des sans-groupes
groupBox = groupBoxes[group_id];
if (groupBox.isNew) {
groupsToCreate += groupBox.group_name + ';';
groupsToCreate += groupBox.group_name + ";";
for (var etudid in groupBox.etuds) {
if (etudid != 'extend')
groupsToCreate += etudid + ';';
if (etudid != "extend") groupsToCreate += etudid + ";";
}
groupsToCreate += '\n';
groupsToCreate += "\n";
groupBox.isNew = false; // is no more new !
} else {
groupsLists += group_id + ';';
groupsLists += group_id + ";";
for (var etudid in groupBox.etuds) {
if (etudid != 'extend')
groupsLists += etudid + ';';
if (etudid != "extend") groupsLists += etudid + ";";
}
groupsLists += '\n';
groupsLists += "\n";
}
}
}
}
var todel = '';
var todel = "";
for (var group_id in groupsToDelete) {
todel += group_id + ';';
todel += group_id + ";";
}
groupsToDelete = new Object(); // empty
var partition_id = document.formGroup.partition_id.value;
@ -394,7 +422,7 @@ function submitGroups() {
groupsLists: groupsLists,
partition_id: partition_id,
groupsToDelete: todel,
groupsToCreate: groupsToCreate
groupsToCreate: groupsToCreate,
})
.done(function (data) {
processResponse(data);
@ -413,45 +441,45 @@ function GotoAnother() {
if (groups_unsaved) {
alert("Enregistrez ou annulez vos changement avant !");
} else
document.location = SCO_URL + '/affect_groups?partition_id=' + document.formGroup.other_partition_id.value;
document.location =
SCO_URL +
"/affect_groups?partition_id=" +
document.formGroup.other_partition_id.value;
}
// Boite information haut de page
function updateginfo() {
var g = document.getElementById('ginfo');
var g = document.getElementById("ginfo");
var group_names = new Array();
for (var group_id in groupBoxes) {
if ((group_id != 'extend') && (groupBoxes[group_id].group_name)) {
if (group_id != "extend" && groupBoxes[group_id].group_name) {
group_names.push(groupBoxes[group_id].group_name);
}
}
g.innerHTML = '<b>Groupes définis: ' + group_names.join(', ') + '<br/>'
+ "Nombre d'etudiants: " + NbEtuds + '</b>';
g.innerHTML =
"<b>Groupes définis: " +
group_names.join(", ") +
"<br/>" +
"Nombre d'etudiants: " +
NbEtuds +
"</b>";
updatesavedinfo();
}
// Boite indiquant si modifications non enregistrees ou non
function updatesavedinfo() {
var g = document.getElementById('savedinfo');
var g = document.getElementById("savedinfo");
if (groups_unsaved) {
g.innerHTML = 'modifications non enregistrées';
g.style.visibility = 'visible';
g.innerHTML = "modifications non enregistrées";
g.style.visibility = "visible";
} else {
g.innerHTML = '';
g.style.visibility = 'hidden';
g.innerHTML = "";
g.style.visibility = "hidden";
}
return true;
}
$(function () {
loadGroupes();
});
/* debug:
var g = new CGroupBox('G0', 'Toto');
*/

View File

@ -2,6 +2,13 @@
{{ sco_header|safe }}
<h2 class="formsemestre">Affectation aux groupes de {{ partition.partition_name }}</h2>
<p class="help">
👉💡 vous pourriez essayer <a href="{{
url_for('scolar.partition_editor',
scodoc_dept=g.scodoc_dept, formsemestre_id=formsemestre_id)
}}" class="stdlink">le nouvel éditeur</a>
</p>
<p>Faites glisser les étudiants d'un groupe à l'autre. Les modifications ne
sont enregistrées que lorsque vous cliquez sur le bouton "<em>Enregistrer ces groupes</em>".
Vous pouvez créer de nouveaux groupes. Pour <em>supprimer</em> ou <em>renommer</em>

View File

@ -59,6 +59,9 @@
document.querySelector("body").classList.add("loaded");
document.querySelector('.wait').style.display = "none";
{% if edit_partition %}
setEditMode();
{% endif %}
}
function fetchData(request) {

View File

@ -907,8 +907,12 @@ sco_publish(
@scodoc
@permission_required(Permission.ScoView)
@scodoc7func
def partition_editor(formsemestre_id: int):
def partition_editor(formsemestre_id: int, edit_partition=False):
"""Page édition groupes et partitions
Si edit_partition, se met en mode édition des partitions.
"""
formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id)
edit_partition = bool(int(edit_partition)) if edit_partition else False
formsemestre.setup_parcours_groups()
H = [
html_sco_header.sco_header(
@ -928,6 +932,7 @@ def partition_editor(formsemestre_id: int):
read_only=not sco_groups.sco_permissions_check.can_change_groups(
formsemestre_id
),
edit_partition=edit_partition,
),
html_sco_header.sco_footer(),
]