import { OBSERVATION_TYPES, GraduationChange, submitGraduationChange, Observation, submitObservation, } from "./graduation-ENV.ts"; import { fetchGroups } from "./group-fetch.ts"; import { initSelection } from "./selection.js"; import { getName, DATETIME_FMT, datetimeStringNow } from "./utils-ENV.js"; let group; let name; function toggle(btn, others) { if (btn.innerHTML === "X") { btn.innerHTML = "o"; } else { btn.innerHTML = "X"; if (others) { for (const other of others) other.innerHTML = "o"; } } document.getElementById("submit-mass-graduation").style.display = "inline"; document.getElementById("submit-mass-graduation-state").innerHTML = ""; } function observationClickHandler(li) { let observationDiv = li.observationDiv; // Build the observation container if (!observationDiv) { li.style.background = "lightgray"; observationDiv = document.createElement("div"); // Remember the observation div for this student li.observationDiv = observationDiv; observationDiv.id = `${li.student.name}-observation-container`; observationDiv.classList.add("group-member-observation-container"); li.appendChild(observationDiv); const obsTbl = document.createElement("table"); obsTbl.classList.add("group-member-observation-table"); observationDiv.appendChild(obsTbl); const obsTh = document.createElement("thead"); obsTh.innerHTML = ` Ja Nein Kann ich nicht beurteilen `; obsTbl.appendChild(obsTh); const obsTbdy = document.createElement("tbody"); obsTbl.appendChild(obsTbdy); for (const obsType of OBSERVATION_TYPES) { const obsTr = document.createElement("tr"); const obsDesc = document.createElement("td"); obsDesc.innerHTML = obsType; obsDesc.classList.add("group-member-observation-table-description"); obsTr.appendChild(obsDesc); const obsYes = document.createElement("td"); obsYes.innerHTML = "o"; obsYes.dataset.yes = "true"; obsYes.classList.add("group-member-observation-table-yes"); obsTr.appendChild(obsYes); const obsNo = document.createElement("td"); obsNo.innerHTML = "o"; obsNo.dataset.no = "true"; obsNo.classList.add("group-member-observation-table-no"); obsTr.appendChild(obsNo); const obsMaybe = document.createElement("td"); obsMaybe.innerHTML = "X"; obsMaybe.dataset.maybe = "true"; obsMaybe.classList.add("group-member-observation-table-maybe"); obsTr.appendChild(obsMaybe); obsYes.addEventListener("click", () => { toggle(obsYes, [obsNo, obsMaybe]); }); obsNo.addEventListener("click", () => { toggle(obsNo, [obsYes, obsMaybe]); }); obsMaybe.addEventListener("click", () => { toggle(obsMaybe, [obsYes, obsNo]); }); obsTbdy.appendChild(obsTr); } // Toggle the observation container visibility } else { if (observationDiv.style.display === "none") { observationDiv.style.display = "block"; li.style.background = "lightgray"; } else { observationDiv.style.display = "none"; li.style.background = "unset"; } } } async function loadGroup(selected) { group = selected; const students = await group.getStudents(); const graduationPromises = []; document.getElementById("group-content").style.display = "block"; const ul = document.getElementById("group-members"); // Clear group list ul.innerHTML = ""; for (const student of students) { const graduationPromise = student.getGraduation(); const li = document.createElement("li"); li.classList.add("group-member"); // Remember the student of the entry li.student = student; const i = document.createElement("img"); i.classList.add("group-member-icon"); graduationPromise.then((graduation) => { i.src = graduation.getIcon(); }); li.appendChild(i); const n = document.createElement("span"); n.classList.add("group-member-name"); n.innerHTML = `${student.name}`; li.appendChild(n); const ob = document.createElement("button"); ob.classList.add("group-member-observation-icon"); graduationPromise.then((graduation) => { if (!graduation.isObserved()) { return; } ob.innerHTML = "👁"; ob.addEventListener("click", () => observationClickHandler(li)); }); graduationPromises.push(graduationPromise); li.appendChild(ob); for (const col of ["green", "orange", "red"]) { const b = document.createElement("button"); b.classList.add(`group-member-${col}`); b.innerHTML = "o"; b.addEventListener("click", () => toggle(b)); li.appendChild(b); } const textarea = document.createElement("textarea"); textarea.classList.add("group-member-point-reason"); li.appendChild(textarea); const p = document.createElement("button"); p.classList.add("group-member-print"); p.innerHTML = "🖶"; p.addEventListener("click", () => printNote(li)); li.appendChild(p); ul.appendChild(li); } const graduations = await Promise.all(graduationPromises); const observations = graduations.filter( (g) => g.observationRequested || (g.observation && !g.observation.end), ); const observationReuqestsContainer = document.getElementById("observation-requests-container"); if (observations.length == 0) { observationReuqestsContainer.style.display = "none"; return; } else { observationReuqestsContainer.style.display = "unset"; } const observationReuqestsNode = document.getElementById("observation-requests"); observationReuqestsNode.innerHTML = ""; observations.sort((g1, g2) => { const g1D = g1.observationRequested ? g1.observationRequested : g1.observation.start; const g2D = g2.observationRequested ? g2.observationRequested : g2.observation.start; return g1D - g2D; }); for (const graduation of observations) { const row = document.createElement("tr"); const iconCell = document.createElement("td"); const icon = document.createElement("img"); icon.src = graduation.getIcon(); row.appendChild(iconCell); const nameCell = document.createElement("td"); nameCell.innerHTML = `${graduation.student.name}`; row.appendChild(nameCell); const dateCell = document.createElement("td"); let date; if (graduation.observationRequested) { date = graduation.observationRequested; } else { date = graduation.observation.start; } dateCell.innerHTML = DATETIME_FMT.format(date); row.appendChild(dateCell); const btnCell = document.createElement("td"); if (graduation.observation && !graduation.observation.ready()) { btnCell.innerHTML = "In Beobachtungsphase"; } else { const startBtn = document.createElement("button"); if (graduation.observationRequested) { startBtn.addEventListener("click", () => { graduation.startObservation(); //TODO(muhq): Add observation icon-button. startBtn.remove(); btnCell.innerHTML = "In Beobachtungsphase"; }); startBtn.innerHTML = `Beobachtungsphase beginnen`; startBtn.classList.add("start-observation"); } else { startBtn.addEventListener("click", () => { window.open( `/mod/page/view.php?id=93017047&userToLoad=${graduation.student.id}`, "_blank", ); }); startBtn.innerHTML = `Graduierung abschließen`; startBtn.classList.add("end-observation"); } btnCell.appendChild(startBtn); } row.appendChild(btnCell); observationReuqestsNode.appendChild(row); } } 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")) { const reason = li.querySelector(".group-member-point-reason").value; const student = li.student; if (li.querySelector(".group-member-green").innerHTML === "X") { promises.push( submitGraduationChange(student, GraduationChange.newGreenPointChange(reason, name)), ); } if (li.querySelector(".group-member-orange").innerHTML === "X") { promises.push( submitGraduationChange(student, GraduationChange.newOrangePointChange(reason, name)), ); } if (li.querySelector(".group-member-red").innerHTML === "X") { promises.push( submitGraduationChange(student, GraduationChange.newRedPointChange(reason, name)), ); } if (li.observationDiv) { const status = []; for (const row of li.observationDiv.querySelectorAll("tbody > tr")) { if (row.querySelector('td[data-yes="true"]').innerHTML === "X") status.push("yes"); else if (row.querySelector('td[data-no="true"]').innerHTML === "X") status.push("no"); else status.push(""); } promises.push(submitObservation(student, new Observation(new Date(), status))); } } Promise.all(promises) .then(() => { state.style.display = "inline"; state.innerHTML = "✓"; state.style.color = "green"; for (const li of document.querySelectorAll("li.group-member")) { if (!li.observationDiv) continue; li.observationDiv.remove(); li.observationDiv = null; } }) .catch((error) => { state.style.display = "inline"; state.innerHTML = "X"; state.style.color = "red"; console.log(error); }) .finally(() => { state.classList.remove("submit-mass-graduation-inprogress"); }); } let prePrintBody = null; function printNote(li) { // save the current DOM prePrintBody = document.body; // prepare the printable red point notice const printBdy = document.createElement("body"); const reason = li.querySelector(".group-member-point-reason").value; const dateStr = datetimeStringNow(); let pointType = ""; if (li.querySelector(".group-member-orange").innerHTML === "X") { pointType = "Oranger Punkt"; } if (li.querySelector(".group-member-red").innerHTML === "X") { pointType = "Roter Punkt"; } printBdy.innerHTML = `

Dokuzettel

${pointType}

Schüler*in: ${li.student.name}

Datum: ${dateStr}

Lehrkraft: ${name}

Klassenleitung: TODO

Begründung

${reason}

`; document.body = printBdy; print(); // Restore the DOM after printing the red point note document.body = prePrintBody; } async function init() { document.getElementById("submit-mass-graduation").addEventListener("click", submitMassGraduation); name = getName(); initSelection( "group-selection", async function () { return (await fetchGroups()).values(); }, (group) => `${group.name}`, loadGroup, ); } if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", init); } else { init(); }