<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>