ScoDoc-Lille/app/templates/assiduites/widgets/tableau_base.j2

615 lines
18 KiB
Plaintext
Raw Normal View History

2023-06-20 15:50:56 +02:00
<ul id="contextMenu" class="context-menu">
<li id="detailOption">Détails</li>
<li id="editOption">Éditer</li>
2023-06-20 15:50:56 +02:00
<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");
2023-06-23 16:12:36 +02:00
const detailOption = document.getElementById("detailOption");
2023-06-20 15:50:56 +02:00
const deleteOption = document.getElementById("deleteOption");
let selectedRow;
document.addEventListener("click", () => {
contextMenu.style.display = "none";
2023-09-11 15:55:18 +02:00
if (contextMenu.childElementCount > 3) {
contextMenu.removeChild(contextMenu.lastElementChild)
}
2023-06-20 15:50:56 +02:00
});
editOption.addEventListener("click", () => {
if (selectedRow) {
2023-06-23 16:12:36 +02:00
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);
}
2023-06-20 15:50:56 +02:00
}
});
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;
}
}
2023-09-11 15:55:18 +02:00
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);
}
2023-09-15 10:51:40 +02:00
if (k == "etud") {
const e = getEtudiant(el.etudid);
const str = `${e.prenom.capitalize()} ${e.nom.toUpperCase()}`
return f.etud === "" || str.indexOf(f.etud) != -1;
}
2023-06-20 15:50:56 +02:00
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);
2023-06-23 16:12:36 +02:00
if (totalPages <= 1) {
2023-06-28 17:15:24 +02:00
if (assi) {
paginationContainerAssiduites.innerHTML = ""
} else {
paginationContainerJustificatifs.innerHTML = ""
}
2023-06-23 16:12:36 +02:00
return;
}
2023-06-20 15:50:56 +02:00
if (assi) {
2023-06-23 16:12:36 +02:00
paginationContainerAssiduites.innerHTML = "<span class='liste_pagination'><button class='pagination_moins'>&lt;</button><select id='paginationAssi'></select><button class='pagination_plus'>&gt;</button></span>"
paginationContainerAssiduites.querySelector('#paginationAssi')?.addEventListener('change', (e) => {
currentPageAssiduites = e.target.value;
2023-06-28 17:15:24 +02:00
assiduiteCallBack(array);
2023-06-23 16:12:36 +02:00
})
paginationContainerAssiduites.querySelector('.pagination_moins').addEventListener('click', () => {
if (currentPageAssiduites > 1) {
currentPageAssiduites--;
2023-09-11 08:31:09 +02:00
paginationContainerAssiduites.querySelector('#paginationAssi').value = currentPageAssiduites + ""
2023-06-28 17:15:24 +02:00
assiduiteCallBack(array);
2023-06-23 16:12:36 +02:00
}
})
paginationContainerAssiduites.querySelector('.pagination_plus').addEventListener('click', () => {
if (currentPageAssiduites < totalPages) {
currentPageAssiduites++;
2023-09-11 08:31:09 +02:00
paginationContainerAssiduites.querySelector('#paginationAssi').value = currentPageAssiduites + ""
2023-06-28 17:15:24 +02:00
assiduiteCallBack(array);
2023-06-23 16:12:36 +02:00
}
})
2023-06-20 15:50:56 +02:00
} else {
2023-06-23 16:12:36 +02:00
paginationContainerJustificatifs.innerHTML = "<span class='liste_pagination'><button class='pagination_moins'>&lt;</button><select id='paginationJusti'></select><button class='pagination_plus'>&gt;</button></span>"
paginationContainerJustificatifs.querySelector('#paginationJusti')?.addEventListener('change', (e) => {
currentPageJustificatifs = e.target.value;
2023-06-28 17:15:24 +02:00
justificatifCallBack(array);
2023-06-23 16:12:36 +02:00
})
2023-06-20 15:50:56 +02:00
2023-06-23 16:12:36 +02:00
paginationContainerJustificatifs.querySelector('.pagination_moins').addEventListener('click', () => {
if (currentPageJustificatifs > 1) {
currentPageJustificatifs--;
paginationContainerJustificatifs.querySelector('#paginationJusti').value = currentPageJustificatifs
2023-06-28 17:15:24 +02:00
justificatifCallBack(array);
2023-06-23 16:12:36 +02:00
}
})
paginationContainerJustificatifs.querySelector('.pagination_plus').addEventListener('click', () => {
if (currentPageJustificatifs < totalPages) {
currentPageJustificatifs++;
paginationContainerJustificatifs.querySelector('#paginationJusti').value = currentPageJustificatifs
2023-06-28 17:15:24 +02:00
justificatifCallBack(array);
2023-06-23 16:12:36 +02:00
}
})
2023-06-20 15:50:56 +02:00
}
2023-06-23 16:12:36 +02:00
2023-06-20 15:50:56 +02:00
for (let i = 1; i <= totalPages; i++) {
2023-06-23 16:12:36 +02:00
const paginationButton = document.createElement("option");
2023-06-20 15:50:56 +02:00
paginationButton.textContent = i;
2023-06-23 16:12:36 +02:00
paginationButton.value = i;
2023-06-20 15:50:56 +02:00
if (assi) {
2023-06-23 16:12:36 +02:00
paginationContainerAssiduites.querySelector('#paginationAssi').appendChild(paginationButton)
2023-09-11 08:31:09 +02:00
if (i == currentPageAssiduites)
paginationContainerAssiduites.querySelector('#paginationAssi').value = i + "";
2023-06-20 15:50:56 +02:00
} else {
2023-06-23 16:12:36 +02:00
paginationContainerJustificatifs.querySelector('#paginationJusti').appendChild(paginationButton)
2023-09-11 08:31:09 +02:00
if (i == currentPageJustificatifs)
paginationContainerJustificatifs.querySelector('#paginationJusti').value = i + "";
2023-06-20 15:50:56 +02:00
}
}
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() {
2023-09-15 10:51:40 +02:00
try { getAssi(assiduiteCallBack) } catch { }
try { getJusti(justificatifCallBack) } catch { }
2023-06-20 15:50:56 +02:00
}
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);
2023-06-20 15:50:56 +02:00
}
2023-09-15 10:51:40 +02:00
if (keyword.indexOf("etudid") != -1) {
keyValueA = getEtudiant(a.etudid);
keyValueB = getEtudiant(b.etudid);
keyValueA = `${keyValueA.prenom.capitalize()} ${keyValueA.nom.toUpperCase()}`
keyValueB = `${keyValueB.prenom.capitalize()} ${keyValueB.nom.toUpperCase()}`
}
2023-06-20 15:50:56 +02:00
let orderDertermined = keyValueA > keyValueB;
if (!ordered) {
orderDertermined = keyValueA < keyValueB;
}
return orderDertermined
});
callback(sorted);
};
if (assi) {
orderAssiduites = !orderAssiduites;
2023-09-15 10:51:40 +02:00
getAssi((a) => { call(a, orderAssiduites) });
2023-06-20 15:50:56 +02:00
} else {
orderJustificatifs = !orderJustificatifs;
2023-09-15 10:51:40 +02:00
getJusti((a) => { call(a, orderJustificatifs) });
2023-06-20 15:50:56 +02:00
}
}
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";
2023-06-28 17:15:24 +02:00
case "etudid":
return "Etudiant";
case "formsemestre":
return "Semestre";
2023-06-20 15:50:56 +02:00
}
}
2023-06-23 16:12:36 +02:00
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";
2023-09-11 15:55:18 +02:00
if (contextMenu.childElementCount > 3) {
contextMenu.removeChild(contextMenu.lastElementChild)
}
if (selectedRow.getAttribute('type') == "assiduite") {
const li = document.createElement('li')
li.textContent = "Justifier"
let obj_id = selectedRow.getAttribute('obj_id');
let assi = Object.values(assiduites).flat().filter((a) => { return a.assiduite_id == obj_id })[0]
2023-09-11 15:55:18 +02:00
li.addEventListener('click', () => {
2023-10-27 16:51:06 +02:00
if (assi && !assi.est_just && assi.etat != "PRESENT") {
fastJustify(assi)
2023-09-11 15:55:18 +02:00
} else {
openAlertModal("Erreur", document.createTextNode("L'assiduité est déjà justifiée."))
2023-09-11 15:55:18 +02:00
}
})
if (assi && assi.etat != "PRESENT") {
contextMenu.appendChild(li);
}
2023-09-11 15:55:18 +02:00
}
2023-06-23 16:12:36 +02:00
}
2023-06-20 15:50:56 +02:00
2023-09-15 09:13:25 +02:00
function downloadStr(data, name) {
const blob = new Blob([data], { type: 'text/csv' });
const url = window.URL.createObjectURL(blob)
const a = document.createElement('a')
a.setAttribute('href', url)
a.setAttribute('download', name);
a.click()
a.remove()
}
function askDownload(data) {
const div = document.createElement('div');
const head = document.createElement('h3');
const input = document.createElement('input');
head.textContent = "Veuillez nommer le fichier qui sera téléchargé (sera au format CSV)"
input.type = "text";
input.placeholder = "liste.csv"
div.appendChild(head)
div.appendChild(input)
openPromptModal("Préparation du téléchargement", div, () => {
downloadStr(data, input.value ? input.value : "download.csv")
}, () => { }, "green");
}
function toCSV(array, filters) {
array = filterArray(array, filters.filters)
let csv = filters.columns.map((c) => columnTranslator(c)).join(',') + "\n";
array.forEach((a) => {
let line = ""
filters.columns.forEach((c) => {
switch (c) {
case "fichier":
line += a[c] ? "Oui," : "Non,"
break;
case "etudid":
const e = getEtudiant(a.etudid);
line += `${e.nom.toUpperCase()} ${e.prenom.capitalize()},`
break;
case "formsemestre":
line += a.hasOwnProperty("formsemestre") ? a.formsemestre.title : ""
line += ","
break;
case "est_just":
line += a[c] ? "Oui," : "Non,"
break;
case "moduleimpl_id":
line += `${getModuleImpl(a)},`
break;
default:
line += `${a[c]},`;
break;
}
})
line = line.substring(0, line.lastIndexOf(',')) + "\n"
csv += line;
})
askDownload(csv);
}
2023-09-15 10:51:40 +02:00
function getEtudiant(id) {
if (id in etuds) {
return etuds[id];
}
getSingleEtud(id);
return etuds[id];
}
2023-06-20 15:50:56 +02:00
</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;
2023-06-23 16:12:36 +02:00
position: fixed;
2023-06-20 15:50:56 +02:00
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;
}
2023-06-28 17:15:24 +02:00
.filter-body label {
2023-06-20 15:50:56 +02:00
display: flex;
justify-content: center;
align-items: center;
padding: 0;
margin: 0;
}
2023-06-23 16:12:36 +02:00
.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;
}
2023-06-20 15:50:56 +02:00
</style>