aboutsummaryrefslogtreecommitdiff
path: root/src/mass-graduation.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/mass-graduation.js')
-rw-r--r--src/mass-graduation.js281
1 files changed, 52 insertions, 229 deletions
diff --git a/src/mass-graduation.js b/src/mass-graduation.js
index 48d23ad..a761130 100644
--- a/src/mass-graduation.js
+++ b/src/mass-graduation.js
@@ -1,111 +1,59 @@
-import {
- OBSERVATION_TYPES,
- GraduationChange,
- submitGraduationChange,
- Observation,
- submitObservation,
-} from "./graduation-ENV.ts";
+import { GraduationChange, submitGraduationChange } from "./graduation-ENV.ts";
import { fetchGroups } from "./group-fetch.ts";
import { initSelection } from "./selection.js";
-import { getName, DATETIME_FMT, datetimeStringNow } from "./utils-ENV.js";
+import { getName } from "./utils-ENV.js";
let group;
let name;
-function toggle(btn, others) {
+function toggle(btn) {
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 = `
-<tr>
- <th></th>
- <th class="group-member-observation-table-yes">Ja</th>
- <th class="group-member-observation-table-no">Nein</th>
- <th class="group-member-observation-table-maybe">Kann ich nicht beurteilen</th>
-</tr>`;
-
- 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);
+// 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;
+}
- const obsMaybe = document.createElement("td");
- obsMaybe.innerHTML = "X";
- obsMaybe.dataset.maybe = "true";
- obsMaybe.classList.add("group-member-observation-table-maybe");
- obsTr.appendChild(obsMaybe);
+function chooseMandatory(graduations) {
+ graduations.sort((g1, g2) => g1.mandatory - g2.mandatory);
- obsYes.addEventListener("click", () => {
- toggle(obsYes, [obsNo, obsMaybe]);
- });
- obsNo.addEventListener("click", () => {
- toggle(obsNo, [obsYes, obsMaybe]);
- });
- obsMaybe.addEventListener("click", () => {
- toggle(obsMaybe, [obsYes, obsNo]);
- });
+ // Get all graduations with smaller mandatory amount than the one with the highest amount
+ const mandatoryCandidates = graduations.filter(
+ (g) => g.mandatory < graduations[graduations.length - 1].mandatory,
+ );
+ let rest;
- obsTbdy.appendChild(obsTr);
- }
- // Toggle the observation container visibility
+ // All graduations have the same mandatory amount
+ if (mandatoryCandidates.length === 0) {
+ mandatoryCandidates = graduations;
+ rest = [];
} else {
- if (observationDiv.style.display === "none") {
- observationDiv.style.display = "block";
- li.style.background = "lightgray";
- } else {
- observationDiv.style.display = "none";
- li.style.background = "unset";
- }
+ 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(selected) {
@@ -114,17 +62,20 @@ async function loadGroup(selected) {
const graduationPromises = [];
document.getElementById("group-content").style.display = "block";
+ const mul = document.getElementById("group-mandatory-members");
const ul = document.getElementById("group-members");
- // Clear group list
+
+ mul.innerHTML = "";
ul.innerHTML = "";
+ const listEntries = [];
for (const student of students) {
const graduationPromise = student.getGraduation();
+ graduationPromises.push(graduationPromise);
const li = document.createElement("li");
- li.classList.add("group-member");
- // Remember the student of the entry
li.student = student;
+ listEntries.push(li);
const i = document.createElement("img");
i.classList.add("group-member-icon");
@@ -132,26 +83,19 @@ async function loadGroup(selected) {
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 ob = document.createElement("button");
- ob.classList.add("group-member-observation-icon");
-
- graduationPromise.then((graduation) => {
- if (!graduation.isObserved()) {
- return;
- }
- ob.innerHTML = "&#128065";
- 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}`);
@@ -160,91 +104,13 @@ async function loadGroup(selected) {
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";
+ if (chosen.includes(student.graduation)) {
+ li.classList.add("group-mandatory-member");
+ mul.appendChild(li);
} 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);
+ li.classList.add("group-member");
+ ul.appendChild(li);
}
- row.appendChild(btnCell);
-
- observationReuqestsNode.appendChild(row);
}
}
@@ -275,15 +141,6 @@ function submitMassGraduation() {
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)
@@ -308,40 +165,6 @@ function submitMassGraduation() {
});
}
-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 = `
-<h2>Dokuzettel</h2>
-<h3>${pointType}</h3>
-<p>Schüler*in: ${li.student.name}</p>
-<p>Datum: ${dateStr}</p>
-<p>Lehrkraft: ${name}</p>
-<p>Klassenleitung: TODO</p>
-<h3>Begründung</h3>
-<p>${reason}</p>
-`;
-
- 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();