Update opolka/ScoDoc from ScoDoc/ScoDoc #2

Merged
opolka merged 1272 commits from ScoDoc/ScoDoc:master into master 2024-05-27 09:11:04 +02:00
8 changed files with 222 additions and 51 deletions
Showing only changes of commit c6659db08a - Show all commits

View File

@ -171,6 +171,13 @@ def formsemestre_status_menubar(formsemestre: FormSemestre) -> str:
"enabled": True,
"helpmsg": "Tableau de bord du semestre",
},
{
"title": "Assiduités du semestre",
"endpoint": "assiduites.liste_assiduites_formsemestre",
"args": {"formsemestre_id": formsemestre_id},
"enabled": True,
"helpmsg": "Tableau des assiduités et des justificatifs du semestre",
},
{
"title": f"Voir la formation {formation.acronyme} (v{formation.version})",
"endpoint": "notes.ue_table",
@ -218,14 +225,6 @@ def formsemestre_status_menubar(formsemestre: FormSemestre) -> str:
"enabled": True,
"helpmsg": "",
},
# TODO: Mettre à jour avec module Assiduités
# {
# "title": "Vérifier absences aux évaluations",
# "endpoint": "notes.formsemestre_check_absences_html",
# "args": {"formsemestre_id": formsemestre_id},
# "enabled": True,
# "helpmsg": "",
# },
{
"title": "Lister tous les enseignants",
"endpoint": "notes.formsemestre_enseignants_list",

View File

@ -33,11 +33,6 @@
</div>
<script>
function loadAll() {
generate(defAnnee)
}
let formsemestre_id = "{{formsemestre_id}}"
let group_id = "{{group_id}}"
@ -74,10 +69,14 @@
defAnnee = annee;
getDeptJustificatifsFromPeriod()
loadAll();
}
function getJusti(action) {
try { getDeptJustificatifsFromPeriod(action) } catch (_) { }
}
function setterAnnee(annee) {
annee = parseInt(annee);
document.querySelector('.annee span').textContent = `Année scolaire ${annee}-${annee + 1} Changer année: `

View File

@ -0,0 +1,94 @@
{% block pageContent %}
<div class="pageContent">
<h3>Assiduites et justificatifs de <span class="rouge">{{sem}}</span> </h3>
{% include "assiduites/widgets/tableau_base.j2" %}
<h4>Assiduités :</h4>
<span class="iconline">
<a class="icon filter" onclick="filterAssi()"></a>
<a class="icon download" onclick="downloadAssi()"></a>
</span>
{% include "assiduites/widgets/tableau_assi.j2" %}
<h4>Justificatifs :</h4>
<span class="iconline">
<a class="icon filter" onclick="filterJusti()"></a>
<a class="icon download" onclick="downloadJusti()"></a>
</span>
{% include "assiduites/widgets/tableau_justi.j2" %}
</div>
<script>
const formsemestre_id = {{ formsemestre_id }};
function getFormSemestreAssiduites(action) {
const path = getUrl() + `/api/assiduites/formsemestre/${formsemestre_id}`
async_get(
path,
(data, status) => {
if (action) {
action(data)
} else {
assiduiteCallBack(data);
}
},
(data, status) => {
console.error(data, status)
errorAlert();
}
)
}
function getFormSemestreJustificatifs(action) {
const path = getUrl() + `/api/justificatifs/formsemestre/${formsemestre_id}`
async_get(
path,
(data, status) => {
if (action) {
action(data)
} else {
justificatifCallBack(data);
}
},
(data, status) => {
console.error(data, status)
errorAlert();
}
)
}
function getAssi(action) {
try { getFormSemestreAssiduites(action) } catch (_) { }
}
function getJusti(action) {
try { getFormSemestreJustificatifs(action) } catch (_) { }
}
window.addEventListener('load', () => {
filterJustificatifs = {
"columns": [
"etudid",
"entry_date",
"date_debut",
"date_fin",
"etat",
"raison",
"fichier"
],
"filters": {
}
}
filterAssiduites = {
columns: [
"etudid", "entry_date", "date_debut", "date_fin", "etat", "moduleimpl_id", "est_just"
],
"filters": {
}
}
loadAll();
})
</script>
{% endblock pageContent %}

View File

@ -117,10 +117,12 @@
}
})
const conflicts = getAssiduitesConflict(etudid);
if (conflicts.length > 0) {
updateSelectedSelect(conflicts[0].moduleimpl_id);
}
try {
const conflicts = getAssiduitesConflict(etudid);
if (conflicts.length > 0) {
updateSelectedSelect(conflicts[0].moduleimpl_id);
}
} catch { }
}, { once: true });

