From b8e99e574b8ef818a2bf428c8d92fb82e7796170 Mon Sep 17 00:00:00 2001 From: Florian Fischer Date: Mon, 10 Aug 2026 14:27:35 +0200 Subject: cockpit: improve graduation history * Allow change deletion if the current user issued the change * Only the assigned coach is allowed to change the level --- cockpit.css | 29 ++++++++++++++++++++++++ cockpit.html | 30 ++++++++++++++----------- src/cockpit.js | 70 ++++++++++++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 104 insertions(+), 25 deletions(-) diff --git a/cockpit.css b/cockpit.css index 6b6295a..c9b529e 100644 --- a/cockpit.css +++ b/cockpit.css @@ -234,3 +234,32 @@ margin-top: 1rem; margin-bottom: 1rem; } + +#graduation-level-change, +#graduation-history { + border: black solid 0.2pt; + border-radius: 10px; + padding-left: 1rem; + padding-bottom: 1rem; + margin-top: 1rem; + margin-bottom: 1rem; +} + +.graduation-delete-state { + margin-left: 1rem; + position: relative; +} + +.graduation-delete-inprogress { + --size: 0.5px; + width: calc(48 * var(--size)); + height: calc(48 * var(--size)); + border: calc(5 * var(--size)) solid black; + border-bottom-color: transparent; + border-radius: 50%; + display: inline; + position: absolute; + right: -1rem; + box-sizing: border-box; + animation: rotation 1s linear infinite; +} diff --git a/cockpit.html b/cockpit.html index 8e77ffe..bda0322 100644 --- a/cockpit.html +++ b/cockpit.html @@ -71,23 +71,27 @@
Graduierung -
+
+

Graduierung abgeschlossen?

- - - - - - - - - - - -
ÄnderungDatumGrundCoachContext
+
+

Änderungsverlauf

+ + + + + + + + + + + +
ÄnderungDatumGrundCoachContext
+
diff --git a/src/cockpit.js b/src/cockpit.js index 6b2ac35..ed04cde 100644 --- a/src/cockpit.js +++ b/src/cockpit.js @@ -1,4 +1,10 @@ -import { GraduationChange, fetchGraduation, submitGraduationChange } from "./graduation-ENV.ts"; +import { assert } from "./assert.ts"; +import { + GraduationChange, + fetchGraduation, + submitGraduationChange, + deleteGraduationChange, +} from "./graduation-ENV.ts"; import { fetchStudent, fetchStudents } from "./student-ENV.ts"; import { getName, DATETIME_FMT } from "./utils-ENV.js"; @@ -133,19 +139,24 @@ function updateStudentInfo() { } async function updateStudentGraduation() { - console.assert(student.graduation, "Student has no graduation"); + assert(student.graduation, "Student has no graduation"); const graduation = student.graduation; - const levelChangeLvl = document.getElementById("graduation-level-change-level"); - levelChangeLvl.value = Math.min(graduation.level + 1, 4); - - const levelChangeBtn = document.getElementById("graduation-level-change-submit"); - levelChangeBtn.onclick = () => { - const change = GraduationChange.newLevelChange(Number(levelChangeLvl.value)); - submitGraduationChange(student.graduation, change); - updateStudentInfo(); - updateStudentGraduation(); - }; + // Only the coach is allowed to graduate + if (name === student.graduation.coach) { + const levelChangeLvl = document.getElementById("graduation-level-change-level"); + levelChangeLvl.value = Math.min(graduation.level + 1, 4); + + const levelChangeBtn = document.getElementById("graduation-level-change-submit"); + levelChangeBtn.onclick = () => { + const change = GraduationChange.newLevelChange(Number(levelChangeLvl.value), "", name); + submitGraduationChange(student.graduation, change); + updateStudentInfo(); + updateStudentGraduation(); + }; + } else { + document.getElementById("graduation-level-change").remove(); + } const changesTbl = document.getElementById("graduation-changes"); changesTbl.innerHTML = ""; @@ -164,10 +175,12 @@ async function updateStudentGraduation() { break; } + const tds = []; const addTd = (s) => { const changeTd = document.createElement("td"); changeTd.innerHTML = s; changeTr.appendChild(changeTd); + tds.push(changeTd); }; addTd(change.change); @@ -176,6 +189,39 @@ async function updateStudentGraduation() { addTd(change.coach); addTd(JSON.stringify(change.context)); + if (change.coach === name) { + const delBtn = document.createElement("button"); + delBtn.innerHTML = "Löschen"; + + delBtn.addEventListener("click", () => { + const state = document.createElement("span"); + state.classList.add("graduation-delete-state"); + + const inprogress = document.createElement("span"); + inprogress.classList.add("graduation-delete-inprogress"); + state.appendChild(inprogress); + + delBtn.replaceWith(state); + deleteGraduationChange(graduation, change) + .then(() => { + updateStudentInfo(); + state.style.display = "inline"; + state.innerHTML = "✓"; + for (const td of tds) { + td.style["text-decoration"] = "line-through"; + } + }) + .catch(() => { + state.style.display = "inline"; + state.innerHTML = "X"; + }) + .finally(() => { + inprogress.remove(); + }); + }); + changeTr.appendChild(delBtn); + } + changesTbl.appendChild(changeTr); } } -- cgit v1.2.3