aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFlorian Fischer <florian.fischer@muhq.space>2026-08-10 14:27:35 +0200
committerFlorian Fischer <florian.fischer@muhq.space>2026-08-10 14:29:09 +0200
commitb8e99e574b8ef818a2bf428c8d92fb82e7796170 (patch)
tree19e1d1ae5432b7f67e72e91fd244fe22bd55ab89 /src
parent7c585983d91a691401d626b55583f1917c7b1328 (diff)
downloadbycs-sol-b8e99e574b8ef818a2bf428c8d92fb82e7796170.tar.gz
bycs-sol-b8e99e574b8ef818a2bf428c8d92fb82e7796170.zip
cockpit: improve graduation history
* Allow change deletion if the current user issued the change * Only the assigned coach is allowed to change the level
Diffstat (limited to 'src')
-rw-r--r--src/cockpit.js70
1 files changed, 58 insertions, 12 deletions
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);
}
}