View File

@ -88,6 +88,10 @@
td.textContent = getModuleImpl(assiduite);
} else if (k.indexOf('est_just') != -1) {
td.textContent = assiduite[k] ? "Oui" : "Non"
} else if (k.indexOf('etudid') != -1) {
const e = getEtudiant(assiduite.etudid);
td.innerHTML = `<a class="etudinfo" id="line-${assiduite.etudid}" href="BilanEtud?etudid=${assiduite.etudid}">${e.prenom.capitalize()} ${e.nom.toUpperCase()}</a>`;
} else {
td.textContent = assiduite[k].capitalize()
}
@ -341,6 +345,10 @@
<option value="false">Non</option>
</select>
</span>
<span class="filter-line">
<span class="filter-title" for="etud">Rechercher dans les étudiants</span>
<input type="text" name="etud" id="etud" placeholder="Anne Onymous" >
</span>
</div>
`;
const span = document.createElement('span');
@ -349,7 +357,7 @@
const filterHead = html.querySelector('.filter-head');
filterHead.innerHTML = ""
let cols = ["entry_date", "date_debut", "date_fin", "etat", "moduleimpl_id", "est_just"];
let cols = ["etudid", "entry_date", "date_debut", "date_fin", "etat", "moduleimpl_id", "est_just"];
cols.forEach((k) => {
const label = document.createElement('label')
@ -401,6 +409,8 @@
l.querySelector('#moduleimpl_id').value = filterAssiduites.filters[key];
} else if (key.indexOf("est_just") != -1) {
l.querySelector('#est_just').value = filterAssiduites.filters[key];
} else if (key == "etud") {
l.querySelector('#etud').value = filterAssiduites.filters["etud"];
}
})
@ -434,18 +444,23 @@
filterAssiduites.filters[key] = l.querySelector('#moduleimpl_id').value;
} else if (key.indexOf("est_just") != -1) {
filterAssiduites.filters[key] = l.querySelector('#est_just').value;
} else if (key == "etud") {
filterAssiduites.filters["etud"] = l.querySelector('#etud').value;
}
})
getAllAssiduitesFromEtud(etudid, assiduiteCallBack)
getAssi(assiduiteCallBack)
}, () => { }, "#7059FF");
}
function downloadAssi() {
try { getAllAssiduitesFromEtud(etudid, (d) => { toCSV(d, filterAssiduites) }, true, true, assi_limit_annee) } catch (_) { }
getAssi((d) => { toCSV(d, filterAssiduites) })
}
function getAssi(action) {
try { getAllAssiduitesFromEtud(etudid, action, true, true, assi_limit_annee) } catch (_) { }
}
</script>

View File

@ -60,8 +60,6 @@
deleteJustificatif(obj_id);
}
loadAll();
}
});
@ -105,6 +103,13 @@
if (k == "formsemestre") {
return f.formsemestre === "" || (el.hasOwnProperty("formsemestre") && el.formsemestre.title.replaceAll('-', ' ').indexOf(f.formsemestre) != -1);
}
if (k == "etud") {
const e = getEtudiant(el.etudid);
const str = `${e.prenom.capitalize()} ${e.nom.toUpperCase()}`
return f.etud === "" || str.indexOf(f.etud) != -1;
}
return true;
})
@ -246,8 +251,8 @@
}
function loadAll() {
try { getAllAssiduitesFromEtud(etudid, assiduiteCallBack, true, true, assi_limit_annee) } catch (_) { }
try { getAllJustificatifsFromEtud(etudid, justificatifCallBack, true, assi_limit_annee) } catch (_) { }
try { getAssi(assiduiteCallBack) } catch { }
try { getJusti(justificatifCallBack) } catch { }
}
function order(keyword, callback = () => { }, el, assi = true) {
@ -265,6 +270,13 @@
keyValueA = getModuleImpl(a);
keyValueB = getModuleImpl(b);
}
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()}`
}
let orderDertermined = keyValueA > keyValueB;
@ -282,10 +294,10 @@
if (assi) {
orderAssiduites = !orderAssiduites;
getAllAssiduitesFromEtud(etudid, (a) => { call(a, orderAssiduites) })
getAssi((a) => { call(a, orderAssiduites) });
} else {
orderJustificatifs = !orderJustificatifs;
getAllJustificatifsFromEtud(etudid, (a) => { call(a, orderJustificatifs) })
getJusti((a) => { call(a, orderJustificatifs) });
}
}
@ -333,7 +345,6 @@
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 {
@ -412,6 +423,16 @@
askDownload(csv);
}
function getEtudiant(id) {
if (id in etuds) {
return etuds[id];
}
getSingleEtud(id);
return etuds[id];
}
</script>
<style>

