Assiduites : Mise à jour diverses (Page différée + live groupe)
This commit is contained in:
parent
72b0ed17b5
commit
99223b760b
@ -278,7 +278,7 @@
|
||||
padding: 20px;
|
||||
border: 1px solid #888;
|
||||
width: 80%;
|
||||
height: 30%;
|
||||
height: 40%;
|
||||
position: relative;
|
||||
border-radius: 10px;
|
||||
|
||||
|
@ -1570,26 +1570,28 @@ function resetSelection() {
|
||||
*/
|
||||
window.onload = () => {
|
||||
modal = document.getElementById("myModal");
|
||||
closeBtn = document.querySelector(".close");
|
||||
timeline = document.getElementById("timeline");
|
||||
deleteBtn = document.getElementById("delete");
|
||||
splitBtn = document.getElementById("split");
|
||||
editBtn = document.getElementById("edit");
|
||||
selectedAssiduite = null;
|
||||
if (modal) {
|
||||
closeBtn = document.querySelector(".close");
|
||||
timeline = document.getElementById("timeline");
|
||||
deleteBtn = document.getElementById("delete");
|
||||
splitBtn = document.getElementById("split");
|
||||
editBtn = document.getElementById("edit");
|
||||
selectedAssiduite = null;
|
||||
|
||||
closeBtn?.addEventListener("click", closeModal);
|
||||
closeBtn?.addEventListener("click", closeModal);
|
||||
|
||||
deleteBtn?.addEventListener("click", deleteAssiduiteModal);
|
||||
splitBtn?.addEventListener("click", () => {
|
||||
if (selectedAssiduite) {
|
||||
splitAssiduiteModal(selectedAssiduite);
|
||||
}
|
||||
});
|
||||
editBtn?.addEventListener("click", () => {
|
||||
if (selectedAssiduite) {
|
||||
editAssiduiteModal(selectedAssiduite);
|
||||
}
|
||||
});
|
||||
deleteBtn?.addEventListener("click", deleteAssiduiteModal);
|
||||
splitBtn?.addEventListener("click", () => {
|
||||
if (selectedAssiduite) {
|
||||
splitAssiduiteModal(selectedAssiduite);
|
||||
}
|
||||
});
|
||||
editBtn?.addEventListener("click", () => {
|
||||
if (selectedAssiduite) {
|
||||
editAssiduiteModal(selectedAssiduite);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// <<== Gestion de la récupération d'informations ==>>
|
||||
|
@ -59,18 +59,18 @@
|
||||
block.style.width = `${widthPercentage}%`;
|
||||
|
||||
if (assiduité.etat != "CRENEAU") {
|
||||
if (isSingleEtud()) {
|
||||
block.addEventListener("click", () => {
|
||||
let deb = startDate.hours() + startDate.minutes() / 60;
|
||||
let fin = endDate.hours() + endDate.minutes() / 60;
|
||||
deb = Math.max(mt_start, deb);
|
||||
fin = Math.min(mt_end, fin);
|
||||
block.addEventListener("click", () => {
|
||||
let deb = startDate.hours() + startDate.minutes() / 60;
|
||||
let fin = endDate.hours() + endDate.minutes() / 60;
|
||||
deb = Math.max(mt_start, deb);
|
||||
fin = Math.min(mt_end, fin);
|
||||
|
||||
setPeriodValues(deb, fin);
|
||||
setPeriodValues(deb, fin);
|
||||
if (isSingleEtud()) {
|
||||
updateSelectedSelect(getCurrentAssiduiteModuleImplId());
|
||||
updateJustifyBtn();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
//ajouter affichage assiduites on over
|
||||
setupAssiduiteBuble(block, assiduité);
|
||||
}
|
||||
@ -272,7 +272,9 @@
|
||||
position: absolute;
|
||||
text-align: start;
|
||||
top: -40px;
|
||||
transform: translateX(-50%)
|
||||
transform: translateX(-50%);
|
||||
z-index: 50;
|
||||
|
||||
}
|
||||
|
||||
.mini_tick::after {
|
||||
|
@ -4,7 +4,7 @@
|
||||
<div id="studentTable">
|
||||
<div class="thead">
|
||||
<div class="tr">
|
||||
<div class="th sticky">Noms</div>
|
||||
<div class="th sticky" order="ASC" onclick="reOrderEtudiants()">Noms</div>
|
||||
<button id="addColumn" class="floating-button">+</button>
|
||||
</div>
|
||||
</div>
|
||||
@ -52,7 +52,7 @@
|
||||
}
|
||||
|
||||
.thead .tr .th {
|
||||
height: 125px;
|
||||
height: 200px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
@ -61,11 +61,12 @@
|
||||
|
||||
.th.sticky {
|
||||
z-index: 5;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.th,
|
||||
.td {
|
||||
padding: 10px;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
width: 200px;
|
||||
border: 1px solid #ddd;
|
||||
@ -124,6 +125,7 @@
|
||||
.th {
|
||||
background-color: #007BFF;
|
||||
color: white;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.tbody .tr:nth-child(even) {
|
||||
@ -143,12 +145,48 @@
|
||||
}
|
||||
|
||||
#moduleimpl_select {
|
||||
max-width: 175px;
|
||||
max-width: 190px;
|
||||
}
|
||||
|
||||
.btngroup {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.btngroup>button {
|
||||
background-color: transparent;
|
||||
outline: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
color: whitesmoke;
|
||||
}
|
||||
|
||||
.close {
|
||||
font-size: larger;
|
||||
}
|
||||
|
||||
.activate {
|
||||
font-size: large;
|
||||
}
|
||||
|
||||
.th[activated] {
|
||||
transition: all 0.5s;
|
||||
}
|
||||
|
||||
.th[activated='false'] {
|
||||
opacity: 0.5;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
let verified = false;
|
||||
const etatDef = "{{etat_def}}";
|
||||
|
||||
let forceModule = "{{ forcer_module }}"
|
||||
forceModule = forceModule == "True" ? true : false
|
||||
|
||||
moment.tz.setDefault("Etc/UTC");
|
||||
function createColumn() {
|
||||
let table = document.getElementById("studentTable");
|
||||
@ -156,11 +194,22 @@
|
||||
th.classList.add("th");
|
||||
const col_id = `${document.querySelectorAll("[col]").length + 1}`;
|
||||
th.setAttribute("col", col_id);
|
||||
th.setAttribute("activated", "true");
|
||||
th.innerHTML = `
|
||||
<div class="mini-form">
|
||||
<div class="btngroup">
|
||||
<button class="activate" onclick="toggleColumn(${col_id})">Désactiver</button>
|
||||
<button class="close" onclick="removeColumn(this)">x</button>
|
||||
</div>
|
||||
<input type="datetime-local" id="dateStart">
|
||||
<input type="datetime-local" id="dateEnd">
|
||||
{{moduleimpl_select|safe}}
|
||||
<select name="mass_action_${col_id}" id="mass_action_${col_id}" onchange="setEtatCol(${col_id},this.value)">
|
||||
<option value="">Sélectionner une assiduité</option>
|
||||
<option value="0">Présent</option>
|
||||
<option value="1">Retard</option>
|
||||
<option value="2">Absent</option>
|
||||
</select>
|
||||
</div>
|
||||
`;
|
||||
table
|
||||
@ -193,9 +242,68 @@
|
||||
}
|
||||
}
|
||||
|
||||
function reOrderEtudiants() {
|
||||
const th = document.querySelector(".th.sticky");
|
||||
let lines = [...document.querySelectorAll('.tr[etudid]')];
|
||||
const tbody = document.querySelector('.tbody')
|
||||
|
||||
let order = (a, b) => { return a > b }
|
||||
|
||||
if (th.getAttribute("order") == "ASC") {
|
||||
order = (a, b) => { return b > a }
|
||||
th.setAttribute("order", "DESC")
|
||||
} else {
|
||||
th.setAttribute("order", "ASC")
|
||||
}
|
||||
|
||||
lines = lines.sort((a, b) => {
|
||||
const nameA = a.querySelector(".td.sticky").textContent.split(" ").pop();
|
||||
const nameB = b.querySelector(".td.sticky").textContent.split(" ").pop();
|
||||
return order(nameA, nameB)
|
||||
})
|
||||
|
||||
tbody.innerHTML = "";
|
||||
tbody.append(...lines)
|
||||
}
|
||||
|
||||
function toggleColumn(colId) {
|
||||
const column = document.querySelector(`[col='${colId}']`)
|
||||
const btn = column.querySelector(".activate");
|
||||
if (column.getAttribute('activated') == "true") {
|
||||
column.setAttribute("activated", "false");
|
||||
btn.textContent = "Activer"
|
||||
} else {
|
||||
column.setAttribute("activated", "true");
|
||||
btn.textContent = "Déactiver"
|
||||
}
|
||||
}
|
||||
|
||||
function previousCol(column) {
|
||||
const cols = [...document.querySelectorAll("[col]")]
|
||||
let previousCol = null;
|
||||
|
||||
let i = 1;
|
||||
|
||||
while (i < cols.length) {
|
||||
previousCol = cols[i - 1];
|
||||
if (cols[i] == column)
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
|
||||
return previousCol
|
||||
|
||||
}
|
||||
|
||||
function removeColumn(element) {
|
||||
const col = element.parentElement.parentElement.parentElement;
|
||||
const col_id = col.getAttribute("col");
|
||||
document.querySelectorAll(`[col='${col_id}'],[colid='${col_id}']`).forEach((el) => { el.remove() })
|
||||
}
|
||||
|
||||
function defaultDate(element) {
|
||||
const num = element.parentElement.parentElement.getAttribute("col") - 1;
|
||||
const last = [...document.querySelectorAll(`[col='${num}'] #dateEnd`)].pop();
|
||||
const num = previousCol(element.parentElement.parentElement)?.getAttribute("col");
|
||||
const last = document.querySelector(`[col='${num}'] #dateEnd`);
|
||||
let date = undefined;
|
||||
if (last == undefined) {
|
||||
date = moment().tz("Europe/Paris").format("YYYY-MM-DDTHH:mm");
|
||||
@ -218,6 +326,17 @@
|
||||
);
|
||||
}
|
||||
|
||||
function setEtatCol(colId, etatId) {
|
||||
const tds = [...document.querySelectorAll(`.td[colid='${colId}']`)]
|
||||
tds.forEach((td) => {
|
||||
let inputs = [...td.querySelectorAll("input")]
|
||||
inputs.forEach((el) => { el.checked = false })
|
||||
if (etatId != "") {
|
||||
inputs[Number.parseInt(etatId)].checked = true;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function getEtatCol(colId) {
|
||||
const etats = {};
|
||||
const tds = [...document.querySelectorAll(`.td[colid='${colId}']`)]
|
||||
@ -266,6 +385,8 @@
|
||||
|
||||
cols.forEach((col) => {
|
||||
const col_id = col.getAttribute("col");
|
||||
if (col.getAttribute("activated") == "false") return;
|
||||
toggleColumn(col_id);
|
||||
const etats = getEtatCol(col_id);
|
||||
|
||||
const inputDeb = col.querySelector("#dateStart").value;
|
||||
@ -273,10 +394,27 @@
|
||||
const moduleSelect = col.querySelector("#moduleimpl_select").value;
|
||||
|
||||
if (inputDeb == "" || inputFin == "") {
|
||||
errors.push(`La colonne n°${col_id} n'est pas valide`);
|
||||
errors.push(`La période de la colonne n°${col_id} n'est pas valide`);
|
||||
return;
|
||||
}
|
||||
|
||||
const d_debut = moment(inputDeb)
|
||||
const d_fin = moment(inputFin)
|
||||
const testPeriode = [
|
||||
d_debut.isBefore("{{formsemestre_date_debut}}"),
|
||||
d_debut.isAfter("{{formsemestre_date_fin}}"),
|
||||
d_fin.isBefore("{{formsemestre_date_debut}}"),
|
||||
d_fin.isAfter("{{formsemestre_date_fin}}"),
|
||||
]
|
||||
if (testPeriode.some((e) => e)) {
|
||||
errors.push(`La période de la colonne n°${col_id} n'est pas dans le semestre`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (forceModule && moduleSelect == "") {
|
||||
errors.push(`Le module de la colonne n°${col_id} n'a pas été entré. (Préférence de semestre)`);
|
||||
return;
|
||||
}
|
||||
// TODO Mettre une erreur lorsque moduleimpl forcé (pref)
|
||||
// TODO Mettre une erreur lorsque assiduité forcé (pref)
|
||||
|
||||
Object.keys(etats).forEach((key) => {
|
||||
@ -297,7 +435,9 @@
|
||||
|
||||
openAlertModal("Erreur(s) détéctée(s)", texte)
|
||||
} else {
|
||||
createAllAssiduites(assiduites);
|
||||
if (assiduites.length > 0) {
|
||||
createAllAssiduites(assiduites);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -45,7 +45,7 @@
|
||||
<div class="action-buttons">
|
||||
<button id="delete" class="btnPrompt" disabled>Supprimer</button>
|
||||
<button id="split" class="btnPrompt" disabled>Séparer</button>
|
||||
<button id="edit" class="btnPrompt" disabled>Modifier</button>
|
||||
<button id="edit" class="btnPrompt" disabled>Modifier l'état</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -489,7 +489,6 @@ def get_etat_abs_date():
|
||||
@permission_required(Permission.ScoAbsChange)
|
||||
def signal_assiduites_diff():
|
||||
group_ids: list[int] = request.args.get("group_ids", None)
|
||||
etudid: int = request.args.get("etudid", None)
|
||||
formsemestre_id: int = request.args.get("formsemestre_id", -1)
|
||||
etudiants: list[dict] = []
|
||||
|
||||
@ -503,9 +502,6 @@ def signal_assiduites_diff():
|
||||
|
||||
formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id)
|
||||
|
||||
if etudid is not None:
|
||||
etudiants.append(sco_etud.get_etud_info(etudid=int(etudid), filled=True)[0])
|
||||
|
||||
if group_ids is None:
|
||||
group_ids = []
|
||||
else:
|
||||
@ -514,6 +510,13 @@ def signal_assiduites_diff():
|
||||
|
||||
groups_infos = sco_groups_view.DisplayedGroupsInfos(group_ids)
|
||||
|
||||
if not groups_infos.members:
|
||||
return (
|
||||
html_sco_header.sco_header(page_title="Assiduités Différées")
|
||||
+ "<h3>Aucun étudiant ! </h3>"
|
||||
+ html_sco_header.sco_footer()
|
||||
)
|
||||
|
||||
etudiants.extend(
|
||||
[
|
||||
sco_etud.get_etud_info(etudid=m["etudid"], filled=True)[0]
|
||||
@ -553,7 +556,14 @@ def signal_assiduites_diff():
|
||||
"assiduites/signal_assiduites_diff.j2",
|
||||
etudiants=etudiants,
|
||||
etat_def=sco_preferences.get_preference("assi_etat_defaut"),
|
||||
formsemestre_date_debut=str(formsemestre.date_debut),
|
||||
formsemestre_date_fin=str(formsemestre.date_fin),
|
||||
moduleimpl_select=_module_selector(formsemestre),
|
||||
forcer_module=sco_preferences.get_preference(
|
||||
"forcer_module",
|
||||
formsemestre_id=formsemestre_id,
|
||||
dept_id=g.scodoc_dept_id,
|
||||
),
|
||||
gr=gr_tit,
|
||||
sem=sem["titre_num"],
|
||||
),
|
||||
|
Loading…
Reference in New Issue
Block a user