forked from ScoDoc/ScoDoc
Assiduites : Modif Live + Toasts + filtre Liste
This commit is contained in:
parent
f10fd311e1
commit
da8b416785
@ -10,6 +10,10 @@
|
|||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#validate_selectors {
|
||||||
|
margin-top: 5vh;
|
||||||
|
}
|
||||||
|
|
||||||
.no-display {
|
.no-display {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
@ -246,6 +250,10 @@
|
|||||||
background-image: url(../icons/absent.svg);
|
background-image: url(../icons/absent.svg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.rbtn.aucun::before {
|
||||||
|
background-image: url(../icons/aucun.svg);
|
||||||
|
}
|
||||||
|
|
||||||
.rbtn.retard::before {
|
.rbtn.retard::before {
|
||||||
background-image: url(../icons/retard.svg);
|
background-image: url(../icons/retard.svg);
|
||||||
}
|
}
|
||||||
@ -498,3 +506,18 @@
|
|||||||
width: 75%;
|
width: 75%;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.order {
|
||||||
|
display: block;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
background-image: url(../icons/sort.svg);
|
||||||
|
outline: none;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order:focus {
|
||||||
|
outline: none;
|
||||||
|
border: none;
|
||||||
|
}
|
8
app/static/icons/aucun.svg
Executable file
8
app/static/icons/aucun.svg
Executable file
@ -0,0 +1,8 @@
|
|||||||
|
<svg width="85" height="85" viewBox="0 0 85 85" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect width="85" height="85" rx="15" fill="#BBB"/>
|
||||||
|
<defs>
|
||||||
|
<clipPath id="clip0_120_4425">
|
||||||
|
<rect width="56" height="56" fill="white" transform="matrix(1 0 0 -1 15 70)"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 291 B |
1
app/static/icons/sort.svg
Normal file
1
app/static/icons/sort.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M10 14H2m6-4H2m4-4H2m10 12H2m17 2V4m0 16l3-3m-3 3l-3-3m3-13l3 3m-3-3l-3 3"/></svg>
|
After Width: | Height: | Size: 274 B |
@ -20,17 +20,7 @@ let justificatifs = {};
|
|||||||
|
|
||||||
// Variable qui définit si le processus d'action de masse est lancé
|
// Variable qui définit si le processus d'action de masse est lancé
|
||||||
let currentMassAction = false;
|
let currentMassAction = false;
|
||||||
|
let currentMassActionEtat = undefined;
|
||||||
/**
|
|
||||||
* Variable de gestion des conflits
|
|
||||||
*/
|
|
||||||
let modal;
|
|
||||||
let closeBtn;
|
|
||||||
let timeline;
|
|
||||||
let deleteBtn;
|
|
||||||
let splitBtn;
|
|
||||||
let editBtn;
|
|
||||||
let selectedAssiduite;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ajout d'une fonction `capitalize` sur tous les strings
|
* Ajout d'une fonction `capitalize` sur tous les strings
|
||||||
@ -74,7 +64,7 @@ function setupCheckBox(parent = document) {
|
|||||||
* - Module impl
|
* - Module impl
|
||||||
* - Date
|
* - Date
|
||||||
*/
|
*/
|
||||||
function validateSelectors() {
|
function validateSelectors(btn) {
|
||||||
const action = () => {
|
const action = () => {
|
||||||
const group_ids = getGroupIds();
|
const group_ids = getGroupIds();
|
||||||
|
|
||||||
@ -113,6 +103,8 @@ function validateSelectors() {
|
|||||||
document.querySelector(".selectors").disabled = true;
|
document.querySelector(".selectors").disabled = true;
|
||||||
generateMassAssiduites();
|
generateMassAssiduites();
|
||||||
generateAllEtudRow();
|
generateAllEtudRow();
|
||||||
|
btn.remove();
|
||||||
|
onlyAbs();
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!verifyDateInSemester()) {
|
if (!verifyDateInSemester()) {
|
||||||
@ -133,6 +125,14 @@ function validateSelectors() {
|
|||||||
action();
|
action();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onlyAbs() {
|
||||||
|
if (getDate() > moment()) {
|
||||||
|
document
|
||||||
|
.querySelectorAll(".rbtn.present, .rbtn.retard")
|
||||||
|
.forEach((el) => el.remove());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Limite le nombre de checkbox marquée
|
* Limite le nombre de checkbox marquée
|
||||||
* Vérifie aussi si le cliqué est fait sur des assiduités conflictuelles
|
* Vérifie aussi si le cliqué est fait sur des assiduités conflictuelles
|
||||||
@ -287,6 +287,7 @@ function executeMassActionQueue() {
|
|||||||
console.error(data, status);
|
console.error(data, status);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
return createQueue.length;
|
||||||
};
|
};
|
||||||
|
|
||||||
//Fonction qui modifie les assiduités de la queue 'edition'
|
//Fonction qui modifie les assiduités de la queue 'edition'
|
||||||
@ -312,6 +313,7 @@ function executeMassActionQueue() {
|
|||||||
console.error(data, status);
|
console.error(data, status);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
return editQueue.length;
|
||||||
};
|
};
|
||||||
|
|
||||||
//Fonction qui supprime les assiduités de la queue 'supprimer'
|
//Fonction qui supprime les assiduités de la queue 'supprimer'
|
||||||
@ -328,12 +330,44 @@ function executeMassActionQueue() {
|
|||||||
console.error(data, status);
|
console.error(data, status);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
return toDelete.length;
|
||||||
};
|
};
|
||||||
|
|
||||||
//On exécute les fonctions de queue
|
//On exécute les fonctions de queue
|
||||||
create();
|
let color;
|
||||||
edit();
|
switch (currentMassActionEtat.toUpperCase()) {
|
||||||
supprimer();
|
case "PRESENT":
|
||||||
|
color = "#6bdb83";
|
||||||
|
break;
|
||||||
|
case "ABSENT":
|
||||||
|
color = "#F1A69C";
|
||||||
|
break;
|
||||||
|
case "RETARD":
|
||||||
|
color = "#f0c865";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
color = "#AAA";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
let count = 0;
|
||||||
|
if (currentMassActionEtat == "remove") {
|
||||||
|
count += supprimer();
|
||||||
|
const span = document.createElement("span");
|
||||||
|
span.innerHTML = `${count} assiduités ont été supprimées.`;
|
||||||
|
pushToast(generateToast(span, color, 5));
|
||||||
|
} else {
|
||||||
|
count += create();
|
||||||
|
count += edit();
|
||||||
|
const etat =
|
||||||
|
currentMassActionEtat.toUpperCase() == "RETARD"
|
||||||
|
? "En retard"
|
||||||
|
: currentMassActionEtat;
|
||||||
|
const span = document.createElement("span");
|
||||||
|
span.innerHTML = `${count} étudiants ont été mis <u><strong>${etat
|
||||||
|
.capitalize()
|
||||||
|
.trim()}</strong></u>`;
|
||||||
|
pushToast(generateToast(span, color, 5));
|
||||||
|
}
|
||||||
//On récupère les assiduités puis on regénère les lignes d'étudiants
|
//On récupère les assiduités puis on regénère les lignes d'étudiants
|
||||||
getAssiduitesFromEtuds(true);
|
getAssiduitesFromEtuds(true);
|
||||||
generateAllEtudRow();
|
generateAllEtudRow();
|
||||||
@ -346,7 +380,10 @@ function massAction() {
|
|||||||
//On récupère tous les boutons d'assiduités
|
//On récupère tous les boutons d'assiduités
|
||||||
const fields = Array.from(document.querySelectorAll(".btns_field.single"));
|
const fields = Array.from(document.querySelectorAll(".btns_field.single"));
|
||||||
//On récupère l'état de l'action de masse
|
//On récupère l'état de l'action de masse
|
||||||
const action = getAssiduiteValue(document.querySelector(".btns_field.mass"));
|
currentMassActionEtat = getAssiduiteValue(
|
||||||
|
document.querySelector(".btns_field.mass")
|
||||||
|
);
|
||||||
|
|
||||||
//On remet à 0 les queues
|
//On remet à 0 les queues
|
||||||
resetMassActionQueue();
|
resetMassActionQueue();
|
||||||
|
|
||||||
@ -366,7 +403,11 @@ function massAction() {
|
|||||||
*/
|
*/
|
||||||
fields.forEach((field) => {
|
fields.forEach((field) => {
|
||||||
if (field.getAttribute("type") != "conflit") {
|
if (field.getAttribute("type") != "conflit") {
|
||||||
field.querySelector(`.rbtn.${action}`).click();
|
if (currentMassActionEtat != "remove") {
|
||||||
|
field.querySelector(`.rbtn.${currentMassActionEtat}`).click();
|
||||||
|
} else {
|
||||||
|
field.querySelector(".rbtn.absent").click();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
const etudid = field.getAttribute("etudid");
|
const etudid = field.getAttribute("etudid");
|
||||||
conflicts.push(etuds[parseInt(etudid)]);
|
conflicts.push(etuds[parseInt(etudid)]);
|
||||||
@ -379,6 +420,7 @@ function massAction() {
|
|||||||
|
|
||||||
//Fin du processus, on remet à false
|
//Fin du processus, on remet à false
|
||||||
currentMassAction = false;
|
currentMassAction = false;
|
||||||
|
currentMassActionEtat = undefined;
|
||||||
|
|
||||||
//On remet à zero les boutons d'assiduité de masse
|
//On remet à zero les boutons d'assiduité de masse
|
||||||
const boxes = Array.from(
|
const boxes = Array.from(
|
||||||
@ -423,6 +465,7 @@ function generateMassAssiduites() {
|
|||||||
class="rbtn present">
|
class="rbtn present">
|
||||||
<input type="checkbox" value="retard" name="mass_btn_assiduites" id="mass_rbtn_retard" class="rbtn retard">
|
<input type="checkbox" value="retard" name="mass_btn_assiduites" id="mass_rbtn_retard" class="rbtn retard">
|
||||||
<input type="checkbox" value="absent" name="mass_btn_assiduites" id="mass_rbtn_absent" class="rbtn absent">
|
<input type="checkbox" value="absent" name="mass_btn_assiduites" id="mass_rbtn_absent" class="rbtn absent">
|
||||||
|
<input type="checkbox" value="remove" name="mass_btn_assiduites" id="mass_rbtn_aucun" class="rbtn aucun">
|
||||||
</fieldset>`;
|
</fieldset>`;
|
||||||
|
|
||||||
content.insertBefore(mass, content.querySelector(".etud_holder"));
|
content.insertBefore(mass, content.querySelector(".etud_holder"));
|
||||||
@ -953,7 +996,6 @@ function actualizeEtudAssiduite(etudid, has_formsemestre = true) {
|
|||||||
getUrl() +
|
getUrl() +
|
||||||
`/api/assiduites/${etudid}/query?${formsemestre_id}date_debut=${date_debut}&date_fin=${date_fin}`;
|
`/api/assiduites/${etudid}/query?${formsemestre_id}date_debut=${date_debut}&date_fin=${date_fin}`;
|
||||||
sync_get(url_api, (data, status) => {
|
sync_get(url_api, (data, status) => {
|
||||||
console.error(data, status);
|
|
||||||
if (status === "success") {
|
if (status === "success") {
|
||||||
assiduites[etudid] = data;
|
assiduites[etudid] = data;
|
||||||
}
|
}
|
||||||
@ -991,14 +1033,13 @@ function assiduiteAction(element) {
|
|||||||
|
|
||||||
// Cas de l'action de masse -> peuplement des queues
|
// Cas de l'action de masse -> peuplement des queues
|
||||||
if (currentMassAction) {
|
if (currentMassAction) {
|
||||||
|
if (currentMassActionEtat != "remove") {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case "création":
|
case "création":
|
||||||
addToMassActionQueue("creer", { etat: etat, etudid: etudid });
|
addToMassActionQueue("creer", { etat: etat, etudid: etudid });
|
||||||
break;
|
break;
|
||||||
case "édition":
|
case "édition":
|
||||||
if (etat === "remove") {
|
if (etat != "remove") {
|
||||||
addToMassActionQueue("supprimer", assiduite_id);
|
|
||||||
} else {
|
|
||||||
addToMassActionQueue("editer", {
|
addToMassActionQueue("editer", {
|
||||||
etat: etat,
|
etat: etat,
|
||||||
assiduite_id: assiduite_id,
|
assiduite_id: assiduite_id,
|
||||||
@ -1006,6 +1047,9 @@ function assiduiteAction(element) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
} else if (type == "édition") {
|
||||||
|
addToMassActionQueue("supprimer", assiduite_id);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Cas normal -> mise à jour en base
|
// Cas normal -> mise à jour en base
|
||||||
switch (type) {
|
switch (type) {
|
||||||
@ -1042,13 +1086,49 @@ function assiduiteAction(element) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (type != "conflit") {
|
if (type != "conflit") {
|
||||||
document
|
let etatAffiche;
|
||||||
.querySelector(".toast-holder")
|
|
||||||
.appendChild(
|
switch (etat.toUpperCase()) {
|
||||||
generateToast(
|
case "PRESENT":
|
||||||
document.createTextNode("L'assiduité a bien été enregistrée.")
|
etatAffiche =
|
||||||
)
|
"%etud% a été noté(e) <u><strong>présent(e)</strong></u>";
|
||||||
);
|
break;
|
||||||
|
case "RETARD":
|
||||||
|
etatAffiche =
|
||||||
|
"%etud% a été noté(e) <u><strong>en retard</strong></u>";
|
||||||
|
break;
|
||||||
|
case "ABSENT":
|
||||||
|
etatAffiche =
|
||||||
|
"%etud% a été noté(e) <u><strong>absent(e)</strong></u>";
|
||||||
|
break;
|
||||||
|
case "REMOVE":
|
||||||
|
etatAffiche = "L'assiduité de %etud% a été retirée.";
|
||||||
|
}
|
||||||
|
|
||||||
|
let color;
|
||||||
|
|
||||||
|
switch (etat.toUpperCase()) {
|
||||||
|
case "PRESENT":
|
||||||
|
color = "#6bdb83";
|
||||||
|
break;
|
||||||
|
case "ABSENT":
|
||||||
|
color = "#F1A69C";
|
||||||
|
break;
|
||||||
|
case "RETARD":
|
||||||
|
color = "#f0c865";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
color = "#AAA";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nom_prenom = `${etuds[etudid].nom.toUpperCase()} ${etuds[
|
||||||
|
etudid
|
||||||
|
].prenom.capitalize()}`;
|
||||||
|
const span = document.createElement("span");
|
||||||
|
span.innerHTML = etatAffiche.replace("%etud%", nom_prenom);
|
||||||
|
|
||||||
|
pushToast(generateToast(span, color, 5));
|
||||||
}
|
}
|
||||||
|
|
||||||
actualizeEtud(etudid, !isSingleEtud);
|
actualizeEtud(etudid, !isSingleEtud);
|
||||||
|
@ -692,6 +692,52 @@
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function launchToast(etudid, etat) {
|
||||||
|
let etatAffiche;
|
||||||
|
|
||||||
|
switch (etat.toUpperCase()) {
|
||||||
|
case "PRESENT":
|
||||||
|
etatAffiche =
|
||||||
|
"%etud% a été noté(e) <u><strong>présent(e)</strong></u>";
|
||||||
|
break;
|
||||||
|
case "RETARD":
|
||||||
|
etatAffiche =
|
||||||
|
"%etud% a été noté(e) <u><strong>en retard</strong></u>";
|
||||||
|
break;
|
||||||
|
case "ABSENT":
|
||||||
|
etatAffiche =
|
||||||
|
"%etud% a été noté(e) <u><strong>absent(e)</strong></u>";
|
||||||
|
break;
|
||||||
|
case "REMOVE":
|
||||||
|
etatAffiche = "L'assiduité de %etud% a été retirée.";
|
||||||
|
}
|
||||||
|
|
||||||
|
let color;
|
||||||
|
|
||||||
|
switch (etat.toUpperCase()) {
|
||||||
|
case "PRESENT":
|
||||||
|
color = "#6bdb83";
|
||||||
|
break;
|
||||||
|
case "ABSENT":
|
||||||
|
color = "#F1A69C";
|
||||||
|
break;
|
||||||
|
case "RETARD":
|
||||||
|
color = "#f0c865";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
color = "#AAA";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nom_prenom = `${etuds[etudid].nom.toUpperCase()} ${etuds[
|
||||||
|
etudid
|
||||||
|
].prenom.capitalize()}`;
|
||||||
|
const span = document.createElement("span");
|
||||||
|
span.innerHTML = etatAffiche.replace("%etud%", nom_prenom);
|
||||||
|
|
||||||
|
pushToast(generateToast(span, color, 5));
|
||||||
|
}
|
||||||
|
|
||||||
function updateEtudAssiduite(rbtn) {
|
function updateEtudAssiduite(rbtn) {
|
||||||
const [_, colid, etudid] = rbtn.name.split("_");
|
const [_, colid, etudid] = rbtn.name.split("_");
|
||||||
|
|
||||||
@ -714,8 +760,8 @@
|
|||||||
assiduite["assiduite_id"] = assi_id;
|
assiduite["assiduite_id"] = assi_id;
|
||||||
assiduites[etudid].push(assiduite);
|
assiduites[etudid].push(assiduite);
|
||||||
updateAllCol()
|
updateAllCol()
|
||||||
|
launchToast(etudid, etat);
|
||||||
|
|
||||||
// TODO Envoyer toast
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
break;
|
break;
|
||||||
@ -761,7 +807,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
asyncEditAssiduite(edit, (data) => {
|
asyncEditAssiduite(edit, (data) => {
|
||||||
console.log(data)
|
const obj = getAssiduite(etudid, assi);
|
||||||
|
|
||||||
|
obj.moduleimpl = edit.moduleimpl_id;
|
||||||
|
obj.etat = edit.etat;
|
||||||
|
|
||||||
|
launchToast(etudid, etat);
|
||||||
})
|
})
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -769,6 +820,10 @@
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getAssiduite(etudid, id) {
|
||||||
|
return assiduites[etudid].filter((a) => a.assiduite_id == id)
|
||||||
|
}
|
||||||
|
|
||||||
function asyncCreateAssiduite(assi, callback = () => { }) {
|
function asyncCreateAssiduite(assi, callback = () => { }) {
|
||||||
const path = getUrl() + `/api/assiduite/${assi.etudid}/create`;
|
const path = getUrl() + `/api/assiduite/${assi.etudid}/create`;
|
||||||
async_post(
|
async_post(
|
||||||
|
@ -10,11 +10,36 @@
|
|||||||
<table id="assiduiteTable">
|
<table id="assiduiteTable">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Début</th>
|
<th>
|
||||||
<th>Fin</th>
|
<div>
|
||||||
<th>État</th>
|
<span>Début</span>
|
||||||
<th>Module</th>
|
<a class="order" onclick="order('date_debut', assiduiteCallBack, this)"></a>
|
||||||
<th>Justifiée</th>
|
</div>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
<div>
|
||||||
|
<span>Fin</span>
|
||||||
|
<a class="order" onclick="order('date_fin', assiduiteCallBack, this)"></a>
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
<div>
|
||||||
|
<span>État</span>
|
||||||
|
<a class="order" onclick="order('etat', assiduiteCallBack, this)"></a>
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
<div>
|
||||||
|
<span>Module</span>
|
||||||
|
<a class="order" onclick="order('moduleimpl_id', assiduiteCallBack, this)"></a>
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
<div>
|
||||||
|
<span>Justifiée</span>
|
||||||
|
<a class="order" onclick="order('est_just', assiduiteCallBack, this)"></a>
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody id="tableBodyAssiduites">
|
<tbody id="tableBodyAssiduites">
|
||||||
@ -26,10 +51,30 @@
|
|||||||
<table id="justificatifTable">
|
<table id="justificatifTable">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Début</th>
|
<th>
|
||||||
<th>Fin</th>
|
<div>
|
||||||
<th>État</th>
|
<span>Début</span>
|
||||||
<th>Raison</th>
|
<a class="order" onclick="order('date_debut', justificatifCallBack, this, false)"></a>
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
<div>
|
||||||
|
<span>Fin</span>
|
||||||
|
<a class="order" onclick="order('date_fin', justificatifCallBack, this, false)"></a>
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
<div>
|
||||||
|
<span>État</span>
|
||||||
|
<a class="order" onclick="order('etat', justificatifCallBack, this, false)"></a>
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
<div>
|
||||||
|
<span>Raison</span>
|
||||||
|
<a class="order" onclick="order('raison', justificatifCallBack, this, false)"></a>
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody id="tableBodyJustificatifs">
|
<tbody id="tableBodyJustificatifs">
|
||||||
@ -70,6 +115,7 @@
|
|||||||
|
|
||||||
th {
|
th {
|
||||||
background-color: #f2f2f2;
|
background-color: #f2f2f2;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tr:hover {
|
tr:hover {
|
||||||
@ -138,6 +184,12 @@
|
|||||||
color: #fff;
|
color: #fff;
|
||||||
border-color: #007bff;
|
border-color: #007bff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
th>div {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@ -147,6 +199,8 @@
|
|||||||
const itemsPerPage = 10;
|
const itemsPerPage = 10;
|
||||||
let currentPageAssiduites = 1;
|
let currentPageAssiduites = 1;
|
||||||
let currentPageJustificatifs = 1;
|
let currentPageJustificatifs = 1;
|
||||||
|
let orderAssiduites = true;
|
||||||
|
let orderJustificatifs = true;
|
||||||
|
|
||||||
const tableBodyAssiduites = document.getElementById("tableBodyAssiduites");
|
const tableBodyAssiduites = document.getElementById("tableBodyAssiduites");
|
||||||
const tableBodyJustificatifs = document.getElementById("tableBodyJustificatifs");
|
const tableBodyJustificatifs = document.getElementById("tableBodyJustificatifs");
|
||||||
@ -184,6 +238,33 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function assiduiteCallBack(assi) {
|
||||||
|
renderTableAssiduites(currentPageAssiduites, assi);
|
||||||
|
renderPaginationButtons(assi);
|
||||||
|
}
|
||||||
|
function justificatifCallBack(justi) {
|
||||||
|
renderTableJustificatifs(currentPageJustificatifs, justi);
|
||||||
|
renderPaginationButtons(justi, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
const moduleimpls = {}
|
||||||
|
|
||||||
|
function getModuleImpl(id) {
|
||||||
|
if (id == null || id == undefined) {
|
||||||
|
moduleimpls[id] = "Pas de module"
|
||||||
|
}
|
||||||
|
if (id in moduleimpls) {
|
||||||
|
return moduleimpls[id];
|
||||||
|
}
|
||||||
|
const url_api = getUrl() + `/api/moduleimpl/${id}`;
|
||||||
|
sync_get(url_api, (data) => {
|
||||||
|
moduleimpls[id] = `${data.module.code} ${data.module.abbrev}`;
|
||||||
|
}, (data) => { moduleimpls[id] = "Pas de module" });
|
||||||
|
|
||||||
|
return moduleimpls[id];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
function renderTableAssiduites(page, assiduités) {
|
function renderTableAssiduites(page, assiduités) {
|
||||||
tableBodyAssiduites.innerHTML = "";
|
tableBodyAssiduites.innerHTML = "";
|
||||||
const start = (page - 1) * itemsPerPage;
|
const start = (page - 1) * itemsPerPage;
|
||||||
@ -198,10 +279,10 @@
|
|||||||
row.classList.add(etat);
|
row.classList.add(etat);
|
||||||
|
|
||||||
row.innerHTML = `
|
row.innerHTML = `
|
||||||
<td>${new Date(assiduite.date_debut).toLocaleString()}</td>
|
<td>${moment.tz(assiduite.date_debut, TIMEZONE).format(`DD/MM/Y HH:mm`)}</td>
|
||||||
<td>${new Date(assiduite.date_fin).toLocaleString()}</td>
|
<td>${moment.tz(assiduite.date_fin, TIMEZONE).format(`DD/MM/Y HH:mm`)}</td>
|
||||||
<td>${etat}</td>
|
<td>${etat}</td>
|
||||||
<td>${assiduite.moduleimpl_id}</td> <td>${assiduite.est_just ? "Oui" : "Non"
|
<td>${getModuleImpl(assiduite.moduleimpl_id)}</td> <td>${assiduite.est_just ? "Oui" : "Non"
|
||||||
}</td>
|
}</td>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@ -267,6 +348,10 @@
|
|||||||
paginationContainerJustificatifs.innerHTML = ""
|
paginationContainerJustificatifs.innerHTML = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (totalPages == 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (let i = 1; i <= totalPages; i++) {
|
for (let i = 1; i <= totalPages; i++) {
|
||||||
const paginationButton = document.createElement("a");
|
const paginationButton = document.createElement("a");
|
||||||
paginationButton.textContent = i;
|
paginationButton.textContent = i;
|
||||||
@ -312,15 +397,47 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function loadAll() {
|
function loadAll() {
|
||||||
getAllAssiduitesFromEtud(etudid, (assi) => {
|
getAllAssiduitesFromEtud(etudid, assiduiteCallBack)
|
||||||
renderTableAssiduites(currentPageAssiduites, assi);
|
|
||||||
renderPaginationButtons(assi), true;
|
getAllJustificatifsFromEtud(etudid, justificatifCallBack)
|
||||||
})
|
}
|
||||||
|
|
||||||
|
function order(keyword, callback = () => { }, el, assi = true) {
|
||||||
|
const call = (array) => {
|
||||||
|
const sorted = array.sort((a, b) => {
|
||||||
|
let keyValueA = a[keyword];
|
||||||
|
let keyValueB = b[keyword];
|
||||||
|
|
||||||
|
if (keyword.indexOf("date") != -1) {
|
||||||
|
keyValueA = moment.tz(keyValueA, TIMEZONE)
|
||||||
|
keyValueB = moment.tz(keyValueB, TIMEZONE)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keyword.indexOf("module") != -1) {
|
||||||
|
keyValueA = getModuleImpl(keyValueA);
|
||||||
|
keyValueB = getModuleImpl(keyValueB);
|
||||||
|
}
|
||||||
|
|
||||||
|
let orderDertermined = keyValueA > keyValueB;
|
||||||
|
|
||||||
|
if (el.classList.contains("desc")) {
|
||||||
|
orderDertermined = keyValueA < keyValueB;
|
||||||
|
}
|
||||||
|
return orderDertermined
|
||||||
|
});
|
||||||
|
|
||||||
|
el.classList.toggle("desc");
|
||||||
|
|
||||||
|
callback(sorted);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
if (assi) {
|
||||||
|
getAllAssiduitesFromEtud(etudid, call)
|
||||||
|
} else {
|
||||||
|
getAllJustificatifsFromEtud(etudid, call)
|
||||||
|
}
|
||||||
|
|
||||||
getAllJustificatifsFromEtud(etudid, (assi) => {
|
|
||||||
renderTableJustificatifs(currentPageJustificatifs, assi);
|
|
||||||
renderPaginationButtons(assi, false);
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
window.onload = () => {
|
window.onload = () => {
|
||||||
|
@ -71,7 +71,8 @@
|
|||||||
setupDate(() => {
|
setupDate(() => {
|
||||||
if (updateDate()) {
|
if (updateDate()) {
|
||||||
actualizeEtud(etudid);
|
actualizeEtud(etudid);
|
||||||
updateSelect()
|
updateSelect();
|
||||||
|
onlyAbs();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -98,11 +99,6 @@
|
|||||||
window.forceModule = "{{ forcer_module }}"
|
window.forceModule = "{{ forcer_module }}"
|
||||||
window.forceModule = window.forceModule == "True" ? true : false
|
window.forceModule = window.forceModule == "True" ? true : false
|
||||||
|
|
||||||
window.addEventListener('load', function () {
|
|
||||||
loading();
|
|
||||||
}, { once: true });
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,14 +22,14 @@
|
|||||||
Date: <span id="datestr"></span>
|
Date: <span id="datestr"></span>
|
||||||
<input type="date" name="tl_date" id="tl_date" value="{{ date }}" onchange="updateDate()">
|
<input type="date" name="tl_date" id="tl_date" value="{{ date }}" onchange="updateDate()">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button id="validate_selectors" onclick="validateSelectors()">
|
|
||||||
Valider
|
|
||||||
</button>
|
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
{{timeline|safe}}
|
{{timeline|safe}}
|
||||||
|
|
||||||
|
<button id="validate_selectors" onclick="validateSelectors(this)">
|
||||||
|
Faire la saisie
|
||||||
|
</button>
|
||||||
|
|
||||||
<div class="etud_holder">
|
<div class="etud_holder">
|
||||||
<p class="placeholder">
|
<p class="placeholder">
|
||||||
Veillez à choisir le groupe concerné par la saisie ainsi que la date de la saisie.
|
Veillez à choisir le groupe concerné par la saisie ainsi que la date de la saisie.
|
||||||
@ -77,5 +77,23 @@
|
|||||||
window.forceModule = "{{ forcer_module }}"
|
window.forceModule = "{{ forcer_module }}"
|
||||||
window.forceModule = window.forceModule == "True" ? true : false
|
window.forceModule = window.forceModule == "True" ? true : false
|
||||||
|
|
||||||
|
if (window.forceModule) {
|
||||||
|
const btn = document.getElementById("validate_selectors");
|
||||||
|
|
||||||
|
const select = document.getElementById("moduleimpl_select");
|
||||||
|
|
||||||
|
if (select.value == "") {
|
||||||
|
btn.disabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
select.addEventListener('change', (e) => {
|
||||||
|
if (e.target.value != "") {
|
||||||
|
btn.disabled = false;
|
||||||
|
} else {
|
||||||
|
btn.disabled = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
</section>
|
</section>
|
@ -2,6 +2,7 @@
|
|||||||
<div class="period" style="left: 0%; width: 20%">
|
<div class="period" style="left: 0%; width: 20%">
|
||||||
<div class="period-handle left"></div>
|
<div class="period-handle left"></div>
|
||||||
<div class="period-handle right"></div>
|
<div class="period-handle right"></div>
|
||||||
|
<div class="period-time">Time</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
@ -77,6 +78,15 @@
|
|||||||
return Math.round(value * tick_time) / tick_time;
|
return Math.round(value * tick_time) / tick_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updatePeriodTimeLabel() {
|
||||||
|
const values = getPeriodValues();
|
||||||
|
const deb = numberToTime(values[0])
|
||||||
|
const fin = numberToTime(values[1])
|
||||||
|
const text = `${deb} - ${fin}`
|
||||||
|
periodTimeLine.querySelector('.period-time').textContent = text;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
function setupTimeLine(callback) {
|
function setupTimeLine(callback) {
|
||||||
const func_call = callback ? callback : () => { };
|
const func_call = callback ? callback : () => { };
|
||||||
timelineContainer.addEventListener("mousedown", (event) => {
|
timelineContainer.addEventListener("mousedown", (event) => {
|
||||||
@ -91,6 +101,8 @@
|
|||||||
const newLeft = startLeft + (deltaX / containerWidth) * 100;
|
const newLeft = startLeft + (deltaX / containerWidth) * 100;
|
||||||
|
|
||||||
adjustPeriodPosition(newLeft, parseFloat(periodTimeLine.style.width));
|
adjustPeriodPosition(newLeft, parseFloat(periodTimeLine.style.width));
|
||||||
|
|
||||||
|
updatePeriodTimeLabel();
|
||||||
};
|
};
|
||||||
|
|
||||||
document.addEventListener("mousemove", onMouseMove);
|
document.addEventListener("mousemove", onMouseMove);
|
||||||
@ -121,6 +133,8 @@
|
|||||||
} else {
|
} else {
|
||||||
adjustPeriodPosition(parseFloat(periodTimeLine.style.left), newWidth);
|
adjustPeriodPosition(parseFloat(periodTimeLine.style.left), newWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updatePeriodTimeLabel();
|
||||||
};
|
};
|
||||||
|
|
||||||
document.addEventListener("mousemove", onMouseMove);
|
document.addEventListener("mousemove", onMouseMove);
|
||||||
@ -187,6 +201,7 @@
|
|||||||
|
|
||||||
snapHandlesToQuarters();
|
snapHandlesToQuarters();
|
||||||
generateAllEtudRow();
|
generateAllEtudRow();
|
||||||
|
updatePeriodTimeLabel()
|
||||||
}
|
}
|
||||||
|
|
||||||
function snapHandlesToQuarters() {
|
function snapHandlesToQuarters() {
|
||||||
@ -204,6 +219,8 @@
|
|||||||
const width = `${wid}%`
|
const width = `${wid}%`
|
||||||
periodTimeLine.style.left = left;
|
periodTimeLine.style.left = left;
|
||||||
periodTimeLine.style.width = width;
|
periodTimeLine.style.width = width;
|
||||||
|
|
||||||
|
updatePeriodTimeLabel()
|
||||||
}
|
}
|
||||||
|
|
||||||
function computePercentage(a, b) {
|
function computePercentage(a, b) {
|
||||||
@ -273,4 +290,23 @@
|
|||||||
right: 0;
|
right: 0;
|
||||||
border-radius: 4px 0 0 4px;
|
border-radius: 4px 0 0 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.period .period-time {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
left: calc(50% - var(--w)/2 - 5px);
|
||||||
|
justify-content: center;
|
||||||
|
align-content: center;
|
||||||
|
top: calc(-60% - 10px);
|
||||||
|
--w: 10em;
|
||||||
|
width: var(--w);
|
||||||
|
}
|
||||||
|
|
||||||
|
.period:hover .period-time {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
background-color: rgba(0, 183, 255, 1);
|
||||||
|
border-radius: 15px;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
@ -83,6 +83,14 @@
|
|||||||
return toast
|
return toast
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function pushToast(toast) {
|
||||||
|
document
|
||||||
|
.querySelector(".toast-holder")
|
||||||
|
.appendChild(
|
||||||
|
toast
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user