526 lines
16 KiB
Django/Jinja
526 lines
16 KiB
Django/Jinja
<ul id="contextMenu" class="context-menu">
|
|
<li id="detailOption">Détails</li>
|
|
<li id="editOption">Éditer</li>
|
|
<li id="deleteOption">Supprimer</li>
|
|
</ul>
|
|
|
|
{% include "assiduites/widgets/alert.j2" %}
|
|
{% include "assiduites/widgets/prompt.j2" %}
|
|
|
|
<script>
|
|
const itemsPerPage = 10;
|
|
const contextMenu = document.getElementById("contextMenu");
|
|
const editOption = document.getElementById("editOption");
|
|
const detailOption = document.getElementById("detailOption");
|
|
const deleteOption = document.getElementById("deleteOption");
|
|
|
|
let selectedRow;
|
|
|
|
document.addEventListener("click", () => {
|
|
contextMenu.style.display = "none";
|
|
if (contextMenu.childElementCount > 3) {
|
|
contextMenu.removeChild(contextMenu.lastElementChild)
|
|
}
|
|
});
|
|
|
|
editOption.addEventListener("click", () => {
|
|
if (selectedRow) {
|
|
const type = selectedRow.getAttribute('type');
|
|
const obj_id = selectedRow.getAttribute('obj_id');
|
|
|
|
if (type == "assiduite") {
|
|
editionAssiduites(obj_id);
|
|
} else {
|
|
editionJustificatifs(obj_id);
|
|
}
|
|
}
|
|
});
|
|
|
|
detailOption.addEventListener("click", () => {
|
|
if (selectedRow) {
|
|
const type = selectedRow.getAttribute('type');
|
|
const obj_id = selectedRow.getAttribute('obj_id');
|
|
|
|
if (type == "assiduite") {
|
|
detailAssiduites(obj_id);
|
|
} else {
|
|
detailJustificatifs(obj_id);
|
|
}
|
|
}
|
|
});
|
|
|
|
deleteOption.addEventListener("click", () => {
|
|
if (selectedRow) {
|
|
const type = selectedRow.getAttribute('type');
|
|
const obj_id = selectedRow.getAttribute('obj_id');
|
|
if (type == "assiduite") {
|
|
deleteAssiduite(obj_id);
|
|
|
|
} else {
|
|
deleteJustificatif(obj_id);
|
|
}
|
|
loadAll();
|
|
|
|
|
|
}
|
|
});
|
|
|
|
function filterArray(array, f) {
|
|
return array.filter((el) => {
|
|
let t = Object.keys(f).every((k) => {
|
|
if (k == "etat") {
|
|
return f.etat.includes(el.etat.toLowerCase())
|
|
};
|
|
if (k == "est_just") {
|
|
if (f.est_just != "") {
|
|
return `${el.est_just}` == f.est_just;
|
|
}
|
|
}
|
|
if (k.indexOf('date') != -1) {
|
|
const assi_time = moment.tz(el[k], TIMEZONE);
|
|
const filter_time = f[k].time;
|
|
switch (f[k].pref) {
|
|
|
|
case "0":
|
|
return assi_time.isSame(filter_time, 'minute');
|
|
case "-1":
|
|
return assi_time.isBefore(filter_time, 'minutes');
|
|
case "1":
|
|
return assi_time.isAfter(filter_time, 'minutes');
|
|
}
|
|
}
|
|
|
|
if (k == "moduleimpl_id") {
|
|
const m = el[k] == undefined || el[k] == null ? "null" : el[k];
|
|
if (f.moduleimpl_id != '') {
|
|
return m == f.moduleimpl_id;
|
|
}
|
|
}
|
|
|
|
if (k == "obj_id") {
|
|
const obj_id = el.assiduite_id || el.justif_id;
|
|
return f.obj_id.includes(obj_id)
|
|
}
|
|
|
|
if (k == "formsemestre") {
|
|
return f.formsemestre === "" || (el.hasOwnProperty("formsemestre") && el.formsemestre.title.replaceAll('-', ' ').indexOf(f.formsemestre) != -1);
|
|
}
|
|
|
|
return true;
|
|
})
|
|
|
|
return t;
|
|
|
|
})
|
|
}
|
|
|
|
function generateTableHead(columns, assi = true) {
|
|
const table = assi ? "#assiduiteTable" : "#justificatifTable"
|
|
const call = assi ? [assiduiteCallBack, true] : [justificatifCallBack, false]
|
|
const tr = document.querySelector(`${table} thead tr`);
|
|
|
|
tr.innerHTML = ""
|
|
|
|
columns.forEach((c) => {
|
|
const th = document.createElement('th');
|
|
const div = document.createElement('div');
|
|
|
|
const span = document.createElement('span');
|
|
span.textContent = columnTranslator(c);
|
|
|
|
const a = document.createElement('a');
|
|
a.classList.add('icon', "order");
|
|
a.onclick = () => { order(c, call[0], a, call[1]) }
|
|
|
|
div.appendChild(span)
|
|
div.appendChild(a)
|
|
|
|
th.appendChild(div);
|
|
|
|
tr.appendChild(th);
|
|
})
|
|
}
|
|
|
|
function renderPaginationButtons(array, assi = true) {
|
|
const totalPages = Math.ceil(array.length / itemsPerPage);
|
|
if (totalPages <= 1) {
|
|
if (assi) {
|
|
paginationContainerAssiduites.innerHTML = ""
|
|
} else {
|
|
paginationContainerJustificatifs.innerHTML = ""
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (assi) {
|
|
paginationContainerAssiduites.innerHTML = "<span class='liste_pagination'><button class='pagination_moins'><</button><select id='paginationAssi'></select><button class='pagination_plus'>></button></span>"
|
|
paginationContainerAssiduites.querySelector('#paginationAssi')?.addEventListener('change', (e) => {
|
|
currentPageAssiduites = e.target.value;
|
|
assiduiteCallBack(array);
|
|
})
|
|
|
|
paginationContainerAssiduites.querySelector('.pagination_moins').addEventListener('click', () => {
|
|
if (currentPageAssiduites > 1) {
|
|
currentPageAssiduites--;
|
|
paginationContainerAssiduites.querySelector('#paginationAssi').value = currentPageAssiduites + ""
|
|
assiduiteCallBack(array);
|
|
|
|
}
|
|
})
|
|
|
|
paginationContainerAssiduites.querySelector('.pagination_plus').addEventListener('click', () => {
|
|
if (currentPageAssiduites < totalPages) {
|
|
currentPageAssiduites++;
|
|
paginationContainerAssiduites.querySelector('#paginationAssi').value = currentPageAssiduites + ""
|
|
assiduiteCallBack(array);
|
|
}
|
|
})
|
|
} else {
|
|
paginationContainerJustificatifs.innerHTML = "<span class='liste_pagination'><button class='pagination_moins'><</button><select id='paginationJusti'></select><button class='pagination_plus'>></button></span>"
|
|
paginationContainerJustificatifs.querySelector('#paginationJusti')?.addEventListener('change', (e) => {
|
|
currentPageJustificatifs = e.target.value;
|
|
justificatifCallBack(array);
|
|
})
|
|
|
|
paginationContainerJustificatifs.querySelector('.pagination_moins').addEventListener('click', () => {
|
|
if (currentPageJustificatifs > 1) {
|
|
currentPageJustificatifs--;
|
|
paginationContainerJustificatifs.querySelector('#paginationJusti').value = currentPageAssiduites
|
|
justificatifCallBack(array);
|
|
}
|
|
})
|
|
|
|
paginationContainerJustificatifs.querySelector('.pagination_plus').addEventListener('click', () => {
|
|
if (currentPageJustificatifs < totalPages) {
|
|
currentPageJustificatifs++;
|
|
paginationContainerJustificatifs.querySelector('#paginationJusti').value = currentPageAssiduites
|
|
justificatifCallBack(array);
|
|
}
|
|
})
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (let i = 1; i <= totalPages; i++) {
|
|
const paginationButton = document.createElement("option");
|
|
paginationButton.textContent = i;
|
|
paginationButton.value = i;
|
|
|
|
if (assi) {
|
|
paginationContainerAssiduites.querySelector('#paginationAssi').appendChild(paginationButton)
|
|
if (i == currentPageAssiduites)
|
|
paginationContainerAssiduites.querySelector('#paginationAssi').value = i + "";
|
|
} else {
|
|
paginationContainerJustificatifs.querySelector('#paginationJusti').appendChild(paginationButton)
|
|
if (i == currentPageJustificatifs)
|
|
paginationContainerJustificatifs.querySelector('#paginationJusti').value = i + "";
|
|
}
|
|
}
|
|
updateActivePaginationButton(assi);
|
|
}
|
|
function updateActivePaginationButton(assi = true) {
|
|
if (assi) {
|
|
const paginationButtons =
|
|
paginationContainerAssiduites.querySelectorAll("#paginationContainerAssiduites .pagination-button");
|
|
paginationButtons.forEach((button) => {
|
|
if (parseInt(button.textContent) === currentPageAssiduites) {
|
|
button.classList.add("active");
|
|
} else {
|
|
button.classList.remove("active");
|
|
}
|
|
});
|
|
} else {
|
|
const paginationButtons =
|
|
paginationContainerJustificatifs.querySelectorAll("#paginationContainerJustificatifs .pagination-button");
|
|
paginationButtons.forEach((button) => {
|
|
if (parseInt(button.textContent) === currentPageJustificatifs) {
|
|
button.classList.add("active");
|
|
} else {
|
|
button.classList.remove("active");
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
function loadAll() {
|
|
try { getAllAssiduitesFromEtud(etudid, assiduiteCallBack, true, true, assi_limit_annee) } catch (_) { }
|
|
try { getAllJustificatifsFromEtud(etudid, justificatifCallBack, true, assi_limit_annee) } catch (_) { }
|
|
}
|
|
|
|
function order(keyword, callback = () => { }, el, assi = true) {
|
|
const call = (array, ordered) => {
|
|
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(a);
|
|
keyValueB = getModuleImpl(b);
|
|
}
|
|
|
|
let orderDertermined = keyValueA > keyValueB;
|
|
|
|
if (!ordered) {
|
|
orderDertermined = keyValueA < keyValueB;
|
|
}
|
|
return orderDertermined
|
|
});
|
|
|
|
|
|
|
|
callback(sorted);
|
|
|
|
};
|
|
|
|
if (assi) {
|
|
orderAssiduites = !orderAssiduites;
|
|
getAllAssiduitesFromEtud(etudid, (a) => { call(a, orderAssiduites) })
|
|
} else {
|
|
orderJustificatifs = !orderJustificatifs;
|
|
getAllJustificatifsFromEtud(etudid, (a) => { call(a, orderJustificatifs) })
|
|
}
|
|
|
|
}
|
|
|
|
|
|
function columnTranslator(colName) {
|
|
switch (colName) {
|
|
case "date_debut":
|
|
return "Début";
|
|
case "entry_date":
|
|
return "Saisie le";
|
|
case "date_fin":
|
|
return "Fin";
|
|
case "etat":
|
|
return "État";
|
|
case "moduleimpl_id":
|
|
return "Module";
|
|
case "est_just":
|
|
return "Justifiée";
|
|
case "raison":
|
|
return "Raison";
|
|
case "fichier":
|
|
return "Fichier";
|
|
case "etudid":
|
|
return "Etudiant";
|
|
case "formsemestre":
|
|
return "Semestre";
|
|
}
|
|
}
|
|
|
|
function openContext(e) {
|
|
e.preventDefault();
|
|
selectedRow = e.target.parentElement;
|
|
contextMenu.style.top = `${e.clientY - contextMenu.offsetHeight}px`;
|
|
contextMenu.style.left = `${e.clientX}px`;
|
|
contextMenu.style.display = "block";
|
|
if (contextMenu.childElementCount > 3) {
|
|
contextMenu.removeChild(contextMenu.lastElementChild)
|
|
}
|
|
if (selectedRow.getAttribute('type') == "assiduite") {
|
|
|
|
const li = document.createElement('li')
|
|
li.textContent = "Justifier"
|
|
|
|
li.addEventListener('click', () => {
|
|
let obj_id = selectedRow.getAttribute('obj_id');
|
|
assiduite = Object.values(assiduites).flat().filter((a) => { return a.assiduite_id == obj_id })
|
|
console.log(assiduite[0])
|
|
if (assiduite && !assiduite[0].est_just && assiduite[0].etat != "PRESENT") {
|
|
fastJustify(assiduite[0])
|
|
} else {
|
|
openAlertModal("Erreur", document.createTextNode("L'assiduité est déjà justifiée ou ne peut pas l'être."))
|
|
}
|
|
})
|
|
|
|
contextMenu.appendChild(li)
|
|
}
|
|
}
|
|
|
|
</script>
|
|
|
|
<style>
|
|
.pageContent {
|
|
width: 100%;
|
|
max-width: var(--sco-content-max-width);
|
|
display: flex;
|
|
flex-direction: column;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
table {
|
|
border-collapse: collapse;
|
|
|
|
text-align: left;
|
|
margin: 20px 0;
|
|
}
|
|
|
|
th,
|
|
td {
|
|
border: 1px solid #dddddd;
|
|
padding: 8px;
|
|
}
|
|
|
|
th {
|
|
background-color: #f2f2f2;
|
|
|
|
}
|
|
|
|
tr:hover {
|
|
filter: brightness(1.2)
|
|
}
|
|
|
|
.context-menu {
|
|
display: none;
|
|
position: fixed;
|
|
list-style-type: none;
|
|
padding: 10px 0;
|
|
background-color: #f9f9f9;
|
|
border: 1px solid #ccc;
|
|
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
|
|
cursor: pointer;
|
|
z-index: 45;
|
|
}
|
|
|
|
.context-menu li {
|
|
padding: 8px 16px;
|
|
background-color: #f9f9f9;
|
|
}
|
|
|
|
.context-menu li:hover {
|
|
filter: brightness(0.7);
|
|
}
|
|
|
|
#deleteOption {
|
|
background-color: #F1A69C;
|
|
}
|
|
|
|
.l-present {
|
|
background-color: #9CF1AF;
|
|
}
|
|
|
|
.l-absent,
|
|
.l-invalid {
|
|
background-color: #F1A69C;
|
|
}
|
|
|
|
.l-valid {
|
|
background-color: #8f7eff;
|
|
}
|
|
|
|
.l-retard {
|
|
background-color: #F1D99C;
|
|
}
|
|
|
|
/* Ajoutez des styles pour le conteneur de pagination et les boutons */
|
|
.pagination-container {
|
|
display: flex;
|
|
justify-content: center;
|
|
margin: 20px 0;
|
|
}
|
|
|
|
.pagination-button {
|
|
padding: 10px;
|
|
border: 1px solid #ccc;
|
|
cursor: pointer;
|
|
background-color: #f9f9f9;
|
|
margin: 0 5px;
|
|
text-decoration: none;
|
|
color: #000;
|
|
}
|
|
|
|
.pagination-button:hover {
|
|
background-color: #ddd;
|
|
}
|
|
|
|
.pagination-button.active {
|
|
background-color: #007bff;
|
|
color: #fff;
|
|
border-color: #007bff;
|
|
}
|
|
|
|
th>div {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
}
|
|
|
|
.filter-head {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 5px;
|
|
}
|
|
|
|
.filter-line {
|
|
display: flex;
|
|
justify-content: start;
|
|
align-items: center;
|
|
margin: 15px;
|
|
}
|
|
|
|
.filter-line>* {
|
|
margin-right: 5px;
|
|
}
|
|
|
|
|
|
|
|
.rbtn {
|
|
width: 35px;
|
|
height: 35px;
|
|
margin: 0 5px !important;
|
|
}
|
|
|
|
.f-label {
|
|
margin: 0 5px;
|
|
}
|
|
|
|
.chk {
|
|
margin-left: 2px !important;
|
|
}
|
|
|
|
.filter-body label {
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
padding: 0;
|
|
margin: 0;
|
|
}
|
|
|
|
.obj-title {
|
|
text-decoration: underline #bbb;
|
|
font-weight: bold;
|
|
}
|
|
|
|
.obj-part {
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: center;
|
|
align-items: center;
|
|
width: 33%;
|
|
padding: 5px;
|
|
border: 1px solid #bbb;
|
|
}
|
|
|
|
.obj-dates,
|
|
.obj-mod,
|
|
.obj-rest {
|
|
display: flex;
|
|
justify-content: space-evenly;
|
|
margin: 2px;
|
|
}
|
|
|
|
.liste_pagination {
|
|
display: flex;
|
|
justify-content: space-evenly;
|
|
align-items: center;
|
|
gap: 5px;
|
|
}
|
|
</style> |