ScoDoc/app/templates/assiduites/widgets/minitimeline.j2

161 lines
6.0 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 ? $("#date").datepicker("getDate") : new Date(day);
const timeline = document.createElement("div");
timeline.className = "mini-timeline";
const timelineDate = date.startOf("day");
const dayStart = new Date(`${timelineDate.format("YYYY-MM-DD").substring(0,10)}T${numberToTime(mt_start)}`);
const dayEnd = new Date(`${timelineDate.format("YYYY-MM-DD").substring(0,10)}T${numberToTime(mt_end)}`);
const dayDuration = new Duration(dayStart, dayEnd).minutes;
timeline.appendChild(setMiniTick(timelineDate, dayStart, dayDuration));
if (day == null) {
const tlTimes = getPeriodAsDate();
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);
$("#moduleimpl_select").val(getModuleImplId(assiduité))
setTimeout(()=>{
$("#moduleimpl_select").trigger("change");
}, 0)
});
//ajouter affichage assiduites on over
setupAssiduiteBubble(block, assiduité);
}
// TODO: ajout couleur justificatif
block.classList.add(assiduité.etat.toLowerCase());
if(assiduité.etat != "CRENEAU") block.classList.add("color");
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 setupAssiduiteBubble(el, assiduite) {
function formatDateModal(dateStr){
const date = new Date(Date.removeUTC(dateStr));
return date.format("DD/MM/Y HH:mm");
}
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";
getModuleImpl(assiduite).then((modImpl) => {
idDiv.textContent = `${modImpl}`;
});
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 motifDiv = document.createElement("div");
stateDiv.className = "assiduite-why";
const motif = ["", null, undefined].includes(assiduite.desc) ? "Pas de motif" : assiduite.desc.capitalize();
stateDiv.textContent = `Motif: ${motif}`;
bubble.appendChild(motifDiv);
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>