forked from ScoDoc/ScoDoc
Assiduité : signal_assiduites_diff : sauvegarde auto + historique action WIP
This commit is contained in:
parent
63f21c2dd6
commit
89dbac2514
|
@ -132,8 +132,238 @@
|
||||||
<script src="{{scu.STATIC_DIR}}/js/date_utils.js"></script>
|
<script src="{{scu.STATIC_DIR}}/js/date_utils.js"></script>
|
||||||
{% include "sco_timepicker.j2" %}
|
{% include "sco_timepicker.j2" %}
|
||||||
|
|
||||||
<script>
|
|
||||||
|
|
||||||
|
{# Gestion de l'historique #}
|
||||||
|
<script>
|
||||||
|
/**
|
||||||
|
* Enregistre une action dans l'historique
|
||||||
|
* @param {string} action - L'action à enregistrer
|
||||||
|
* @param {Object} data - Les données associées à l'action
|
||||||
|
*/
|
||||||
|
function recordAction(action, data) {
|
||||||
|
historyStack.push({ action: action, data: data });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Permet de revenir en arrière sur la dernière action
|
||||||
|
*/
|
||||||
|
function revertAction() {
|
||||||
|
const lastAction = historyStack.pop();
|
||||||
|
if (lastAction) {
|
||||||
|
switch (lastAction.action) {
|
||||||
|
case "create":
|
||||||
|
deleteAssiduite(lastAction.data, false);
|
||||||
|
break;
|
||||||
|
case "delete":
|
||||||
|
createAssiduite(lastAction.data, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// On met à jour l'affichage
|
||||||
|
updateCell(
|
||||||
|
lastAction.data.periodId,
|
||||||
|
lastAction.data.etudid,
|
||||||
|
lastAction.action == "create" ? null : lastAction.data.assiduite_id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Permet de vider l'historique
|
||||||
|
*/
|
||||||
|
function clearHistory() {
|
||||||
|
historyStack = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('keyup', (event) => {
|
||||||
|
if (event.ctrlKey && event.key === 'z') {
|
||||||
|
revertAction();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let historyStack = [];
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{# Gestion des actions d'assiduité #}
|
||||||
|
<script>
|
||||||
|
/**
|
||||||
|
* Permet de générer un nouvel objet assiduité à partir du plageId, etudid et etat
|
||||||
|
* @param {int} plageId - L'id de la plage
|
||||||
|
* @param {int} etudid - L'id de l'étudiant
|
||||||
|
* @param {string} etat - L'état de l'assiduité (present, retard, absent)
|
||||||
|
*/
|
||||||
|
function generateNewAssiduite(plageId, etudid, etat) {
|
||||||
|
const periode = periodes.get(plageId);
|
||||||
|
if (!periode) return;
|
||||||
|
return {
|
||||||
|
etudid: etudid,
|
||||||
|
etat: etat,
|
||||||
|
date_debut: periode.date_debut.toFakeIso(),
|
||||||
|
date_fin: periode.date_fin.toFakeIso(),
|
||||||
|
moduleimpl_id: periode.moduleimpl_id,
|
||||||
|
periodId: plageId,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Permet de récuppérer une assiduité à partir de son assiduite_id
|
||||||
|
* @param {int} assiduite_id
|
||||||
|
* Retourne une promise
|
||||||
|
*/
|
||||||
|
async function getAssiduite(assiduite_id) {
|
||||||
|
return await fetch(`../../api/assiduite/${assiduite_id}`, {
|
||||||
|
method: "GET",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
if (!res.ok) {
|
||||||
|
throw new Error("Network response was not ok");
|
||||||
|
}
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
return data;
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error("Error:", error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Crée une nouvelle assiduité.
|
||||||
|
*
|
||||||
|
* @param {Object} newAssiduite - Les informations de la nouvelle assiduité.
|
||||||
|
* @param {boolean} [record=true] - Indique si l'action doit être enregistrée.
|
||||||
|
* @returns {Promise<void>} - Une promesse qui se résout lorsque la création de l'assiduité est terminée.
|
||||||
|
*/
|
||||||
|
async function createAssiduite(newAssiduite, record = true) {
|
||||||
|
if (!newAssiduite) return;
|
||||||
|
|
||||||
|
await async_post(
|
||||||
|
`../../api/assiduite/${newAssiduite.etudid}/create`,
|
||||||
|
[newAssiduite],
|
||||||
|
(data) => {
|
||||||
|
if (data.success.length > 0) {
|
||||||
|
newAssiduite.assiduite_id = data.success[0].message.assiduite_id;
|
||||||
|
|
||||||
|
// On enregistre l'action si elle est réussie
|
||||||
|
if (record) recordAction("create", newAssiduite);
|
||||||
|
} else {
|
||||||
|
console.error(data.errors["0"].message);
|
||||||
|
erreurModuleImpl(data.errors["0"].message);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
console.error("Erreur lors de la création de l'assiduité", error);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Supprime une assiduité.
|
||||||
|
*
|
||||||
|
* @param {Object} assiduite - L'assiduité à supprimer.
|
||||||
|
* @param {boolean} [record=true] - Indique si l'action de suppression doit être enregistrée.
|
||||||
|
* @returns {Promise<void>} - Une promesse qui se résout lorsque la suppression est terminée.
|
||||||
|
*/
|
||||||
|
async function deleteAssiduite(assiduite, record = true) {
|
||||||
|
if (!assiduite) return;
|
||||||
|
await async_post(
|
||||||
|
`../../api/assiduite/delete`,
|
||||||
|
[assiduite.assiduite_id],
|
||||||
|
(data) => {
|
||||||
|
if (data.success.length > 0) {
|
||||||
|
// On enregistre l'action si elle est réussie
|
||||||
|
if (record) recordAction("delete", assiduite);
|
||||||
|
} else {
|
||||||
|
console.error(data.errors["0"].message);
|
||||||
|
erreurModuleImpl(data.errors["0"].message);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
console.error("Erreur lors de la suppression de l'assiduité", error);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Crée une action d'assiduité.
|
||||||
|
*
|
||||||
|
* @param {string} plageId - L'identifiant de la plage horaire.
|
||||||
|
* @param {string} etudid - L'identifiant de l'étudiant.
|
||||||
|
* @param {string} etat - L'état de l'assiduité.
|
||||||
|
* @returns {Promise<void>} Une promesse qui se résout lorsque l'assiduité est créée avec succès.
|
||||||
|
*/
|
||||||
|
async function createAssiduiteAction(plageId, etudid, etat) {
|
||||||
|
// création de l'assiduité
|
||||||
|
const newAssiduite = generateNewAssiduite(plageId, etudid, etat);
|
||||||
|
await createAssiduite(newAssiduite);
|
||||||
|
|
||||||
|
updateCell(plageId, etudid, newAssiduite.assiduite_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Met à jour une cellule du tableau
|
||||||
|
*
|
||||||
|
* @param {string} plageId - L'identifiant de la plage horaire.
|
||||||
|
* @param {string} etudid - L'identifiant de l'étudiant.
|
||||||
|
* @param {string|null} assiduite_id - L'identifiant de l'assiduité (facultatif).
|
||||||
|
*/
|
||||||
|
function updateCell(plageId, etudid, assiduite_id = null) {
|
||||||
|
// Vérifie si la plage horaire existe
|
||||||
|
if (!periodes.has(plageId)) return;
|
||||||
|
|
||||||
|
// Mise à jour de la cellule
|
||||||
|
const cell = document.querySelector(`#cell-${etudid}-${plageId}`);
|
||||||
|
|
||||||
|
if (!cell) return;
|
||||||
|
|
||||||
|
cell.innerHTML = "";
|
||||||
|
|
||||||
|
if (assiduite_id) {
|
||||||
|
// Récupère les informations de l'assiduité
|
||||||
|
getAssiduite(assiduite_id).then((data) => {
|
||||||
|
setupAssiduiteBubble(cell, data);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const etats = ["retard", "absent"];
|
||||||
|
const assi_btns = document.createElement("div");
|
||||||
|
assi_btns.classList.add("assi-btns");
|
||||||
|
|
||||||
|
if (!window.nonPresent) {
|
||||||
|
etats.splice(0, 0, "present");
|
||||||
|
}
|
||||||
|
|
||||||
|
etats.forEach((value) => {
|
||||||
|
const cbox = document.createElement("input");
|
||||||
|
cbox.type = "checkbox";
|
||||||
|
cbox.value = value;
|
||||||
|
cbox.name = `rbtn_${etudid}_${plageId}`;
|
||||||
|
cbox.classList.add("rbtn", value);
|
||||||
|
|
||||||
|
// Événement pour s'assurer qu'un seul bouton est coché à la fois
|
||||||
|
cbox.addEventListener("click", (event) => {
|
||||||
|
const parent = event.target.parentElement;
|
||||||
|
parent.querySelectorAll(".rbtn").forEach((ele) => {
|
||||||
|
if (ele.value != value) {
|
||||||
|
ele.checked = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
createAssiduiteAction(plageId, etudid, value);
|
||||||
|
});
|
||||||
|
|
||||||
|
assi_btns.appendChild(cbox);
|
||||||
|
});
|
||||||
|
cell.appendChild(assi_btns);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
{# Gestion des plages et MAIN #}
|
||||||
|
<script>
|
||||||
/**
|
/**
|
||||||
* Permet d'ajouter une nouvelle période au tableau
|
* Permet d'ajouter une nouvelle période au tableau
|
||||||
* Par défaut la période est générèe avec les valeurs des inputs
|
* Par défaut la période est générèe avec les valeurs des inputs
|
||||||
|
@ -308,8 +538,8 @@ async function nouvellePeriode(period = null) {
|
||||||
// Si l'étudiant n'a pas d'assiduité, on crée les boutons assiduité
|
// Si l'étudiant n'a pas d'assiduité, on crée les boutons assiduité
|
||||||
if (assiduites.length == 0) {
|
if (assiduites.length == 0) {
|
||||||
|
|
||||||
const assi_btns = document.createElement('div');
|
const assi_btns = document.createElement('div');
|
||||||
assi_btns.classList.add('assi-btns');
|
assi_btns.classList.add('assi-btns');
|
||||||
const etats = ["retard", "absent"];
|
const etats = ["retard", "absent"];
|
||||||
|
|
||||||
if(!window.nonPresent){
|
if(!window.nonPresent){
|
||||||
|
@ -331,9 +561,8 @@ async function nouvellePeriode(period = null) {
|
||||||
ele.checked = false;
|
ele.checked = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
createAssiduiteAction(periodId,etudid, value);
|
||||||
});
|
});
|
||||||
// Si une valeur par défaut est donnée alors on l'applique
|
|
||||||
cbox.checked = etatDef.value == value;
|
|
||||||
|
|
||||||
assi_btns.appendChild(cbox);
|
assi_btns.appendChild(cbox);
|
||||||
});
|
});
|
||||||
|
@ -606,6 +835,18 @@ window.addEventListener("load", main);
|
||||||
|
|
||||||
<button id="add_periode" onclick="nouvellePeriode()">Ajouter une plage</button>
|
<button id="add_periode" onclick="nouvellePeriode()">Ajouter une plage</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="box">
|
||||||
|
|
||||||
|
<p>Cette page enregistre automatiquement la saisie effectuée.</p>
|
||||||
|
<p>La page enregistre un historique des dernières saisies.
|
||||||
|
<br>En cas d'erreur, appuyez sur le bouton "Annuler"
|
||||||
|
<br>ou appuyez sur "Ctrl + Z" pour annuler la dernière saisie.
|
||||||
|
</p>
|
||||||
|
<p>Vous pouvez également vider l'historique en appuyant sur le bouton "Vider l'historique".</p>
|
||||||
|
<button onclick="revertAction()">Annuler la dernière saisie</button>
|
||||||
|
<button onclick="clearHistory()">Vider l'historique</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- Boutons d'actions
|
<!-- Boutons d'actions
|
||||||
- Sauvegarder
|
- Sauvegarder
|
||||||
|
@ -614,13 +855,12 @@ window.addEventListener("load", main);
|
||||||
--->
|
--->
|
||||||
<br>
|
<br>
|
||||||
<div id="actions" class="flex">
|
<div id="actions" class="flex">
|
||||||
<button id="save" onclick="sauvegarderAssiduites()">ENREGISTRER</button>
|
|
||||||
<label for="pdp">
|
<label for="pdp">
|
||||||
Photo de profil :
|
Photo de profil :
|
||||||
<input type="checkbox" name="pdp" id="pdp" checked onclick="afficherPDP(this.checked)">
|
<input type="checkbox" name="pdp" id="pdp" checked onclick="afficherPDP(this.checked)">
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label for="etatDef">
|
{# <label for="etatDef">
|
||||||
Intialiser les étudiants comme :
|
Intialiser les étudiants comme :
|
||||||
<select name="etatDef" id="etatDef">
|
<select name="etatDef" id="etatDef">
|
||||||
<option value="">-</option>
|
<option value="">-</option>
|
||||||
|
@ -630,7 +870,7 @@ window.addEventListener("load", main);
|
||||||
<option value="retard">en retard</option>
|
<option value="retard">en retard</option>
|
||||||
<option value="absent">absents</option>
|
<option value="absent">absents</option>
|
||||||
</select>
|
</select>
|
||||||
</label>
|
</label> #}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user