From fd40558a7eadfc016197fec782d9a3b2a3f84825 Mon Sep 17 00:00:00 2001 From: Florian Fischer Date: Thu, 3 Sep 2026 20:58:48 +0200 Subject: admin-tools: remove obsolete button and add coach assignment import --- admin-tools.html | 8 ++------ doc/graduation.md | 4 ++-- src/admin-tools.js | 50 ++++++++++++++++++------------------------------ src/cockpit.js | 8 ++++---- src/graduation-common.ts | 17 ++++++++-------- src/graduation-mock.ts | 4 ++-- src/mass-graduation.js | 6 +++--- src/mock.ts | 2 +- 8 files changed, 42 insertions(+), 57 deletions(-) diff --git a/admin-tools.html b/admin-tools.html index bf9923e..5b33251 100644 --- a/admin-tools.html +++ b/admin-tools.html @@ -11,13 +11,9 @@
-
- - Coach Zuweisung CSV Import - - + Coach Zuweisung CSV Import +
diff --git a/doc/graduation.md b/doc/graduation.md index d39a374..0fce167 100644 --- a/doc/graduation.md +++ b/doc/graduation.md @@ -75,8 +75,8 @@ Changes the level of a student to the value specified in `context.level`. #### CoachZuweisung -A coach assignment change has the special studentId `-2` and may specify any number of studentIds mapped to a coach name. +A coach assignment change has the special studentId `-2` and may specify any number of studentIds mapped to an array of coach names. ```json -{"zuweisungen": {1337: "Coachy Mc Coachface"}} +{"zuweisungen": {1337: ["Coachy Mc Coachface"]}} ``` diff --git a/src/admin-tools.js b/src/admin-tools.js index d8e1bf7..bcbbcbc 100644 --- a/src/admin-tools.js +++ b/src/admin-tools.js @@ -1,5 +1,5 @@ -import { DB } from "./database-ENV.ts"; -import { fetchStudents } from "./student-ENV.ts"; +import { GraduationChange, submitGraduationChange } from "./graduation-ENV.ts"; +import { fetchStudent } from "./student-ENV.ts"; let outputNode; function output(msg) { @@ -12,42 +12,30 @@ function output(msg) { outputNode.appendChild(line); } -const studentsPromise = fetchStudents(); +async function coachAssignmentImport() { + const csv = document.getElementById("admin-tools-coach-import").value; + const assignments = {}; -async function createGraduationDbs() { - const students = await studentsPromise; - - for (const student of students) { - if (!DB.getStudentDbs(student)) { + for (const line of csv.split("\n")) { + const [studentName, ...coaches] = line.trim().split(";"); + const student = await fetchStudent(undefined, studentName); + if (student === null) { + output(`${studentName} nicht gefunden`); + continue; } + assignments[student.id] = coaches; } + + const assignmentChange = GraduationChange.newCoachAssignmentChange(assignments); + await submitGraduationChange(assignmentChange); + output("Coach Zuweisung importiert"); } async function init() { outputNode = document.getElementById("admin-tools-output"); - const students = await studentsPromise; - - output("Suche nach Datenbanken ..."); - let missing = 0; - for (const student of students) { - const dbs = await DB.getStudentDbs(student); - if (!dbs) { - output(`\t${student.name}: Datenbanken fehlen`); - missing += 3; - continue; - } - for (const type of ["shadow", "public", "submit"]) { - if (!dbs[type]) { - output(`\t${student.name} ${student.group}: ${type} Datenbank fehlt`); - missing++; - } - } - } - if (missing) { - output(`${missing} von ${students.length * 3} Datenbanken fehlen!`); - } else { - output("Alle Datenbanken vorhanden!"); - } + document + .getElementById("admin-tools-coach-import-submit") + .addEventListener("click", coachAssignmentImport); } if (document.readyState === "loading") { diff --git a/src/cockpit.js b/src/cockpit.js index f9a44f9..6830fbb 100644 --- a/src/cockpit.js +++ b/src/cockpit.js @@ -71,7 +71,7 @@ function pointClickHandler(color) { default: throw new Error("Invalid color"); } - submitGraduationChange(student.graduation, change); + submitGraduationChange(change, student.graduation); textareaDiv.style.display = "none"; updateStudentInfo(); fetchGraduation(student).then(() => updateStudentGraduation()); @@ -133,7 +133,7 @@ function updateStudentInfo() { const icon = document.getElementById("student-level-icon"); icon.src = student.graduation.getIcon(); - document.getElementById("student-info-coach").innerHTML = student.graduation.coach; + document.getElementById("student-info-coach").innerHTML = student.graduation.coaches[0] ?? ""; } document.getElementById("student-content").style.display = "block"; @@ -144,7 +144,7 @@ async function updateStudentGraduation() { const graduation = student.graduation; // Only the coach is allowed to graduate - if (name === student.graduation.coach) { + if (student.graduation.coaches.includes(name)) { document.getElementById("graduation-level-change").style.display = "block"; const levelChangeLvl = document.getElementById("graduation-level-change-level"); levelChangeLvl.value = Math.min(graduation.level + 1, 4); @@ -152,7 +152,7 @@ async function updateStudentGraduation() { const levelChangeBtn = document.getElementById("graduation-level-change-submit"); levelChangeBtn.onclick = () => { const change = GraduationChange.newLevelChange(Number(levelChangeLvl.value), "", name); - submitGraduationChange(student.graduation, change); + submitGraduationChange(change, student.graduation); updateStudentInfo(); updateStudentGraduation(); }; diff --git a/src/graduation-common.ts b/src/graduation-common.ts index ca4efde..3c90e34 100644 --- a/src/graduation-common.ts +++ b/src/graduation-common.ts @@ -16,7 +16,7 @@ const LEVEL_IMAGES = [ ]; interface CoachMapping { - [studentId: number]: string; + [studentId: number]: Array; } class GraduationChange { @@ -115,7 +115,7 @@ class GraduationChange { class Graduation { student: Student; - coach: string = ""; + coaches: Array = []; green: number = 0; orange: number = 0; red: number = 0; @@ -168,7 +168,7 @@ class Graduation { case "CoachZuweisung": // Reset the effective marks if (this.student.id in change.context.zuweisungen) - this.coach = change.context.zuweisungen[this.student.id]; + this.coaches = change.context.zuweisungen[this.student.id]; break; default: @@ -185,7 +185,7 @@ class Graduation { removeChange(change: GraduationChange) { let changes: Array = this.changes; // Reset the graduation - this.coach = ""; + this.coaches = []; this.green = 0; this.orange = 0; this.red = 0; @@ -222,16 +222,17 @@ class Graduation { } } -async function submitGraduationChange(graduation: Graduation, change: GraduationChange) { - graduation.addChange(change); +async function submitGraduationChange(change: GraduationChange, graduation?: Graduation) { + if (typeof graduation !== "undefined") graduation.addChange(change); + const db = await getGraduationDb(); - return db.saveEntry(JSON.stringify(change.dbFields())); + return await db.saveEntry(JSON.stringify(change.dbFields())); } async function deleteGraduationChange(graduation: Graduation, change: GraduationChange) { graduation.removeChange(change); const db = await getGraduationDb(); - return db.deleteEntries([change.changeId]); + return await db.deleteEntries([change.changeId]); } export { diff --git a/src/graduation-mock.ts b/src/graduation-mock.ts index f756411..8ddd7ef 100644 --- a/src/graduation-mock.ts +++ b/src/graduation-mock.ts @@ -2,8 +2,8 @@ import { LEVEL_NAMES, GraduationChange, Graduation } from "./graduation-common.t import { fetchGraduationMock as fetchGraduation } from "./mock.ts"; -async function submitGraduationChange(g: Graduation, c: GraduationChange) { - g.addChange(c); +async function submitGraduationChange(c: GraduationChange, g?: Graduation) { + if (typeof g !== "undefined") g.addChange(c); } async function deleteGraduationChange(g: Graduation, c: GraduationChange) { diff --git a/src/mass-graduation.js b/src/mass-graduation.js index 7da1c0f..b62a34a 100644 --- a/src/mass-graduation.js +++ b/src/mass-graduation.js @@ -129,24 +129,24 @@ function submitMassGraduation() { if (li.querySelector(".group-member-green").innerHTML === "X") { promises.push( submitGraduationChange( - student.graduation, GraduationChange.newGreenPointChange(mandatory, "", name), + student.graduation, ), ); } if (li.querySelector(".group-member-orange").innerHTML === "X") { promises.push( submitGraduationChange( - student.graduation, GraduationChange.newOrangePointChange(mandatory, "", name), + student.graduation, ), ); } if (li.querySelector(".group-member-red").innerHTML === "X") { promises.push( submitGraduationChange( - student.graduation, GraduationChange.newRedPointChange(mandatory, "", name), + student.graduation, ), ); } diff --git a/src/mock.ts b/src/mock.ts index d2549b3..3ffcc53 100644 --- a/src/mock.ts +++ b/src/mock.ts @@ -51,7 +51,7 @@ for (const s of students) { Graduation.from(s, [ GraduationChange.newGreenPointChange(false, "", "Florian Fischer"), GraduationChange.newGreenPointChange(false, "", "Florian Fischer"), - GraduationChange.newCoachAssignmentChange({ 2: "Florian Fischer" }), + GraduationChange.newCoachAssignmentChange({ 2: ["Florian Fischer"] }), ]), ); break; -- cgit v1.2.3