/* Module par Seb. L. */ class releveBUT extends HTMLElement { constructor() { super(); this.shadow = this.attachShadow({ mode: 'open' }); /* Config par defaut */ this.config = { showURL: true }; /* Template du module */ this.shadow.innerHTML = this.template(); /* Style du module */ const styles = document.createElement('link'); styles.setAttribute('rel', 'stylesheet'); if (location.href.split("/")[3] == "ScoDoc") { styles.setAttribute('href', '/ScoDoc/static/css/releve-but.css'); // Scodoc } else { styles.setAttribute('href', '/assets/styles/releve-but.css'); // Passerelle } this.shadow.appendChild(styles); } listeOnOff() { this.parentElement.parentElement.classList.toggle("listeOff"); this.parentElement.parentElement.querySelectorAll(".moduleOnOff").forEach(e => { e.classList.remove("moduleOnOff") }) } moduleOnOff() { this.parentElement.classList.toggle("moduleOnOff"); } goTo() { let module = this.dataset.module; this.parentElement.parentElement.parentElement.parentElement.querySelector("#Module_" + module).scrollIntoView(); } set setConfig(config) { this.config.showURL = config.showURL ?? this.config.showURL; } set showData(data) { // this.showInformations(data); this.showSemestre(data); this.showSynthese(data); this.showEvaluations(data); this.showCustom(data); this.setOptions(data.options); this.shadow.querySelectorAll(".CTA_Liste").forEach(e => { e.addEventListener("click", this.listeOnOff) }) this.shadow.querySelectorAll(".ue, .module").forEach(e => { e.addEventListener("click", this.moduleOnOff) }) this.shadow.querySelectorAll(":not(.ueBonus)+.syntheseModule").forEach(e => { e.addEventListener("click", this.goTo) }) this.shadow.children[0].classList.add("ready"); } template() { return ` <div> <div class="wait"></div> <main class="releve"> <!---------------------------------------------------------------------------------------> <!-- Zone spéciale pour que les IUT puisse ajouter des infos locales sur la passerelle --> <!---------------------------------------------------------------------------------------> <section class=custom></section> <!---------------------------> <!-- Semestre --> <!---------------------------> <section> <h2 id="identite_etudiant"></h2> <div> <div class=infoSemestre></div> <div> <div class=decision_annee></div> <div class=decision></div> <div class="ects" id="ects_tot"></div> <div class=dateInscription>Inscrit le </div> <em>Les moyennes ci-dessus servent à situer l'étudiant dans la promotion et ne correspondent pas à des validations de compétences ou d'UE.</em> </div> </div> </section> <!---------------------------> <!-- Synthèse --> <!---------------------------> <section> <div> <div> <h2>Unités d'enseignement</h2> <em>La moyenne des ressources dans une UE dépend des poids donnés aux évaluations.</em> </div> <div class=CTA_Liste> Liste <svg xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 24 24" fill="none" stroke="#ffffff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M18 15l-6-6-6 6" /> </svg> </div> </div> <div class=synthese></div> </section> <!---------------------------> <!-- Evaluations --> <!---------------------------> <section> <div> <h2>Ressources</h2> <div class=CTA_Liste> Liste <svg xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 24 24" fill="none" stroke="#ffffff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M18 15l-6-6-6 6" /> </svg> </div> </div> <div class=evaluations></div> </section> <section> <div> <h2>Situations d'apprentissage et d'évaluation (SAÉ)</h2> <div class=CTA_Liste> Liste <svg xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 24 24" fill="none" stroke="#ffffff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M18 15l-6-6-6 6" /> </svg> </div> </div> <div class=sae></div> </section> </main> </div>`; } /********************************/ /* Informations sur l'étudiant */ /********************************/ showInformations(data) { this.shadow.querySelector(".studentPic").src = data.etudiant.photo_url || "default_Student.svg"; let output = ''; if (this.config.showURL) { output += `<a href="${data.etudiant.fiche_url}" class=info_etudiant>`; } else { output += `<div class=info_etudiant>`; } output += ` <div class=civilite> ${this.civilite(data.etudiant.civilite)} ${data.etudiant.nom} ${data.etudiant.prenom}`; if (data.etudiant.date_naissance) { output += ` <div class=dateNaissance>né${(data.etudiant.civilite == "F") ? "e" : ""} le ${this.ISOToDate(data.etudiant.date_naissance)}</div>`; } output += ` </div> <div class=numerosEtudiant> Numéro étudiant : ${data.etudiant.code_nip || "~"} - Code INE : ${data.etudiant.code_ine || "~"} </div> <div>${data.formation.titre}</div> `; if (this.config.showURL) { output += `</a>`; } else { output += `</div>`; } this.shadow.querySelector(".infoEtudiant").innerHTML = output; } /*******************************/ /* Affichage local */ /*******************************/ showCustom(data) { this.shadow.querySelector(".custom").innerHTML = data.custom || ""; } /*******************************/ /* Information sur le semestre */ /*******************************/ showSemestre(data) { let correspondanceCodes = { "ADM": "Admis", "AJD": "Admis par décision de jury", "PASD": "Passage de droit : tout n'est pas validé, mais d'après les règles du BUT, vous passez", "PAS1NCI": "Vous passez par décision de jury mais attention, vous n'avez pas partout le niveau suffisant", "RED": "Ajourné mais autorisé à redoubler", "NAR": "Non admis et non autorisé à redoubler : réorientation", "DEM": "Démission", "ABAN": "Abandon constaté sans lettre de démission", "RAT": "En attente d'un rattrapage", "EXCLU": "Exclusion dans le cadre d'une décision disciplinaire", "DEF": "Défaillance : non évalué par manque d'assiduité", "ABL": "Année blanche" } this.shadow.querySelector("#identite_etudiant").innerHTML = ` <a href="${data.etudiant.fiche_url}">${data.etudiant.nomprenom}</a> `; this.shadow.querySelector(".dateInscription").innerHTML += this.ISOToDate(data.semestre.inscription); let output = ` <div> <div class=enteteSemestre>Moyenne</div><div class=enteteSemestre>${data.semestre.notes.value}</div> <div class=rang>Rang :</div><div class=rang>${data.semestre.rang.value} / ${data.semestre.rang.total}</div> <div>Max. promo. :</div><div>${data.semestre.notes.max}</div> <div>Moy. promo. :</div><div>${data.semestre.notes.moy}</div> <div>Min. promo. :</div><div>${data.semestre.notes.min}</div> </div> <div class=absencesRecap> <div class=enteteSemestre>Absences</div><div class=enteteSemestre>1/2 jour.</div> <div class=abs>Non justifiées</div> <div>${data.semestre.absences?.injustifie ?? "-"}</div> <div class=abs>Total</div><div>${data.semestre.absences?.total ?? "-"}</div> </div>`; if(data.semestre.decision_rcue.length){ output += ` <div> <div class=enteteSemestre>RCUE</div><div></div> ${(()=>{ let output = ""; data.semestre.decision_rcue.forEach(competence=>{ output += `<div class=rang>${competence.niveau.competence.titre}</div><div>${competence.code}</div>`; }) return output; })()} </div> </div>` } output += ` <a class=photo href="${data.etudiant.fiche_url}"> <img src="${data.etudiant.photo_url || "default_Student.svg"}" alt="photo de l'étudiant" title="fiche de l'étudiant" height="120" border="0"> </a>`; /*${data.semestre.groupes.map(groupe => { return ` <div> <div class=enteteSemestre>Groupe</div><div class=enteteSemestre>${groupe.nom}</div> <div class=rang>Rang :</div><div class=rang>${groupe.rang.value} / ${groupe.rang.total}</div> <div>Max. groupe :</div><div>${groupe.notes.max}</div> <div>Moy. groupe :</div><div>${groupe.notes.min}</div> <div>Min. groupe :</div><div>${groupe.notes.min}</div> </div> `; }).join("") }*/ this.shadow.querySelector(".infoSemestre").innerHTML = output; /*if(data.semestre.decision_annee?.code){ this.shadow.querySelector(".decision_annee").innerHTML = "Décision année : " + data.semestre.decision_annee.code + " - " + correspondanceCodes[data.semestre.decision_annee.code]; }*/ this.shadow.querySelector(".decision").innerHTML = data.semestre.situation || ""; /*if (data.semestre.decision?.code) { this.shadow.querySelector(".decision").innerHTML = "Décision jury: " + (data.semestre.decision?.code || ""); }*/ this.shadow.querySelector("#ects_tot").innerHTML = "ECTS : " + (data.semestre.ECTS?.acquis ?? "-") + " / " + (data.semestre.ECTS?.total ?? "-"); } /*******************************/ /* Synthèse */ /*******************************/ showSynthese(data) { let output = ``; Object.entries(data.ues).forEach(([ue, dataUE]) => { if (dataUE.type == 1) { // UE Sport / Bonus output += ` <div> <div class="ue ueBonus"> <h3>Bonus</h3> <div>${dataUE.bonus_description}</div> </div> ${this.ueSport(dataUE.modules)} </div> `; } else { output += ` <div> <div class=ue> <h3> ${ue}${(dataUE.titre) ? " - " + dataUE.titre : ""} </h3> <div> <div class=moyenne>Moyenne : ${dataUE.moyenne?.value ?? "-"}</div> <div class=rang>Rang : ${dataUE.moyenne?.rang} / ${dataUE.moyenne?.total}</div> <div class=info> Bonus : ${dataUE.bonus || 0} - Malus : ${dataUE.malus || 0} <span class=ects> - ECTS : ${dataUE.ECTS?.acquis ?? "-"} / ${dataUE.ECTS?.total ?? "-"} </span> </div> </div>`; /*<div class=absences> <div>Abs N.J.</div><div>${dataUE.absences?.injustifie || 0}</div> <div>Total</div><div>${dataUE.absences?.total || 0}</div> </div>*/ output += ` </div> ${this.synthese(data, dataUE.ressources)} ${this.synthese(data, dataUE.saes)} </div> `; } }); this.shadow.querySelector(".synthese").innerHTML = output; } synthese(data, modules) { let output = ""; Object.entries(modules).forEach(([module, dataModule]) => { let titre = data.ressources[module]?.titre || data.saes[module]?.titre; //let url = data.ressources[module]?.url || data.saes[module]?.url; output += ` <div class=syntheseModule data-module="${module.replace(/[^a-zA-Z0-9]/g, "")}"> <div>${module} - ${titre}</div> <div> ${dataModule.moyenne} <em>Coef. ${dataModule.coef}</em> </div> </div> `; }) return output; } ueSport(modules) { let output = ""; Object.values(modules).forEach((module) => { Object.values(module.evaluations).forEach((evaluation) => { output += ` <div class=syntheseModule> <div>${module.titre} - ${evaluation.description || "Note"}</div> <div> ${evaluation.note.value ?? "-"} <em>Coef. ${evaluation.coef}</em> </div> </div> `; }) }) return output; } /*******************************/ /* Evaluations */ /*******************************/ showEvaluations(data) { this.shadow.querySelector(".evaluations").innerHTML = this.module(data.ressources); this.shadow.querySelector(".sae").innerHTML += this.module(data.saes); } module(module) { let output = ""; Object.entries(module).forEach(([numero, content]) => { output += ` <div id="Module_${numero.replace(/[^a-zA-Z0-9]/g, "")}"> <div class=module> <h3>${this.URL(content.url, `${numero} - ${content.titre}`)}</h3> <div> <div class=moyenne>Moyenne indicative : ${content.moyenne.value}</div> <div class=info> Classe : ${content.moyenne.moy} - Max : ${content.moyenne.max} - Min : ${content.moyenne.min} </div> </div> <div class=absences> <div>Abs inj.</div><div>${content.absences?.injustifie || 0}</div> <div>Total</div><div>${content.absences?.total || 0}</div> </div> </div> ${this.evaluation(content.evaluations)} </div> `; }) return output; } evaluation(evaluations) { let output = ""; evaluations.forEach((evaluation) => { output += ` <div class=eval> <div>${this.URL(evaluation.url, evaluation.description || "Évaluation")}</div> <div> ${evaluation.note.value} <em>Coef. ${evaluation.coef}</em> </div> <div class=complement> <div>Coef</div><div>${evaluation.coef}</div> <div>Max. promo.</div><div>${evaluation.note.max}</div> <div>Moy. promo.</div><div>${evaluation.note.moy}</div> <div>Min. promo.</div><div>${evaluation.note.min}</div> ${Object.entries(evaluation.poids).map(([UE, poids]) => { return ` <div>Poids ${UE}</div> <div>${poids}</div> `; }).join("")} </div> </div> `; }) return output; } /********************/ /* Options */ /********************/ setOptions(options) { Object.entries(options).forEach(([option, value]) => { if (value === false) { this.shadow.children[0].classList.add(option.replace("show", "hide")); } }); } /********************/ /* Fonctions d'aide */ /********************/ URL(href, content) { if (this.config.showURL) { return `<a href=${href}>${content}</a>`; } else { return content; } } civilite(txt) { switch (txt) { case "M": return "M."; case "F": return "Mme"; default: return ""; } } ISOToDate(ISO) { return ISO.split("-").reverse().join("/"); } } customElements.define('releve-but', releveBUT);