import { GraduationChange, submitGraduationChange } from "./graduation-ENV.ts"; import { fetchStudents } from "./student-ENV.ts"; import { getName } from "./utils-ENV.js"; let name; function toggle(btn, others) { if (btn.innerHTML === "X") { btn.innerHTML = "o"; } else { btn.innerHTML = "X"; for (const o of others) { o.innerHTML = "o"; } } const submitBtn = document.getElementById("submit-mass-graduation"); submitBtn.style.display = "inline"; submitBtn.disabled = false; document.getElementById("submit-mass-graduation-state").innerHTML = ""; } // https://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array function shuffleArray(array) { for (let i = array.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [array[i], array[j]] = [array[j], array[i]]; } return array; } function chooseMandatory(graduations) { graduations.sort((g1, g2) => g1.mandatory - g2.mandatory); // Get all graduations with smaller mandatory amount than the one with the highest amount let mandatoryCandidates = graduations.filter( (g) => g.mandatory < graduations[graduations.length - 1].mandatory, ); let rest; // All graduations have the same mandatory amount if (mandatoryCandidates.length === 0) { mandatoryCandidates = graduations; rest = []; } else { rest = graduations.filter((g) => !mandatoryCandidates.includes(g)); } // Get a random list of possible indexes const candidatesIdxs = shuffleArray([...Array(mandatoryCandidates.length).keys()]); let chosen = candidatesIdxs.slice(0, 5).map((i) => mandatoryCandidates[i]); if (chosen.length < 5) { const missing = 5 - chosen.length; const restIdxs = shuffleArray([...Array(rest.length).keys()]); chosen = chosen.concat(restIdxs.slice(0, missing).map((i) => rest[i])); } return chosen; } async function loadGroup() { const students = await fetchStudents(); const graduationPromises = []; document.getElementById("group-content").style.display = "block"; const mul = document.getElementById("group-mandatory-members"); const ul = document.getElementById("group-members"); mul.innerHTML = ""; ul.innerHTML = ""; const listEntries = []; for (const student of students) { const graduationPromise = student.getGraduation(); graduationPromises.push(graduationPromise); const li = document.createElement("li"); li.student = student; listEntries.push(li); const i = document.createElement("img"); i.classList.add("group-member-icon"); graduationPromise.then((graduation) => { i.src = graduation.getIcon(); }); li.appendChild(i); } const graduations = await Promise.all(graduationPromises); const chosen = chooseMandatory(graduations); for (const li of listEntries) { const student = li.student; const n = document.createElement("span"); n.classList.add("group-member-name"); n.innerHTML = `${student.name}`; li.appendChild(n); const btns = []; for (const col of ["green", "orange", "red"]) { const b = document.createElement("button"); btns.push(b); b.classList.add(`group-member-${col}`); b.innerHTML = "o"; li.appendChild(b); } for (const b of btns) { b.addEventListener("click", () => toggle( b, btns.filter((o) => o !== b), ), ); } if (chosen.includes(student.graduation)) { li.classList.add("group-mandatory-member"); mul.appendChild(li); } else { li.classList.add("group-member"); ul.appendChild(li); } } } function submitMassGraduation() { const state = document.getElementById("submit-mass-graduation-state"); state.innerHTML = ""; state.classList.add("submit-mass-graduation-inprogress"); state.style.display = "unset"; // TODO(muhq): await graduation promises const promises = []; for (const li of document.querySelectorAll("li.group-member, li.group-mandatory-member")) { const student = li.student; const mandatory = li.classList.contains("group-mandatory-member"); if (li.querySelector(".group-member-green").innerHTML === "X") { promises.push( submitGraduationChange( GraduationChange.newGreenPointChange(mandatory, "", name), student.graduation, ), ); } if (li.querySelector(".group-member-orange").innerHTML === "X") { promises.push( submitGraduationChange( GraduationChange.newOrangePointChange(mandatory, "", name), student.graduation, ), ); } if (li.querySelector(".group-member-red").innerHTML === "X") { promises.push( submitGraduationChange( GraduationChange.newRedPointChange(mandatory, "", name), student.graduation, ), ); } } Promise.all(promises) .then(() => { state.style.display = "inline"; state.innerHTML = "✓"; state.style.color = "green"; }) .catch((error) => { state.style.display = "inline"; state.innerHTML = "X"; state.style.color = "red"; // re-enable submit button document.getElementById("submit-mass-graduation").disabled = false; console.log(error); }) .finally(() => { state.classList.remove("submit-mass-graduation-inprogress"); }); } async function init() { document.getElementById("submit-mass-graduation").addEventListener("click", submitMassGraduation); name = getName(); loadGroup(); } if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", init); } else { init(); }