forked from ScoDoc/ScoDoc
Update opolka/ScoDoc from ScoDoc/ScoDoc #2
@ -36,10 +36,10 @@
|
|||||||
|
|
||||||
.infos {
|
.infos {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: fit-content;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-evenly;
|
justify-content: start;
|
||||||
align-content: center;
|
align-content: center;
|
||||||
|
gap: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#datestr {
|
#datestr {
|
||||||
@ -48,7 +48,7 @@
|
|||||||
border: 1px #444 solid;
|
border: 1px #444 solid;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
min-width: 100px;
|
min-width: 250px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
min-height: 20px;
|
min-height: 20px;
|
||||||
}
|
}
|
||||||
|
@ -112,6 +112,7 @@ function validateSelectors(btn) {
|
|||||||
getAssiduitesFromEtuds(true);
|
getAssiduitesFromEtuds(true);
|
||||||
|
|
||||||
document.querySelector(".selectors").disabled = true;
|
document.querySelector(".selectors").disabled = true;
|
||||||
|
$("#tl_date").datepicker("option", "disabled", true);
|
||||||
generateMassAssiduites();
|
generateMassAssiduites();
|
||||||
generateAllEtudRow();
|
generateAllEtudRow();
|
||||||
btn.remove();
|
btn.remove();
|
||||||
@ -173,6 +174,7 @@ function uniqueCheckBox(box) {
|
|||||||
* @param {CallableFunction} errors fonction à effectuer en cas d'échec
|
* @param {CallableFunction} errors fonction à effectuer en cas d'échec
|
||||||
*/
|
*/
|
||||||
function sync_get(path, success, errors) {
|
function sync_get(path, success, errors) {
|
||||||
|
//TODO Optimiser : rendre asynchrone + sans jquery
|
||||||
console.log("sync_get " + path);
|
console.log("sync_get " + path);
|
||||||
$.ajax({
|
$.ajax({
|
||||||
async: false,
|
async: false,
|
||||||
@ -188,16 +190,21 @@ function sync_get(path, success, errors) {
|
|||||||
* @param {CallableFunction} success fonction à effectuer en cas de succès
|
* @param {CallableFunction} success fonction à effectuer en cas de succès
|
||||||
* @param {CallableFunction} errors fonction à effectuer en cas d'échec
|
* @param {CallableFunction} errors fonction à effectuer en cas d'échec
|
||||||
*/
|
*/
|
||||||
function async_get(path, success, errors) {
|
async function async_get(path, success, errors) {
|
||||||
console.log("async_get " + path);
|
console.log("async_get " + path);
|
||||||
$.ajax({
|
try {
|
||||||
async: true,
|
const response = await fetch(path);
|
||||||
type: "GET",
|
if (response.ok) {
|
||||||
url: path,
|
const data = await response.json();
|
||||||
success: success,
|
success(data);
|
||||||
error: errors,
|
} else {
|
||||||
});
|
throw new Error("Network response was not ok.");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
errors(error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fait une requête POST de façon synchrone
|
* Fait une requête POST de façon synchrone
|
||||||
* @param {String} path adresse distante
|
* @param {String} path adresse distante
|
||||||
@ -206,6 +213,7 @@ function async_get(path, success, errors) {
|
|||||||
* @param {CallableFunction} errors fonction à effectuer en cas d'échec
|
* @param {CallableFunction} errors fonction à effectuer en cas d'échec
|
||||||
*/
|
*/
|
||||||
function sync_post(path, data, success, errors) {
|
function sync_post(path, data, success, errors) {
|
||||||
|
//TODO Optimiser : rendre asynchrone + sans jquery
|
||||||
console.log("sync_post " + path);
|
console.log("sync_post " + path);
|
||||||
$.ajax({
|
$.ajax({
|
||||||
async: false,
|
async: false,
|
||||||
@ -223,17 +231,28 @@ function sync_post(path, data, success, errors) {
|
|||||||
* @param {CallableFunction} success fonction à effectuer en cas de succès
|
* @param {CallableFunction} success fonction à effectuer en cas de succès
|
||||||
* @param {CallableFunction} errors fonction à effectuer en cas d'échec
|
* @param {CallableFunction} errors fonction à effectuer en cas d'échec
|
||||||
*/
|
*/
|
||||||
function async_post(path, data, success, errors) {
|
async function async_post(path, data, success, errors) {
|
||||||
console.log("sync_post " + path);
|
console.log("async_post " + path);
|
||||||
return $.ajax({
|
try {
|
||||||
async: true,
|
const response = await fetch(path, {
|
||||||
type: "POST",
|
method: "POST",
|
||||||
url: path,
|
headers: {
|
||||||
data: JSON.stringify(data),
|
"Content-Type": "application/json",
|
||||||
success: success,
|
},
|
||||||
error: errors,
|
body: JSON.stringify(data),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
const responseData = await response.json();
|
||||||
|
success(responseData);
|
||||||
|
} else {
|
||||||
|
throw new Error("Network response was not ok.");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
errors(error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// <<== Gestion des actions de masse ==>>
|
// <<== Gestion des actions de masse ==>>
|
||||||
const massActionQueue = new Map();
|
const massActionQueue = new Map();
|
||||||
|
|
||||||
@ -583,10 +602,13 @@ function formatDate(date, styles = { dateStyle: "full" }) {
|
|||||||
*/
|
*/
|
||||||
function updateDate() {
|
function updateDate() {
|
||||||
const dateInput = document.querySelector("#tl_date");
|
const dateInput = document.querySelector("#tl_date");
|
||||||
|
let date = $(dateInput).datepicker("getDate");
|
||||||
|
|
||||||
|
if (date == null) {
|
||||||
|
date = new Date(Date.fromFRA(dateInput.value));
|
||||||
|
}
|
||||||
|
|
||||||
const date = dateInput.valueAsDate ?? new Date();
|
|
||||||
let dateStr = "";
|
let dateStr = "";
|
||||||
|
|
||||||
if (!verifyNonWorkDays(date.getDay(), nonWorkDays)) {
|
if (!verifyNonWorkDays(date.getDay(), nonWorkDays)) {
|
||||||
dateStr = formatDate(date).capitalize();
|
dateStr = formatDate(date).capitalize();
|
||||||
} else {
|
} else {
|
||||||
@ -606,7 +628,11 @@ function updateDate() {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
openAlertModal("Attention", div, "", "#eec660");
|
openAlertModal("Attention", div, "", "#eec660");
|
||||||
dateInput.value = lastWorkDay.toISOString().split("T")[0];
|
$(dateInput).datepicker(
|
||||||
|
"setDate",
|
||||||
|
Date.toFRA(lastWorkDay.toIsoUtcString().split("T")[0])
|
||||||
|
);
|
||||||
|
|
||||||
dateStr = formatDate(lastWorkDay).capitalize();
|
dateStr = formatDate(lastWorkDay).capitalize();
|
||||||
}
|
}
|
||||||
document.querySelector("#datestr").textContent = dateStr;
|
document.querySelector("#datestr").textContent = dateStr;
|
||||||
@ -639,15 +665,15 @@ function setupDate(onchange = null) {
|
|||||||
const input = document.querySelector("#tl_date");
|
const input = document.querySelector("#tl_date");
|
||||||
|
|
||||||
datestr.addEventListener("click", () => {
|
datestr.addEventListener("click", () => {
|
||||||
if (!input.disabled) {
|
if (!document.querySelector(".selectors").disabled) {
|
||||||
try {
|
try {
|
||||||
input.showPicker();
|
document.querySelector(".infos .ui-datepicker-trigger").click();
|
||||||
} catch {}
|
} catch {}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (onchange != null) {
|
if (onchange != null) {
|
||||||
input.addEventListener("change", onchange);
|
$(input).change(onchange);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -726,7 +752,7 @@ function getTimeLineTimes() {
|
|||||||
//getPeriodValues() -> retourne la position de la timeline [a,b] avec a et b des number
|
//getPeriodValues() -> retourne la position de la timeline [a,b] avec a et b des number
|
||||||
let values = getPeriodValues();
|
let values = getPeriodValues();
|
||||||
//On récupère la date
|
//On récupère la date
|
||||||
const dateiso = document.querySelector("#tl_date").value;
|
const dateiso = getDate().format("YYYY-MM-DD");
|
||||||
|
|
||||||
//On génère des objets temps
|
//On génère des objets temps
|
||||||
values = values.map((el) => {
|
values = values.map((el) => {
|
||||||
@ -757,9 +783,10 @@ function isConflictSameAsPeriod(conflict, period = undefined) {
|
|||||||
* @returns {Date} la date sélectionnée
|
* @returns {Date} la date sélectionnée
|
||||||
*/
|
*/
|
||||||
function getDate() {
|
function getDate() {
|
||||||
const date = new Date(document.querySelector("#tl_date").value);
|
const date =
|
||||||
date.setHours(0, 0, 0, 0);
|
$("#tl_date").datepicker("getDate") ??
|
||||||
return date;
|
new Date(Date.fromFRA(document.querySelector("#tl_date").value));
|
||||||
|
return date.startOf("day");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -768,10 +795,7 @@ function getDate() {
|
|||||||
*/
|
*/
|
||||||
function getNextDate() {
|
function getNextDate() {
|
||||||
const date = getDate();
|
const date = getDate();
|
||||||
const next = new Date(date.valueOf());
|
return date.clone().add(1, "days");
|
||||||
next.setDate(date.getDate() + 1);
|
|
||||||
next.setHours(0, 0, 0, 0);
|
|
||||||
return next;
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Retourne un objet date représentant le jour précédent
|
* Retourne un objet date représentant le jour précédent
|
||||||
@ -779,10 +803,7 @@ function getNextDate() {
|
|||||||
*/
|
*/
|
||||||
function getPrevDate() {
|
function getPrevDate() {
|
||||||
const date = getDate();
|
const date = getDate();
|
||||||
const next = new Date(date.valueOf());
|
return date.clone().add(-1, "days");
|
||||||
next.setDate(date.getDate() - 1);
|
|
||||||
next.setHours(0, 0, 0, 0);
|
|
||||||
return next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -790,31 +811,6 @@ function getPrevDate() {
|
|||||||
* @param {Date} date
|
* @param {Date} date
|
||||||
* @returns {string} la date iso avec le timezone
|
* @returns {string} la date iso avec le timezone
|
||||||
*/
|
*/
|
||||||
function toIsoString(date) {
|
|
||||||
var tzo = -date.getTimezoneOffset(),
|
|
||||||
dif = tzo >= 0 ? "+" : "-",
|
|
||||||
pad = function (num) {
|
|
||||||
return (num < 10 ? "0" : "") + num;
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
date.getFullYear() +
|
|
||||||
"-" +
|
|
||||||
pad(date.getMonth() + 1) +
|
|
||||||
"-" +
|
|
||||||
pad(date.getDate()) +
|
|
||||||
"T" +
|
|
||||||
pad(date.getHours()) +
|
|
||||||
":" +
|
|
||||||
pad(date.getMinutes()) +
|
|
||||||
":" +
|
|
||||||
pad(date.getSeconds()) +
|
|
||||||
dif +
|
|
||||||
pad(Math.floor(Math.abs(tzo) / 60)) +
|
|
||||||
":" +
|
|
||||||
pad(Math.abs(tzo) % 60)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transforme un temps numérique en une date
|
* Transforme un temps numérique en une date
|
||||||
@ -823,7 +819,7 @@ function toIsoString(date) {
|
|||||||
*/
|
*/
|
||||||
function numberTimeToDate(nb) {
|
function numberTimeToDate(nb) {
|
||||||
time = toTime(nb).replace("h", ":");
|
time = toTime(nb).replace("h", ":");
|
||||||
date = document.querySelector("#tl_date").value;
|
date = getDate().format("YYYY-MM-DD");
|
||||||
|
|
||||||
datetime = `${date}T${time}`;
|
datetime = `${date}T${time}`;
|
||||||
|
|
||||||
@ -843,8 +839,8 @@ function numberTimeToDate(nb) {
|
|||||||
function getAssiduitesFromEtuds(clear, deb, fin) {
|
function getAssiduitesFromEtuds(clear, deb, fin) {
|
||||||
const etudIds = Object.keys(etuds).join(",");
|
const etudIds = Object.keys(etuds).join(",");
|
||||||
|
|
||||||
const date_debut = deb ? deb : toIsoString(getPrevDate());
|
const date_debut = deb ? deb : getPrevDate().toIsoUtcString();
|
||||||
const date_fin = fin ? fin : toIsoString(getNextDate());
|
const date_fin = fin ? fin : getNextDate().toIsoUtcString();
|
||||||
|
|
||||||
if (clear) {
|
if (clear) {
|
||||||
assiduites = {};
|
assiduites = {};
|
||||||
@ -1137,8 +1133,8 @@ function getAssiduiteValue(field) {
|
|||||||
* @param {String | Number} etudid identifiant de l'étudiant
|
* @param {String | Number} etudid identifiant de l'étudiant
|
||||||
*/
|
*/
|
||||||
function actualizeEtudAssiduite(etudid) {
|
function actualizeEtudAssiduite(etudid) {
|
||||||
const date_debut = toIsoString(getPrevDate());
|
const date_debut = getPrevDate().toIsoUtcString();
|
||||||
const date_fin = toIsoString(getNextDate());
|
const date_fin = getNextDate().toIsoUtcString();
|
||||||
|
|
||||||
const url_api =
|
const url_api =
|
||||||
getUrl() +
|
getUrl() +
|
||||||
|
@ -1,3 +1,53 @@
|
|||||||
|
/**
|
||||||
|
* Transforme une date du format français (DD/MM/YYYY) au format iso (YYYY-MM-DD)
|
||||||
|
* Exemple d'utilisation :
|
||||||
|
* new Date(Date.fromFRA("30/06/2024")) -> new Date("2024-06-30")
|
||||||
|
* @param {string} dateFra
|
||||||
|
* @returns {string} dateIso
|
||||||
|
*/
|
||||||
|
Date.fromFRA = function (dateFra) {
|
||||||
|
if (dateFra == "") return "";
|
||||||
|
// Expression régulière pour valider le format de date ISO (YYYY-MM-DD)
|
||||||
|
const regexDateFra = /^(0[1-9]|[12][0-9]|3[01])\/(0[1-9]|1[0-2])\/\d{4}$/;
|
||||||
|
|
||||||
|
// Vérification du format de la date ISO
|
||||||
|
if (!regexDateFra.test(dateFra)) {
|
||||||
|
throw new Error(
|
||||||
|
`La date (format français) passée en paramètre [${dateFra}] n'est pas valide.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Conversion du format français (DD/MM/YYYY) au format ISO (YYYY-MM-DD)
|
||||||
|
return `${dateFra.substring(6, 10)}-${dateFra.substring(
|
||||||
|
3,
|
||||||
|
5
|
||||||
|
)}-${dateFra.substring(0, 2)}`;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Transforme une date du format iso (YYYY-MM-DD) au format français (DD/MM/YYYY)
|
||||||
|
* Exemple d'utilisation :
|
||||||
|
* Date.toFRA("2024-06-30") -> "30/06/2024"
|
||||||
|
* @param {string} dateIso
|
||||||
|
* @returns {string} dateFra
|
||||||
|
*/
|
||||||
|
Date.toFRA = function (dateIso) {
|
||||||
|
if (dateIso == "") return "";
|
||||||
|
// Expression régulière pour valider le format de date ISO (YYYY-MM-DD)
|
||||||
|
const regexDateIso = /^\d{4}-(0\d|1[0-2])-([0-2]\d|3[01])$/;
|
||||||
|
|
||||||
|
// Vérification du format de la date ISO
|
||||||
|
if (!regexDateIso.test(dateIso)) {
|
||||||
|
throw new Error(
|
||||||
|
`La date ISO passée en paramètre [${dateIso}] n'est pas valide.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Conversion du format ISO (YYYY-MM-DD) en format français (DD/MM/YYYY)
|
||||||
|
return `${dateIso.substring(8, 10)}/${dateIso.substring(
|
||||||
|
5,
|
||||||
|
7
|
||||||
|
)}/${dateIso.substring(0, 4)}`;
|
||||||
|
};
|
||||||
Object.defineProperty(Date.prototype, "isValid", {
|
Object.defineProperty(Date.prototype, "isValid", {
|
||||||
value: function () {
|
value: function () {
|
||||||
return !Number.isNaN(this.getTime());
|
return !Number.isNaN(this.getTime());
|
||||||
@ -175,6 +225,7 @@ Object.defineProperty(Date.prototype, "clone", {
|
|||||||
|
|
||||||
Object.defineProperty(Date.prototype, "format", {
|
Object.defineProperty(Date.prototype, "format", {
|
||||||
value: function (formatString) {
|
value: function (formatString) {
|
||||||
|
let iso = this.toIsoUtcString();
|
||||||
switch (formatString) {
|
switch (formatString) {
|
||||||
case "DD/MM/Y HH:mm":
|
case "DD/MM/Y HH:mm":
|
||||||
return this.toLocaleString("fr-FR", {
|
return this.toLocaleString("fr-FR", {
|
||||||
@ -196,10 +247,11 @@ Object.defineProperty(Date.prototype, "format", {
|
|||||||
});
|
});
|
||||||
|
|
||||||
case "YYYY-MM-DDTHH:mm":
|
case "YYYY-MM-DDTHH:mm":
|
||||||
let iso = this.toIsoUtcString();
|
|
||||||
// slice : YYYY-MM-DDTHH
|
// slice : YYYY-MM-DDTHH
|
||||||
// slice + 3 : YYYY-MM-DDTHH:mm
|
// slice + 3 : YYYY-MM-DDTHH:mm
|
||||||
return iso.slice(0, iso.indexOf(":") + 3);
|
return iso.slice(0, iso.indexOf(":") + 3);
|
||||||
|
case "YYYY-MM-DD":
|
||||||
|
return iso.slice(0, iso.indexOf("T"));
|
||||||
default:
|
default:
|
||||||
return this.toIsoUtcString();
|
return this.toIsoUtcString();
|
||||||
}
|
}
|
||||||
|
@ -12,10 +12,10 @@
|
|||||||
<!-- Statistiques d'assiduité (nb pres, nb retard, nb absence) + nb justifié -->
|
<!-- Statistiques d'assiduité (nb pres, nb retard, nb absence) + nb justifié -->
|
||||||
<h4>Statistiques d'assiduité</h4>
|
<h4>Statistiques d'assiduité</h4>
|
||||||
<div class="stats-inputs">
|
<div class="stats-inputs">
|
||||||
<label class="stats-label"> Date de début<input type="date" name="stats_date_debut" id="stats_date_debut"
|
<label class="stats-label"> Date de début<input type="text" class="datepicker" name="stats_date_debut"
|
||||||
value="{{date_debut}}"></label>
|
id="stats_date_debut" value="{{date_debut}}"></label>
|
||||||
<label class="stats-label"> Date de fin<input type="date" name="stats_date_fin" id="stats_date_fin"
|
<label class="stats-label"> Date de fin<input type="text" class="datepicker" name="stats_date_fin"
|
||||||
value="{{date_fin}}"></label>
|
id="stats_date_fin" value="{{date_fin}}"></label>
|
||||||
<button onclick="stats()">Actualiser</button>
|
<button onclick="stats()">Actualiser</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -87,20 +87,20 @@
|
|||||||
function stats() {
|
function stats() {
|
||||||
const dd_val = document.getElementById('stats_date_debut').value;
|
const dd_val = document.getElementById('stats_date_debut').value;
|
||||||
const df_val = document.getElementById('stats_date_fin').value;
|
const df_val = document.getElementById('stats_date_fin').value;
|
||||||
|
let date_debut = new Date(Date.fromFRA(dd_val));
|
||||||
if (dd_val == "" || df_val == "") {
|
let date_fin = new Date(Date.fromFRA(df_val));
|
||||||
|
if (dd_val == "" || df_val == "" || !date_debut.isValid() || !date_debut.isValid()) {
|
||||||
openAlertModal("Dates invalides", document.createTextNode('Les dates sélectionnées sont invalides'));
|
openAlertModal("Dates invalides", document.createTextNode('Les dates sélectionnées sont invalides'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const date_debut = new Date(dd_val + "T00:00");
|
date_debut = date_debut.startOf("day")
|
||||||
const date_fin = new Date(df_val + "T23:59");
|
date_fin = date_fin.endOf("day")
|
||||||
|
|
||||||
if (date_debut.valueOf() > date_fin.valueOf()) {
|
if (date_debut.isAfter(date_fin)) {
|
||||||
openAlertModal("Dates invalides", document.createTextNode('La date de début se situe après la date de fin.'));
|
openAlertModal("Dates invalides", document.createTextNode('La date de début se situe après la date de fin.'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
countAssiduites(date_debut.toIsoUtcString(), date_fin.toIsoUtcString())
|
countAssiduites(date_debut.toIsoUtcString(), date_fin.toIsoUtcString())
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
<div class="infos">
|
<div class="infos">
|
||||||
Date: <span id="datestr"></span>
|
Date: <span id="datestr"></span>
|
||||||
<input type="date" name="tl_date" id="tl_date" value="{{ date }}">
|
<input type="text" class="datepicker" name="tl_date" id="tl_date" value="{{ date }}">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{timeline|safe}}
|
{{timeline|safe}}
|
||||||
|
@ -20,7 +20,8 @@
|
|||||||
<div class="infos-button">Groupes : {{grp|safe}}</div>
|
<div class="infos-button">Groupes : {{grp|safe}}</div>
|
||||||
<div class="infos-button" style="margin-left: 24px;">Date : <span style="margin-left: 8px;"
|
<div class="infos-button" style="margin-left: 24px;">Date : <span style="margin-left: 8px;"
|
||||||
id="datestr"></span>
|
id="datestr"></span>
|
||||||
<input type="date" name="tl_date" id="tl_date" value="{{ date }}" onchange="updateDate()">
|
<input type="text" class="datepicker" name="tl_date" id="tl_date" value="{{ date }}"
|
||||||
|
onchange="updateDate()">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
{% extends "sco_page.j2" %}
|
{% extends "sco_page.j2" %}
|
||||||
|
|
||||||
{% block scripts %}
|
{% block scripts %}
|
||||||
{{ super() }}
|
{{ super() }}
|
||||||
<script src="{{scu.STATIC_DIR}}/js/etud_info.js"></script>
|
<script src="{{scu.STATIC_DIR}}/js/etud_info.js"></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block app_content %}
|
{% block app_content %}
|
||||||
@ -10,10 +10,10 @@
|
|||||||
<h2>Visualisation de l'assiduité {{gr_tit|safe}}</h2>
|
<h2>Visualisation de l'assiduité {{gr_tit|safe}}</h2>
|
||||||
|
|
||||||
<div class="stats-inputs">
|
<div class="stats-inputs">
|
||||||
<label class="stats-label"> Date de début <input type="date" name="stats_date_debut" id="stats_date_debut"
|
<label class="stats-label"> Date de début <input type="text" class="datepicker" name="stats_date_debut"
|
||||||
value="{{date_debut}}"></label>
|
id="stats_date_debut" value="{{date_debut}}"></label>
|
||||||
<label class="stats-label"> Date de fin <input type="date" name="stats_date_fin" id="stats_date_fin"
|
<label class="stats-label"> Date de fin <input type="text" class="datepicker" name="stats_date_fin"
|
||||||
value="{{date_fin}}"></label>
|
id="stats_date_fin" value="{{date_fin}}"></label>
|
||||||
<button onclick="stats()">Changer</button>
|
<button onclick="stats()">Changer</button>
|
||||||
|
|
||||||
<a style="margin-left:32px;" href="{{request.url}}&fmt=xlsx">{{scu.ICON_XLS|safe}}</a>
|
<a style="margin-left:32px;" href="{{request.url}}&fmt=xlsx">{{scu.ICON_XLS|safe}}</a>
|
||||||
@ -21,8 +21,8 @@
|
|||||||
|
|
||||||
{{tableau | safe}}
|
{{tableau | safe}}
|
||||||
|
|
||||||
<div class=""help">
|
<div class="" help">
|
||||||
Les comptes sont exprimés en {{ assi_metric | lower}}s.
|
Les comptes sont exprimés en {{ assi_metric | lower}}s.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@ -43,4 +43,4 @@ Les comptes sont exprimés en {{ assi_metric | lower}}s.
|
|||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
@ -258,7 +258,7 @@
|
|||||||
const success = () => {
|
const success = () => {
|
||||||
const separatorTime = document.getElementById("promptTime").value;
|
const separatorTime = document.getElementById("promptTime").value;
|
||||||
const dateString =
|
const dateString =
|
||||||
document.querySelector("#tl_date").value + `T${separatorTime}`;
|
getDate().format("YYYY-MM-DD") + `T${separatorTime}`;
|
||||||
const separtorDate = new Date(dateString);
|
const separtorDate = new Date(dateString);
|
||||||
|
|
||||||
const assiduite_debut = new Date(this.selectedAssiduite.date_debut);
|
const assiduite_debut = new Date(this.selectedAssiduite.date_debut);
|
||||||
|
@ -13,7 +13,8 @@
|
|||||||
*/
|
*/
|
||||||
function createMiniTimeline(assiduitesArray, day = null) {
|
function createMiniTimeline(assiduitesArray, day = null) {
|
||||||
const array = [...assiduitesArray];
|
const array = [...assiduitesArray];
|
||||||
const dateiso = day == null ? document.getElementById("tl_date").value : day;
|
|
||||||
|
const dateiso = day == null ? getDate().format("YYYY-MM-DD") : day;
|
||||||
const timeline = document.createElement("div");
|
const timeline = document.createElement("div");
|
||||||
timeline.className = "mini-timeline";
|
timeline.className = "mini-timeline";
|
||||||
if (isSingleEtud()) {
|
if (isSingleEtud()) {
|
||||||
|
@ -93,9 +93,10 @@
|
|||||||
|
|
||||||
function updateSelect(moduleimpl_id, query = "#moduleimpl_select", dateIso = null) {
|
function updateSelect(moduleimpl_id, query = "#moduleimpl_select", dateIso = null) {
|
||||||
let sem = getEtudFormSemestres()
|
let sem = getEtudFormSemestres()
|
||||||
if (dateIso == null) {
|
if (!dateIso) {
|
||||||
dateIso = document.querySelector("#tl_date").value
|
dateIso = getDate().format("YYYY-MM-DD")
|
||||||
}
|
}
|
||||||
|
|
||||||
sem = filterFormSemestres(sem, dateIso)
|
sem = filterFormSemestres(sem, dateIso)
|
||||||
const mod = getModulesImplByFormsemestre(sem)
|
const mod = getModulesImplByFormsemestre(sem)
|
||||||
populateSelect(mod, moduleimpl_id, query);
|
populateSelect(mod, moduleimpl_id, query);
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
|
import re
|
||||||
|
|
||||||
from flask import g, request, render_template, flash
|
from flask import g, request, render_template, flash
|
||||||
from flask import abort, url_for, redirect
|
from flask import abort, url_for, redirect
|
||||||
@ -319,7 +320,7 @@ def signal_assiduites_etud():
|
|||||||
render_template(
|
render_template(
|
||||||
"assiduites/pages/signal_assiduites_etud.j2",
|
"assiduites/pages/signal_assiduites_etud.j2",
|
||||||
sco=ScoData(etud),
|
sco=ScoData(etud),
|
||||||
date=date,
|
date=_dateiso_to_datefr(date),
|
||||||
morning=morning,
|
morning=morning,
|
||||||
lunch=lunch,
|
lunch=lunch,
|
||||||
timeline=_timeline(heures=",".join([f"'{s}'" for s in heures])),
|
timeline=_timeline(heures=",".join([f"'{s}'" for s in heures])),
|
||||||
@ -425,8 +426,8 @@ def bilan_etud():
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Gestion des dates du bilan (par défaut l'année scolaire)
|
# Gestion des dates du bilan (par défaut l'année scolaire)
|
||||||
date_debut: str = f"{scu.annee_scolaire()}-09-01"
|
date_debut: str = f"01/09/{scu.annee_scolaire()}"
|
||||||
date_fin: str = f"{scu.annee_scolaire()+1}-06-30"
|
date_fin: str = f"30/06/{scu.annee_scolaire()+1}"
|
||||||
|
|
||||||
# Récupération de la métrique d'assiduité
|
# Récupération de la métrique d'assiduité
|
||||||
assi_metric = scu.translate_assiduites_metric(
|
assi_metric = scu.translate_assiduites_metric(
|
||||||
@ -697,7 +698,7 @@ def signal_assiduites_group():
|
|||||||
"assiduites/pages/signal_assiduites_group.j2",
|
"assiduites/pages/signal_assiduites_group.j2",
|
||||||
gr_tit=gr_tit,
|
gr_tit=gr_tit,
|
||||||
sem=sem["titre_num"],
|
sem=sem["titre_num"],
|
||||||
date=date,
|
date=_dateiso_to_datefr(date),
|
||||||
formsemestre_id=formsemestre_id,
|
formsemestre_id=formsemestre_id,
|
||||||
grp=sco_groups_view.menu_groups_choice(groups_infos),
|
grp=sco_groups_view.menu_groups_choice(groups_infos),
|
||||||
moduleimpl_select=_module_selector(formsemestre, moduleimpl_id),
|
moduleimpl_select=_module_selector(formsemestre, moduleimpl_id),
|
||||||
@ -843,7 +844,7 @@ def visu_assiduites_group():
|
|||||||
"assiduites/pages/signal_assiduites_group.j2",
|
"assiduites/pages/signal_assiduites_group.j2",
|
||||||
gr_tit=gr_tit,
|
gr_tit=gr_tit,
|
||||||
sem=sem["titre_num"],
|
sem=sem["titre_num"],
|
||||||
date=date,
|
date=_dateiso_to_datefr(date),
|
||||||
formsemestre_id=formsemestre_id,
|
formsemestre_id=formsemestre_id,
|
||||||
grp=sco_groups_view.menu_groups_choice(groups_infos),
|
grp=sco_groups_view.menu_groups_choice(groups_infos),
|
||||||
moduleimpl_select=_module_selector(formsemestre, moduleimpl_id),
|
moduleimpl_select=_module_selector(formsemestre, moduleimpl_id),
|
||||||
@ -1015,8 +1016,8 @@ def visu_assi_group():
|
|||||||
inverse=False,
|
inverse=False,
|
||||||
short=False,
|
short=False,
|
||||||
),
|
),
|
||||||
date_debut=dates["debut"],
|
date_debut=_dateiso_to_datefr(dates["debut"]),
|
||||||
date_fin=dates["fin"],
|
date_fin=_dateiso_to_datefr(dates["debut"]),
|
||||||
gr_tit=gr_tit,
|
gr_tit=gr_tit,
|
||||||
group_ids=request.args.get("group_ids", None),
|
group_ids=request.args.get("group_ids", None),
|
||||||
sco=ScoData(formsemestre=groups_infos.get_formsemestre()),
|
sco=ScoData(formsemestre=groups_infos.get_formsemestre()),
|
||||||
@ -1318,6 +1319,31 @@ def test():
|
|||||||
# --- Fonctions internes ---
|
# --- Fonctions internes ---
|
||||||
|
|
||||||
|
|
||||||
|
def _dateiso_to_datefr(date_iso: str) -> str:
|
||||||
|
"""
|
||||||
|
_dateiso_to_datefr Transforme une date iso en date format français
|
||||||
|
|
||||||
|
Args:
|
||||||
|
date_iso (str): date au format iso (YYYY-MM-DD)
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
ValueError: Si l'argument `date_iso` n'est pas au bon format
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: date au format français (DD/MM/YYYY)
|
||||||
|
"""
|
||||||
|
|
||||||
|
regex_date_iso: str = r"^\d{4}-([0]\d|1[0-2])-([0-2]\d|3[01])$"
|
||||||
|
|
||||||
|
# Vérification de la date_iso
|
||||||
|
if not re.match(regex_date_iso, date_iso):
|
||||||
|
raise ValueError(
|
||||||
|
f"La dateiso passée en paramètre [{date_iso}] n'est pas valide."
|
||||||
|
)
|
||||||
|
|
||||||
|
return f"{date_iso[8:10]}/{date_iso[5:7]}/{date_iso[0:4]}"
|
||||||
|
|
||||||
|
|
||||||
def _get_date_str(deb: datetime.datetime, fin: datetime.datetime) -> str:
|
def _get_date_str(deb: datetime.datetime, fin: datetime.datetime) -> str:
|
||||||
"""
|
"""
|
||||||
_get_date_str transforme une période en chaîne lisible
|
_get_date_str transforme une période en chaîne lisible
|
||||||
|
Loading…
Reference in New Issue
Block a user