forked from ScoDoc/ScoDoc
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;
|
padding: 20px;
|
||||||
border: 1px solid #888;
|
border: 1px solid #888;
|
||||||
width: 80%;
|
width: 80%;
|
||||||
height: 30%;
|
height: 40%;
|
||||||
position: relative;
|
position: relative;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
|
|
||||||
|
@ -1570,26 +1570,28 @@ function resetSelection() {
|
|||||||
*/
|
*/
|
||||||
window.onload = () => {
|
window.onload = () => {
|
||||||
modal = document.getElementById("myModal");
|
modal = document.getElementById("myModal");
|
||||||
closeBtn = document.querySelector(".close");
|
if (modal) {
|
||||||
timeline = document.getElementById("timeline");
|
closeBtn = document.querySelector(".close");
|
||||||
deleteBtn = document.getElementById("delete");
|
timeline = document.getElementById("timeline");
|
||||||
splitBtn = document.getElementById("split");
|
deleteBtn = document.getElementById("delete");
|
||||||
editBtn = document.getElementById("edit");
|
splitBtn = document.getElementById("split");
|
||||||
selectedAssiduite = null;
|
editBtn = document.getElementById("edit");
|
||||||
|
selectedAssiduite = null;
|
||||||
|
|
||||||
closeBtn?.addEventListener("click", closeModal);
|
closeBtn?.addEventListener("click", closeModal);
|
||||||
|
|
||||||
deleteBtn?.addEventListener("click", deleteAssiduiteModal);
|
deleteBtn?.addEventListener("click", deleteAssiduiteModal);
|
||||||
splitBtn?.addEventListener("click", () => {
|
splitBtn?.addEventListener("click", () => {
|
||||||
if (selectedAssiduite) {
|
if (selectedAssiduite) {
|
||||||
splitAssiduiteModal(selectedAssiduite);
|
splitAssiduiteModal(selectedAssiduite);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
editBtn?.addEventListener("click", () => {
|
editBtn?.addEventListener("click", () => {
|
||||||
if (selectedAssiduite) {
|
if (selectedAssiduite) {
|
||||||
editAssiduiteModal(selectedAssiduite);
|
editAssiduiteModal(selectedAssiduite);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// <<== Gestion de la récupération d'informations ==>>
|
// <<== Gestion de la récupération d'informations ==>>
|
||||||
|
@ -59,18 +59,18 @@
|
|||||||
block.style.width = `${widthPercentage}%`;
|
block.style.width = `${widthPercentage}%`;
|
||||||
|
|
||||||
if (assiduité.etat != "CRENEAU") {
|
if (assiduité.etat != "CRENEAU") {
|
||||||
if (isSingleEtud()) {
|
block.addEventListener("click", () => {
|
||||||
block.addEventListener("click", () => {
|
let deb = startDate.hours() + startDate.minutes() / 60;
|
||||||
let deb = startDate.hours() + startDate.minutes() / 60;
|
let fin = endDate.hours() + endDate.minutes() / 60;
|
||||||
let fin = endDate.hours() + endDate.minutes() / 60;
|
deb = Math.max(mt_start, deb);
|
||||||
deb = Math.max(mt_start, deb);
|
fin = Math.min(mt_end, fin);
|
||||||
fin = Math.min(mt_end, fin);
|
|
||||||
|
|
||||||
setPeriodValues(deb, fin);
|
setPeriodValues(deb, fin);
|
||||||
|
if (isSingleEtud()) {
|
||||||
updateSelectedSelect(getCurrentAssiduiteModuleImplId());
|
updateSelectedSelect(getCurrentAssiduiteModuleImplId());
|
||||||
updateJustifyBtn();
|
updateJustifyBtn();
|
||||||
});
|
}
|
||||||
}
|
});
|
||||||
//ajouter affichage assiduites on over
|
//ajouter affichage assiduites on over
|
||||||
setupAssiduiteBuble(block, assiduité);
|
setupAssiduiteBuble(block, assiduité);
|
||||||
}
|
}
|
||||||
@ -272,7 +272,9 @@
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
text-align: start;
|
text-align: start;
|
||||||
top: -40px;
|
top: -40px;
|
||||||
transform: translateX(-50%)
|
transform: translateX(-50%);
|
||||||
|
z-index: 50;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.mini_tick::after {
|
.mini_tick::after {
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<div id="studentTable">
|
<div id="studentTable">
|
||||||
<div class="thead">
|
<div class="thead">
|
||||||
<div class="tr">
|
<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>
|
<button id="addColumn" class="floating-button">+</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -52,7 +52,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.thead .tr .th {
|
.thead .tr .th {
|
||||||
height: 125px;
|
height: 200px;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -61,11 +61,12 @@
|
|||||||
|
|
||||||
.th.sticky {
|
.th.sticky {
|
||||||
z-index: 5;
|
z-index: 5;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.th,
|
.th,
|
||||||
.td {
|
.td {
|
||||||
padding: 10px;
|
padding: 20px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
width: 200px;
|
width: 200px;
|
||||||
border: 1px solid #ddd;
|
border: 1px solid #ddd;
|
||||||
@ -124,6 +125,7 @@
|
|||||||
.th {
|
.th {
|
||||||
background-color: #007BFF;
|
background-color: #007BFF;
|
||||||
color: white;
|
color: white;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tbody .tr:nth-child(even) {
|
.tbody .tr:nth-child(even) {
|
||||||
@ -143,12 +145,48 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
#moduleimpl_select {
|
#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>
|
</style>
|
||||||
<script>
|
<script>
|
||||||
let verified = false;
|
let verified = false;
|
||||||
const etatDef = "{{etat_def}}";
|
const etatDef = "{{etat_def}}";
|
||||||
|
|
||||||
|
let forceModule = "{{ forcer_module }}"
|
||||||
|
forceModule = forceModule == "True" ? true : false
|
||||||
|
|
||||||
moment.tz.setDefault("Etc/UTC");
|
moment.tz.setDefault("Etc/UTC");
|
||||||
function createColumn() {
|
function createColumn() {
|
||||||
let table = document.getElementById("studentTable");
|
let table = document.getElementById("studentTable");
|
||||||
@ -156,11 +194,22 @@
|
|||||||
th.classList.add("th");
|
th.classList.add("th");
|
||||||
const col_id = `${document.querySelectorAll("[col]").length + 1}`;
|
const col_id = `${document.querySelectorAll("[col]").length + 1}`;
|
||||||
th.setAttribute("col", col_id);
|
th.setAttribute("col", col_id);
|
||||||
|
th.setAttribute("activated", "true");
|
||||||
th.innerHTML = `
|
th.innerHTML = `
|
||||||
<div class="mini-form">
|
<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="dateStart">
|
||||||
<input type="datetime-local" id="dateEnd">
|
<input type="datetime-local" id="dateEnd">
|
||||||
{{moduleimpl_select|safe}}
|
{{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>
|
</div>
|
||||||
`;
|
`;
|
||||||
table
|
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) {
|
function defaultDate(element) {
|
||||||
const num = element.parentElement.parentElement.getAttribute("col") - 1;
|
const num = previousCol(element.parentElement.parentElement)?.getAttribute("col");
|
||||||
const last = [...document.querySelectorAll(`[col='${num}'] #dateEnd`)].pop();
|
const last = document.querySelector(`[col='${num}'] #dateEnd`);
|
||||||
let date = undefined;
|
let date = undefined;
|
||||||
if (last == undefined) {
|
if (last == undefined) {
|
||||||
date = moment().tz("Europe/Paris").format("YYYY-MM-DDTHH:mm");
|
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) {
|
function getEtatCol(colId) {
|
||||||
const etats = {};
|
const etats = {};
|
||||||
const tds = [...document.querySelectorAll(`.td[colid='${colId}']`)]
|
const tds = [...document.querySelectorAll(`.td[colid='${colId}']`)]
|
||||||
@ -266,6 +385,8 @@
|
|||||||
|
|
||||||
cols.forEach((col) => {
|
cols.forEach((col) => {
|
||||||
const col_id = col.getAttribute("col");
|
const col_id = col.getAttribute("col");
|
||||||
|
if (col.getAttribute("activated") == "false") return;
|
||||||
|
toggleColumn(col_id);
|
||||||
const etats = getEtatCol(col_id);
|
const etats = getEtatCol(col_id);
|
||||||
|
|
||||||
const inputDeb = col.querySelector("#dateStart").value;
|
const inputDeb = col.querySelector("#dateStart").value;
|
||||||
@ -273,10 +394,27 @@
|
|||||||
const moduleSelect = col.querySelector("#moduleimpl_select").value;
|
const moduleSelect = col.querySelector("#moduleimpl_select").value;
|
||||||
|
|
||||||
if (inputDeb == "" || inputFin == "") {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
// TODO Mettre une erreur lorsque moduleimpl forcé (pref)
|
|
||||||
// TODO Mettre une erreur lorsque assiduité forcé (pref)
|
// TODO Mettre une erreur lorsque assiduité forcé (pref)
|
||||||
|
|
||||||
Object.keys(etats).forEach((key) => {
|
Object.keys(etats).forEach((key) => {
|
||||||
@ -297,7 +435,9 @@
|
|||||||
|
|
||||||
openAlertModal("Erreur(s) détéctée(s)", texte)
|
openAlertModal("Erreur(s) détéctée(s)", texte)
|
||||||
} else {
|
} else {
|
||||||
createAllAssiduites(assiduites);
|
if (assiduites.length > 0) {
|
||||||
|
createAllAssiduites(assiduites);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@
|
|||||||
<div class="action-buttons">
|
<div class="action-buttons">
|
||||||
<button id="delete" class="btnPrompt" disabled>Supprimer</button>
|
<button id="delete" class="btnPrompt" disabled>Supprimer</button>
|
||||||
<button id="split" class="btnPrompt" disabled>Séparer</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>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -489,7 +489,6 @@ def get_etat_abs_date():
|
|||||||
@permission_required(Permission.ScoAbsChange)
|
@permission_required(Permission.ScoAbsChange)
|
||||||
def signal_assiduites_diff():
|
def signal_assiduites_diff():
|
||||||
group_ids: list[int] = request.args.get("group_ids", None)
|
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)
|
formsemestre_id: int = request.args.get("formsemestre_id", -1)
|
||||||
etudiants: list[dict] = []
|
etudiants: list[dict] = []
|
||||||
|
|
||||||
@ -503,9 +502,6 @@ def signal_assiduites_diff():
|
|||||||
|
|
||||||
formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id)
|
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:
|
if group_ids is None:
|
||||||
group_ids = []
|
group_ids = []
|
||||||
else:
|
else:
|
||||||
@ -514,6 +510,13 @@ def signal_assiduites_diff():
|
|||||||
|
|
||||||
groups_infos = sco_groups_view.DisplayedGroupsInfos(group_ids)
|
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(
|
etudiants.extend(
|
||||||
[
|
[
|
||||||
sco_etud.get_etud_info(etudid=m["etudid"], filled=True)[0]
|
sco_etud.get_etud_info(etudid=m["etudid"], filled=True)[0]
|
||||||
@ -553,7 +556,14 @@ def signal_assiduites_diff():
|
|||||||
"assiduites/signal_assiduites_diff.j2",
|
"assiduites/signal_assiduites_diff.j2",
|
||||||
etudiants=etudiants,
|
etudiants=etudiants,
|
||||||
etat_def=sco_preferences.get_preference("assi_etat_defaut"),
|
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),
|
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,
|
gr=gr_tit,
|
||||||
sem=sem["titre_num"],
|
sem=sem["titre_num"],
|
||||||
),
|
),
|
||||||
|
Loading…
Reference in New Issue
Block a user