forked from ScoDoc/ScoDoc
3e1f563ecd
- - duplication const - + bouton justifier `ajout_assiduite_etud` - + auto actualiser `signal_assiduite_group` - - enum au lieu de str - + mettre css minitimeline.css - + resize timeline fix
188 lines
6.6 KiB
Django/Jinja
188 lines
6.6 KiB
Django/Jinja
<div class="assiduite-bubble">
|
|
|
|
</div>
|
|
|
|
<script>
|
|
|
|
const mt_start = {{ t_start }};
|
|
const mt_end = {{ t_end }};
|
|
/**
|
|
* Création de la minitiline d'un étudiant
|
|
* @param {Array[Assiduité]} assiduitesArray
|
|
* @returns {HTMLElement} l'élément correspondant à la mini timeline
|
|
*/
|
|
function createMiniTimeline(assiduitesArray, day = null) {
|
|
const array = [...assiduitesArray];
|
|
const date = day == null ? getDate() : new Date(day);
|
|
const timeline = document.createElement("div");
|
|
timeline.className = "mini-timeline";
|
|
if (isSingleEtud()) {
|
|
timeline.classList.add("single");
|
|
}
|
|
const timelineDate = date.startOf("day");
|
|
const dayStart = timelineDate.clone().add(mt_start, "hours");
|
|
const dayEnd = timelineDate.clone().add(mt_end, "hours");
|
|
const dayDuration = new Duration(dayStart, dayEnd).minutes;
|
|
|
|
timeline.appendChild(setMiniTick(timelineDate, dayStart, dayDuration));
|
|
|
|
|
|
|
|
if (day == null) {
|
|
const tlTimes = getTimeLineTimes();
|
|
array.push({
|
|
date_debut: tlTimes.deb.format(),
|
|
date_fin: tlTimes.fin.format(),
|
|
etat: "CRENEAU",
|
|
});
|
|
|
|
}
|
|
|
|
array.forEach((assiduité) => {
|
|
if(assiduité.etat == "CRENEAU" && readOnly) return;
|
|
let startDate = new Date(Date.removeUTC(assiduité.date_debut));
|
|
let endDate = new Date(Date.removeUTC(assiduité.date_fin));
|
|
if (startDate.isBefore(dayStart)) {
|
|
startDate = dayEnd.clone().startOf("day").add(mt_start, "hours");
|
|
}
|
|
|
|
if (endDate.isAfter(dayEnd)) {
|
|
endDate = dayEnd.clone().startOf("day").add(mt_end, "hours");
|
|
}
|
|
|
|
const block = document.createElement("div");
|
|
block.className = "mini-timeline-block";
|
|
const duration = (new Duration(startDate, endDate)).minutes;
|
|
const startOffset = (new Duration(dayStart, startDate)).minutes;
|
|
const leftPercentage = (startOffset / dayDuration) * 100;
|
|
const widthPercentage = (duration / dayDuration) * 100;
|
|
|
|
|
|
block.style.left = `${leftPercentage}%`;
|
|
block.style.width = `${widthPercentage}%`;
|
|
|
|
if (assiduité.etat != "CRENEAU") {
|
|
block.addEventListener("click", () => {
|
|
let deb = startDate.getHours() + startDate.getMinutes() / 60;
|
|
let fin = endDate.getHours() + endDate.getMinutes() / 60;
|
|
deb = Math.max(mt_start, deb);
|
|
fin = Math.min(mt_end, fin);
|
|
|
|
if (day == null) setPeriodValues(deb, fin);
|
|
if (isSingleEtud()) {
|
|
updateSelectedSelect(getCurrentAssiduiteModuleImplId());
|
|
updateJustifyBtn();
|
|
}
|
|
});
|
|
//ajouter affichage assiduites on over
|
|
setupAssiduiteBuble(block, assiduité);
|
|
}
|
|
|
|
const action = (justificatifs) => {
|
|
if (justificatifs.length > 0) {
|
|
let j = "invalid_justified";
|
|
|
|
justificatifs.forEach((ju) => {
|
|
if (ju.etat == "VALIDE") {
|
|
j = "justified";
|
|
}
|
|
});
|
|
|
|
block.classList.add(j);
|
|
}
|
|
};
|
|
|
|
if (assiduité.etudid) {
|
|
getJustificatifFromPeriod(
|
|
{
|
|
deb: new Date(assiduité.date_debut),
|
|
fin: new Date(assiduité.date_fin),
|
|
},
|
|
assiduité.etudid,
|
|
action
|
|
);
|
|
}
|
|
|
|
switch (assiduité.etat) {
|
|
case "PRESENT":
|
|
block.classList.add("present");
|
|
break;
|
|
case "RETARD":
|
|
block.classList.add("retard");
|
|
break;
|
|
case "ABSENT":
|
|
block.classList.add("absent");
|
|
break;
|
|
case "CRENEAU":
|
|
block.classList.add("creneau");
|
|
break;
|
|
default:
|
|
block.style.backgroundColor = "white";
|
|
}
|
|
|
|
timeline.appendChild(block);
|
|
});
|
|
|
|
return timeline;
|
|
}
|
|
|
|
/**
|
|
* Ajout de la visualisation des assiduités de la mini timeline
|
|
* @param {HTMLElement} el l'élément survollé
|
|
* @param {Assiduité} assiduite l'assiduité représentée par l'élément
|
|
*/
|
|
function setupAssiduiteBuble(el, assiduite) {
|
|
if (!assiduite) return;
|
|
|
|
const bubble = document.createElement('div');
|
|
bubble.className = "assiduite-bubble";
|
|
bubble.classList.add(assiduite.etat.toLowerCase());
|
|
|
|
const idDiv = document.createElement("div");
|
|
idDiv.className = "assiduite-id";
|
|
idDiv.textContent = `${getModuleImpl(assiduite)}`;
|
|
bubble.appendChild(idDiv);
|
|
|
|
const periodDivDeb = document.createElement("div");
|
|
periodDivDeb.className = "assiduite-period";
|
|
periodDivDeb.textContent = `${formatDateModal(assiduite.date_debut)}`;
|
|
bubble.appendChild(periodDivDeb);
|
|
const periodDivFin = document.createElement("div");
|
|
periodDivFin.className = "assiduite-period";
|
|
periodDivFin.textContent = `${formatDateModal(assiduite.date_fin)}`;
|
|
bubble.appendChild(periodDivFin);
|
|
|
|
const stateDiv = document.createElement("div");
|
|
stateDiv.className = "assiduite-state";
|
|
stateDiv.textContent = `État: ${assiduite.etat.capitalize()}`;
|
|
bubble.appendChild(stateDiv);
|
|
|
|
const userIdDiv = document.createElement("div");
|
|
userIdDiv.className = "assiduite-user_id";
|
|
userIdDiv.textContent = `saisie le ${formatDateModal(
|
|
assiduite.entry_date,
|
|
" à "
|
|
)}`;
|
|
|
|
if (assiduite.user_id != null) {
|
|
userIdDiv.textContent += `\npar ${assiduite.user_nom_complet}`
|
|
}
|
|
bubble.appendChild(userIdDiv);
|
|
|
|
el.appendChild(bubble);
|
|
}
|
|
|
|
function setMiniTick(timelineDate, dayStart, dayDuration) {
|
|
const endDate = timelineDate.clone().startOf("day");
|
|
endDate.setHours(13, 0);
|
|
const duration = new Duration(dayStart, endDate).minutes;
|
|
const widthPercentage = (duration / dayDuration) * 100;
|
|
const tick = document.createElement('span');
|
|
tick.className = "mini_tick"
|
|
tick.textContent = "13h"
|
|
tick.style.left = `${widthPercentage}%`
|
|
|
|
return tick
|
|
|
|
}
|
|
</script> |