View File

@ -57,17 +57,6 @@
renderPaginationButtons(justi, false);
}
function getEtudiant(id) {
if (id in etuds) {
return etuds[id];
}
getSingleEtud(id);
return etuds[id];
}
function renderTableJustificatifs(page, justificatifs) {
generateTableHead(filterJustificatifs.columns, false)
@ -256,7 +245,7 @@
// The catch is getting called only for client-side errors.
// For example the throw in the first then-promise, which is the error that came from the server.
.catch((err) => {
console.log(err);
console.error(err);
});
}
@ -425,7 +414,6 @@
return el.parentElement.querySelector('a').textContent;
});
console.log(justif_id, files);
sync_post(
path,
{
@ -562,6 +550,10 @@
<input checked type="checkbox" name="etat_valide" id="etat_valide" class="" value="modifie">
</label>
</span>
<span class="filter-line">
<span class="filter-title" for="etud">Rechercher dans les étudiants</span>
<input type="text" name="etud" id="etud" placeholder="Anne Onymous" >
</span>
${dept ? dept_html_body : ""}
</div>
`;
@ -571,7 +563,9 @@
const filterHead = html.querySelector('.filter-head');
filterHead.innerHTML = ""
let cols = ["formsemestre", "etudid", "entry_date", "date_debut", "date_fin", "etat", "raison", "fichier"];
let cols = ["etudid", "entry_date", "date_debut", "date_fin", "etat", "raison", "fichier"];
if (dept) { cols.push("formsemestre") }
cols.forEach((k) => {
const label = document.createElement('label')
@ -606,6 +600,8 @@
})
} else if (key == "formsemestre") {
l.querySelector('#formsemestre').value = filterJustificatifs.filters["formsemestre"];
} else if (key == "etudid") {
l.querySelector('#etudid').value = filterJustificatifs.filters["etud"];
}
})
@ -637,23 +633,25 @@
filterJustificatifs.filters[key] = [...l.querySelectorAll("input:checked")].map((e) => e.value);
} else if (key == "formsemestre") {
filterJustificatifs.filters["formsemestre"] = l.querySelector('#formsemestre').value;
} else if (key == "etud") {
filterJustificatifs.filters["etud"] = l.querySelector('#etud').value;
}
})
if (dept) {
loadAll();
} else {
getAllJustificatifsFromEtud(etudid, justificatifCallBack)
}
loadAll();
}, () => { }, "#7059FF");
}
function downloadJusti() {
try { getAllJustificatifsFromEtud(etudid, (d) => { toCSV(d, filterJustificatifs) }, true, assi_limit_annee) } catch {
try { getDeptJustificatifsFromPeriod((d) => { toCSV(d, filterJustificatifs) }) } catch { }
}
getJusti((d) => { toCSV(d, filterJustificatifs) })
}
function getJusti(action) {
try { getAllJustificatifsFromEtud(etudid, action, true, assi_limit_annee) } catch (_) { }
}
</script>
<style>

View File

@ -205,6 +205,49 @@ def bilan_dept():
return "\n".join(H)
@bp.route("/ListeSemestre")
@scodoc
@permission_required(Permission.ScoView)
def liste_assiduites_formsemestre():
"""
liste_assiduites_etud Affichage de toutes les assiduites et justificatifs d'un etudiant
Args:
etudid (int): l'identifiant de l'étudiant
Returns:
str: l'html généré
"""
formsemestre_id = request.args.get("formsemestre_id", -1)
formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id)
if formsemestre.dept_id != g.scodoc_dept_id:
abort(404, "FormSemestre inexistant dans ce département")
header: str = html_sco_header.sco_header(
page_title="Liste des assiduités du semestre",
init_qtip=True,
javascripts=[
"js/assiduites.js",
"libjs/moment.new.min.js",
"libjs/moment-timezone.js",
],
cssstyles=CSSSTYLES
+ [
"css/assiduites.css",
],
)
return HTMLBuilder(
header,
render_template(
"assiduites/pages/liste_semestre.j2",
sco=ScoData(formsemestre=formsemestre),
sem=formsemestre.titre_annee(),
formsemestre_id=formsemestre.id,
),
).build()
@bp.route("/SignaleAssiduiteEtud")
@scodoc
@permission_required(Permission.ScoAbsChange)