From d35e03f0b07d1af3fecd51cd4ca42a76c300db23 Mon Sep 17 00:00:00 2001 From: Florian Fischer Date: Wed, 5 Aug 2026 11:58:50 +0200 Subject: format: run prettier --- src/admin-tools.js | 4 +- src/cockpit.js | 182 ++++++++++++++++++++++--------------------- src/database-mock.ts | 9 +-- src/database-prod.ts | 27 +++---- src/graduation-common.ts | 199 ++++++++++++++++++++++++++++------------------- src/graduation-mock.ts | 4 +- src/graduation-prod.ts | 7 +- src/mass-graduation.js | 89 +++++++++++---------- src/mock.ts | 49 +++++++----- src/selection.js | 32 ++++---- src/student-mock.ts | 13 ++-- src/student-prod.ts | 35 ++++----- src/utils-common.ts | 18 ++++- src/utils-mock.js | 20 ++--- src/utils-prod.js | 12 +-- 15 files changed, 373 insertions(+), 327 deletions(-) (limited to 'src') diff --git a/src/admin-tools.js b/src/admin-tools.js index b0cf80d..d8e1bf7 100644 --- a/src/admin-tools.js +++ b/src/admin-tools.js @@ -1,5 +1,5 @@ -import { DB } from "./database.js"; -import { fetchStudents } from "./student-ENV.js"; +import { DB } from "./database-ENV.ts"; +import { fetchStudents } from "./student-ENV.ts"; let outputNode; function output(msg) { diff --git a/src/cockpit.js b/src/cockpit.js index 67619d8..97d6fed 100644 --- a/src/cockpit.js +++ b/src/cockpit.js @@ -1,6 +1,6 @@ // import { - // fetchSubjectsMock as fetchSubjects, - // fetchProgressMock as fetchProgress, +// fetchSubjectsMock as fetchSubjects, +// fetchProgressMock as fetchProgress, // } from "../../js/mock.ts"; import { @@ -8,15 +8,11 @@ import { LEVEL_NAMES, GraduationChange, fetchGraduation, - submitGraduationChange + submitGraduationChange, } from "./graduation-ENV.ts"; import { fetchStudent, fetchStudents } from "./student-ENV.ts"; -import { - getName, - DATE_FMT, - DATETIME_FMT, -} from "./utils-ENV.js"; +import { getName, DATE_FMT, DATETIME_FMT } from "./utils-ENV.js"; import { initSelection } from "./selection.js"; let name; @@ -35,7 +31,7 @@ function initStudentSelection() { "student-selection", fetchStudents, (student) => `${student.name} ${student.getGroup()}`, - loadStudent + loadStudent, ); } @@ -46,46 +42,46 @@ function pointClickHandler(color) { // TODO(muhq): Prefill the textarea with common reasons switch (color) { - case "green": - textarea.style.background = "rgb(from green r g b / 20%)"; - textarea.value = ""; - break; - case "orange": - textarea.style.background = "rgb(from orange r g b / 20%)"; - textarea.value = ""; - break; - case "red": - textarea.style.background = "rgb(from red r g b / 20%)"; - textarea.value = ""; - break; + case "green": + textarea.style.background = "rgb(from green r g b / 20%)"; + textarea.value = ""; + break; + case "orange": + textarea.style.background = "rgb(from orange r g b / 20%)"; + textarea.value = ""; + break; + case "red": + textarea.style.background = "rgb(from red r g b / 20%)"; + textarea.value = ""; + break; } textareaDiv.style.display = "block"; textarea.focus(); const coach = name; - const submit = function() { + const submit = function () { let change; switch (color) { - case "green": - change = GraduationChange.newGreenPointChange(textarea.value, coach); - break; - case "orange": - change = GraduationChange.newOrangePointChange(textarea.value, coach); - break; - case "red": - change = GraduationChange.newRedPointChange(textarea.value, coach); - break; - default: - throw new Error("Invalid color"); + case "green": + change = GraduationChange.newGreenPointChange(textarea.value, coach); + break; + case "orange": + change = GraduationChange.newOrangePointChange(textarea.value, coach); + break; + case "red": + change = GraduationChange.newRedPointChange(textarea.value, coach); + break; + default: + throw new Error("Invalid color"); } submitGraduationChange(student, change); textareaDiv.style.display = "none"; updateStudentInfo(); - student.fetchGraduation().then(() => updateStudentGraduation() ); + student.fetchGraduation().then(() => updateStudentGraduation()); }; // Use onEVENT to override any previous handler - textarea.onkeydown = function(e) { + textarea.onkeydown = function (e) { if (e.shiftKey && e.key === "Enter") { submit(); } @@ -108,12 +104,12 @@ function updateStudentInfo() { document.getElementById("student-info-icon").src = DEFAULT_STUDENT_ICON; // Try to replace the generic icon with the user's icon - var img = document.createElement('img'); - img.onload = function() { + var img = document.createElement("img"); + img.onload = function () { document.getElementById("student-info-icon").src = img.src; img = img.onload = null; }; - student.getIconUrl().then( (url) => img.src = url ); + student.getIconUrl().then((url) => (img.src = url)); document.getElementById("student-info-name").innerHTML = `${student.name}`; @@ -126,12 +122,15 @@ function updateStudentInfo() { document.getElementById("student-info-points-orange").innerHTML = student.graduation.orange; document.getElementById("student-info-points-red").innerHTML = student.graduation.red; - document.getElementById("student-info-green").addEventListener('click', - () => pointClickHandler("green")); - document.getElementById("student-info-orange").addEventListener('click', - () => pointClickHandler("orange")); - document.getElementById("student-info-red").addEventListener('click', - () => pointClickHandler("red")); + document + .getElementById("student-info-green") + .addEventListener("click", () => pointClickHandler("green")); + document + .getElementById("student-info-orange") + .addEventListener("click", () => pointClickHandler("orange")); + document + .getElementById("student-info-red") + .addEventListener("click", () => pointClickHandler("red")); renderGraduationLevel(student.graduation); @@ -152,11 +151,11 @@ function renderGraduationLevel(graduation) { } // function renderGraduationStickers(graduation, node) { - // node.innerHTML = ""; +// node.innerHTML = ""; // } // function renderGraduationBonus(graduation, node) { - // node.innerHTML = ""; +// node.innerHTML = ""; // } function renderObservationStatus(graduation, node) { @@ -167,9 +166,10 @@ function renderObservationStatus(graduation, node) { status = document.createElement("span"); status.classList.add("student-observation-status"); if (graduation.isObserved()) { - status.innerHTML = '👁 Ich befinde mich in der Beobachtungsphase zum Levelaufstieg.'; + status.innerHTML = + '👁 Ich befinde mich in der Beobachtungsphase zum Levelaufstieg.'; } else if (graduation.observationRequested) { - status.innerHTML = 'Beobachtungsphase noch nicht begonnen.'; + status.innerHTML = "Beobachtungsphase noch nicht begonnen."; } else { status.innerHTML = "Nicht in Beobachtung."; } @@ -178,7 +178,7 @@ function renderObservationStatus(graduation, node) { status.classList.add("student-request-observation-button"); // Level is 1-based status.innerHTML = `Ich will ${LEVEL_NAMES[graduation.level]} werden`; - status.addEventListener("click", async function() { + status.addEventListener("click", async function () { await graduation.requestObservation(); // Rerender the observation status renderObservationStatus(graduation, node); @@ -188,37 +188,37 @@ function renderObservationStatus(graduation, node) { } // function newProgressBar(subject) { - // let bar = document.createElement("div"); - // fetchProgress(subject).then((progress) => { - // bar.progress = progress; - // }); - - // let s1 = document.createElement("div"); - // s1.onhover - - // bar.appendChild(s1); - // let s2 = document.createElement("div"); - // bar.appendChild(s2); - // let s3 = document.createElement("div"); - // bar.appendChild(s3); - // return bar; +// let bar = document.createElement("div"); +// fetchProgress(subject).then((progress) => { +// bar.progress = progress; +// }); + +// let s1 = document.createElement("div"); +// s1.onhover + +// bar.appendChild(s1); +// let s2 = document.createElement("div"); +// bar.appendChild(s2); +// let s3 = document.createElement("div"); +// bar.appendChild(s3); +// return bar; // } // let selectedSubjects; // async function updateStudentProgress() { - // selectedSubjects = await fetchSubjects(student); - - // let prog = document.getElementById("progress"); - // for(const subj of selectedSubjects) { - // let subjDiv = document.createElement("div"); - // subjDiv.innerHTML = subj; - // subjDiv.appendChild(newProgressBar(subj)) - // prog.appendChild(subjDiv); - // } +// selectedSubjects = await fetchSubjects(student); + +// let prog = document.getElementById("progress"); +// for(const subj of selectedSubjects) { +// let subjDiv = document.createElement("div"); +// subjDiv.innerHTML = subj; +// subjDiv.appendChild(newProgressBar(subj)) +// prog.appendChild(subjDiv); +// } // } // async function updateStudentCalendar() { - // let cal = document.getElementById("calendar"); +// let cal = document.getElementById("calendar"); // } async function updateStudentGraduation() { @@ -227,26 +227,26 @@ async function updateStudentGraduation() { const changesTbl = document.getElementById("graduation-changes"); changesTbl.innerHTML = ""; - for (const change of graduation.changes.filter( - (ch) => ["Grün", "Rot", "Orange"].includes(ch.change) )) - { + for (const change of graduation.changes.filter((ch) => + ["Grün", "Rot", "Orange"].includes(ch.change), + )) { const changeTr = document.createElement("tr"); for (const key in change) { if (key == "json" || key == "id" || key == "name") continue; if (key == "change") { - switch(change.change) { - case "Grün": - changeTr.style.background = "green"; - break; - case "Rot": - changeTr.style.background = "red"; - break; - case "Orange": - changeTr.style.background = "orange"; - break; - default: - console.error(`unexpected change: ${change.change}`); + switch (change.change) { + case "Grün": + changeTr.style.background = "green"; + break; + case "Rot": + changeTr.style.background = "red"; + break; + case "Orange": + changeTr.style.background = "orange"; + break; + default: + console.error(`unexpected change: ${change.change}`); } continue; } @@ -291,7 +291,9 @@ async function updateStudentGraduation() { endDiv.style.display = "block"; - const reason = document.getElementById("graduation-current-observation-period-end-reason").value; + const reason = document.getElementById( + "graduation-current-observation-period-end-reason", + ).value; const successBtn = document.getElementById("graduation-current-observation-period-end-success"); successBtn.addEventListener("click", () => { submitGraduationChange(graduation.student, GraduationChange.newObservationEnd(reason, true)); @@ -336,7 +338,7 @@ async function initCockpit() { } } -window.onload = function() { +window.onload = function () { DEFAULT_STUDENT_ICON = document.getElementById("student-info-icon").src; name = getName(); initCockpit(); diff --git a/src/database-mock.ts b/src/database-mock.ts index 24cb08f..4d7bf55 100644 --- a/src/database-mock.ts +++ b/src/database-mock.ts @@ -14,17 +14,12 @@ class DB { async saveEntry(json: string) { console.log(`Mock DB save entry ${json}`); - return; + return; } - } async function getGraduationDb() { return new DB(); } -export { - DB, - DatabaseEntry, DatabaseParams, - getGraduationDb, -}; +export { DB, DatabaseEntry, DatabaseParams, getGraduationDb }; diff --git a/src/database-prod.ts b/src/database-prod.ts index 6a55f25..57b9974 100644 --- a/src/database-prod.ts +++ b/src/database-prod.ts @@ -23,7 +23,7 @@ const DB_TEMPLATE_LIST_FOOTER = ` let graduationDb = findGraduationDb(); -const ID_QUERY_PARAM_REGEX = /[?&]id=(\d+)/ +const ID_QUERY_PARAM_REGEX = /[?&]id=(\d+)/; async function findGraduationDb() { let graduationDbId = localStorage.getItem("gruaduationDbId"); @@ -33,16 +33,16 @@ async function findGraduationDb() { const courseUrl = `https://lernplattform.bycs.de/course/view.php?id=${getCourseId()}`; const courseRes = await fetch(courseUrl); - const courseDoc = new DOMParser().parseFromString(await courseRes.text(), 'text/html'); + const courseDoc = new DOMParser().parseFromString(await courseRes.text(), "text/html"); for (const a of courseDoc.querySelectorAll("div.activityname a.aalink")) { if (a.textContent.trim() === "Graduation Datenbank") { - const anchor = (a as HTMLAnchorElement); + const anchor = a as HTMLAnchorElement; const match = anchor.href.match(ID_QUERY_PARAM_REGEX); if (match === null) continue; const dbId = match[1]; localStorage.setItem("graduationDbId", dbId); - return new DB(Number(dbId)) + return new DB(Number(dbId)); } } console.assert(false, "Graduation DB not found"); @@ -64,13 +64,12 @@ class DB { } async fetchEntries(params?: DatabaseParams) { - return loadFromDatabaseActivity(this.id, params) + return loadFromDatabaseActivity(this.id, params); } async saveEntry(json: string) { return addEntryToDatabaseActivity(this.id, json); } - } async function loadFromDatabaseActivity(id: string | number, params?: DatabaseParams) { @@ -79,16 +78,16 @@ async function loadFromDatabaseActivity(id: string | number, params?: DatabasePa if (typeof params !== "undefined") { dbUrl += "&filter=1&advanced=1"; for (const param in params) { - dbUrl += `&${param}=${encodeURIComponent(params[param])}` + dbUrl += `&${param}=${encodeURIComponent(params[param])}`; } } const dbRes = await fetch(encodeURI(dbUrl)); - const dbDoc = new DOMParser().parseFromString(await dbRes.text(), 'text/html'); + const dbDoc = new DOMParser().parseFromString(await dbRes.text(), "text/html"); let data: any[] = []; - dbDoc.querySelectorAll('.db-row').forEach(row => { + dbDoc.querySelectorAll(".db-row").forEach((row) => { let entry: DatabaseEntry = {}; - row.querySelectorAll('.db-cell').forEach(field => { + row.querySelectorAll(".db-cell").forEach((field) => { const key = field.dataset.key!; let value; // Moodle includes the full date in the title attribute of the included span @@ -112,7 +111,7 @@ async function addEntryToDatabaseActivity(id: number, json: string) { // TODO(muhq): do not fetch the form const url = `/mod/data/edit.php?id=${id}`; const editRes = await fetch(url); - const editDoc = new DOMParser().parseFromString(await editRes.text(), 'text/html'); + const editDoc = new DOMParser().parseFromString(await editRes.text(), "text/html"); const form = editDoc.querySelector('div[role="main"] > form'); const formData = new FormData(form!); @@ -133,8 +132,4 @@ async function addEntryToDatabaseActivity(id: number, json: string) { }); } -export { - DB, - DatabaseEntry, DatabaseParams, - getGraduationDb, -}; +export { DB, DatabaseEntry, DatabaseParams, getGraduationDb }; diff --git a/src/graduation-common.ts b/src/graduation-common.ts index 61600d3..2c0fb69 100644 --- a/src/graduation-common.ts +++ b/src/graduation-common.ts @@ -1,5 +1,5 @@ -import { getGraduationDb, DatabaseEntry } from "./database-ENV.ts" -import type { Student } from "./student-common.ts" +import { getGraduationDb, DatabaseEntry } from "./database-ENV.ts"; +import type { Student } from "./student-common.ts"; import NeulingPng from "../assets/Neuling.png"; import EntdeckerPng from "../assets/Entdecker.png"; @@ -23,7 +23,14 @@ class GraduationChange { coach: string; context: any; - constructor(date: Date, studentId: number, change: string, reason: string, coach: string, context: any) { + constructor( + date: Date, + studentId: number, + change: string, + reason: string, + coach: string, + context: any, + ) { this.date = date; this.studentId = studentId; this.change = change; @@ -32,19 +39,26 @@ class GraduationChange { this.context = context; } - dbFields () { + dbFields() { return { - "studentId": this.studentId, - "change": this.change, - "reason": this.reason, - "context": this.context, + studentId: this.studentId, + change: this.change, + reason: this.reason, + context: this.context, }; } static fromDBEntry(e: DatabaseEntry) { - const {date, coach, json} = e; + const { date, coach, json } = e; const change = JSON.parse(json); - return new GraduationChange(new Date(date), change.change, change.student, change.reason, coach, change.context); + return new GraduationChange( + new Date(date), + change.change, + change.student, + change.reason, + coach, + change.context, + ); } static newObservationRequest() { @@ -56,11 +70,25 @@ class GraduationChange { } static newObservationEnd(reason: string, success: boolean) { - return new GraduationChange(new Date(), -1, "ObservationEnd", reason, "", JSON.stringify(success)); + return new GraduationChange( + new Date(), + -1, + "ObservationEnd", + reason, + "", + JSON.stringify(success), + ); } static newObservationChange(observation: Observation) { - return new GraduationChange(observation.date, -1, "Observation", "", "", JSON.stringify(observation.status)); + return new GraduationChange( + observation.date, + -1, + "Observation", + "", + "", + JSON.stringify(observation.status), + ); } static newGreenPointChange(reason: string, coach: string) { @@ -87,7 +115,17 @@ class Graduation { pastObservations: Array; changes: Array; - constructor(student: Student, green: number, orange: number, red: number, level: number, observationRequested: Date | null, observation: ObservationPeriod | null, pastObservations: Array, changes: Array) { + constructor( + student: Student, + green: number, + orange: number, + red: number, + level: number, + observationRequested: Date | null, + observation: ObservationPeriod | null, + pastObservations: Array, + changes: Array, + ) { this.student = student; this.green = green; this.orange = orange; @@ -115,63 +153,70 @@ class Graduation { for (const change of changes) { switch (change.change) { - case "Grün": - green++; - break; - - case "Orange": - orange++; - break; - - case "Rot": - red++; - break; - - case "ObservationRequest": - openObservationRequest = change.date; - break; - - case "ObservationStart": - console.assert(openObservationRequest === null, - "No request for observation start"); - - observationPeriod = new ObservationPeriod(change.date); - openObservationRequest = null; - break; - - case "ObservationEnd": - if (observationPeriod === null) { - console.error("No active observation period"); - continue; - } - observationPeriod.finishPeriod(change.context.success); - if (change.context.success) { - level++; - } - pastObservations.push(observationPeriod); - observationPeriod = null; - break; - - case "Observation": - if (observationPeriod === null) { - console.error("No active observation period"); - continue; - } - const observation = Observation.fromChange(change); - observationPeriod.addObservation(observation); - break; - - case "LevelChange": - level = change.context.level; - break; - - default: - throw new Error(`Unexpected change: ${change}`); + case "Grün": + green++; + break; + + case "Orange": + orange++; + break; + + case "Rot": + red++; + break; + + case "ObservationRequest": + openObservationRequest = change.date; + break; + + case "ObservationStart": + console.assert(openObservationRequest === null, "No request for observation start"); + + observationPeriod = new ObservationPeriod(change.date); + openObservationRequest = null; + break; + + case "ObservationEnd": + if (observationPeriod === null) { + console.error("No active observation period"); + continue; + } + observationPeriod.finishPeriod(change.context.success); + if (change.context.success) { + level++; + } + pastObservations.push(observationPeriod); + observationPeriod = null; + break; + + case "Observation": + if (observationPeriod === null) { + console.error("No active observation period"); + continue; + } + const observation = Observation.fromChange(change); + observationPeriod.addObservation(observation); + break; + + case "LevelChange": + level = change.context.level; + break; + + default: + throw new Error(`Unexpected change: ${change}`); } } - return new Graduation(student, green, orange, red, level, - openObservationRequest, observationPeriod, pastObservations, - changes); + return new Graduation( + student, + green, + orange, + red, + level, + openObservationRequest, + observationPeriod, + pastObservations, + changes, + ); } addChange(change: GraduationChange) { @@ -264,8 +309,7 @@ class ObservationPeriod { } ready() { - if (this.observations.length < 10) - return false; + if (this.observations.length < 10) return false; // at least 10 observation on different days let days = new Map(); @@ -277,14 +321,14 @@ class ObservationPeriod { } getObservationsSums() { - let sums = Array(OBSERVATION_TYPES.length).fill(null).map(() => ({"yes":0, "no":0})); + let sums = Array(OBSERVATION_TYPES.length) + .fill(null) + .map(() => ({ yes: 0, no: 0 })); for (const observation of this.observations) { for (let i = 0; i < sums.length; i++) { if (observation.status[i]) { - if (observation.status[i] === "yes") - sums[i].yes++; - else - sums[i].no++; + if (observation.status[i] === "yes") sums[i].yes++; + else sums[i].no++; } } } @@ -317,7 +361,7 @@ class Observation { } static fromChange(change: GraduationChange) { - return new Observation(change.date, JSON.parse(change.context)) + return new Observation(change.date, JSON.parse(change.context)); } } @@ -328,7 +372,7 @@ async function submitGraduationChange(graduation: Graduation, change: Graduation } async function submitObservation(graduation: Graduation, observation: Observation) { - if(graduation.observation === null) throw new Error("no active observation"); + if (graduation.observation === null) throw new Error("no active observation"); graduation.observation.addObservation(observation); await submitGraduationChange(graduation, GraduationChange.newObservationChange(observation)); } @@ -340,7 +384,6 @@ export { Graduation, submitGraduationChange, submitObservation, - OBSERVATION_TYPES, Observation, ObservationPeriod, diff --git a/src/graduation-mock.ts b/src/graduation-mock.ts index 84a7143..5c48a81 100644 --- a/src/graduation-mock.ts +++ b/src/graduation-mock.ts @@ -2,7 +2,6 @@ import { LEVEL_NAMES, GraduationChange, Graduation, - OBSERVATION_TYPES, Observation, ObservationPeriod, @@ -11,7 +10,7 @@ import { import { fetchGraduationMock as fetchGraduation, submitGraduationChangeMock as submitGraduationChange, - submitObservationMock as submitObservation + submitObservationMock as submitObservation, } from "./mock.ts"; export { @@ -21,7 +20,6 @@ export { fetchGraduation, submitGraduationChange, submitObservation, - OBSERVATION_TYPES, Observation, ObservationPeriod, diff --git a/src/graduation-prod.ts b/src/graduation-prod.ts index 975fd0f..663493a 100644 --- a/src/graduation-prod.ts +++ b/src/graduation-prod.ts @@ -1,8 +1,8 @@ -import { getGraduationDb } from "./database-ENV.ts" +import { getGraduationDb } from "./database-ENV.ts"; import { Graduation, GraduationChange } from "./graduation-common.ts"; import type { Student } from "./student-common.ts"; -const _graduationChangesPromise = async function() { +const _graduationChangesPromise = (async function () { const db = await getGraduationDb(); let changes = new Map(); let entries = await db.fetchEntries(); @@ -16,7 +16,7 @@ const _graduationChangesPromise = async function() { } } return changes; -}(); +})(); const graduations: Map = new Map(); @@ -36,7 +36,6 @@ export { Graduation, submitGraduationChange, submitObservation, - OBSERVATION_TYPES, Observation, ObservationPeriod, diff --git a/src/mass-graduation.js b/src/mass-graduation.js index b9240f0..48d23ad 100644 --- a/src/mass-graduation.js +++ b/src/mass-graduation.js @@ -3,7 +3,7 @@ import { GraduationChange, submitGraduationChange, Observation, - submitObservation + submitObservation, } from "./graduation-ENV.ts"; import { fetchGroups } from "./group-fetch.ts"; @@ -19,8 +19,7 @@ function toggle(btn, others) { } else { btn.innerHTML = "X"; if (others) { - for (const other of others) - other.innerHTML = "o"; + for (const other of others) other.innerHTML = "o"; } } @@ -31,7 +30,7 @@ function toggle(btn, others) { function observationClickHandler(li) { let observationDiv = li.observationDiv; // Build the observation container - if(!observationDiv) { + if (!observationDiv) { li.style.background = "lightgray"; observationDiv = document.createElement("div"); @@ -97,12 +96,11 @@ function observationClickHandler(li) { obsTbdy.appendChild(obsTr); } - // Toggle the observation container visibility + // 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"; @@ -148,7 +146,7 @@ async function loadGroup(selected) { return; } ob.innerHTML = "👁"; - ob.addEventListener("click", () => observationClickHandler(li) ); + ob.addEventListener("click", () => observationClickHandler(li)); }); graduationPromises.push(graduationPromise); @@ -158,7 +156,7 @@ async function loadGroup(selected) { const b = document.createElement("button"); b.classList.add(`group-member-${col}`); b.innerHTML = "o"; - b.addEventListener("click", () => toggle(b) ); + b.addEventListener("click", () => toggle(b)); li.appendChild(b); } @@ -169,7 +167,7 @@ async function loadGroup(selected) { const p = document.createElement("button"); p.classList.add("group-member-print"); p.innerHTML = "🖶"; - p.addEventListener("click", () => printNote(li) ); + p.addEventListener("click", () => printNote(li)); li.appendChild(p); ul.appendChild(li); @@ -177,7 +175,7 @@ async function loadGroup(selected) { const graduations = await Promise.all(graduationPromises); const observations = graduations.filter( - (g) => g.observationRequested || (g.observation && !g.observation.end) + (g) => g.observationRequested || (g.observation && !g.observation.end), ); const observationReuqestsContainer = document.getElementById("observation-requests-container"); @@ -234,7 +232,10 @@ async function loadGroup(selected) { startBtn.classList.add("start-observation"); } else { startBtn.addEventListener("click", () => { - window.open(`/mod/page/view.php?id=93017047&userToLoad=${graduation.student.id}`, '_blank'); + window.open( + `/mod/page/view.php?id=93017047&userToLoad=${graduation.student.id}`, + "_blank", + ); }); startBtn.innerHTML = `Graduierung abschließen`; startBtn.classList.add("end-observation"); @@ -256,50 +257,55 @@ function submitMassGraduation() { // TODO(muhq): await graduation promises const promises = []; - for(const li of document.querySelectorAll("li.group-member")) { + 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))); + promises.push( + submitGraduationChange(student, GraduationChange.newGreenPointChange(reason, name)), + ); } if (li.querySelector(".group-member-orange").innerHTML === "X") { - promises.push(submitGraduationChange(student, GraduationChange.newOrangePointChange(reason, name))); + promises.push( + submitGraduationChange(student, GraduationChange.newOrangePointChange(reason, name)), + ); } if (li.querySelector(".group-member-red").innerHTML === "X") { - promises.push(submitGraduationChange(student, GraduationChange.newRedPointChange(reason, name))); + 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(""); + 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"); - }); + 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; @@ -342,7 +348,9 @@ async function init() { initSelection( "group-selection", - async function() { return (await fetchGroups()).values(); }, + async function () { + return (await fetchGroups()).values(); + }, (group) => `${group.name}`, loadGroup, ); @@ -353,4 +361,3 @@ if (document.readyState === "loading") { } else { init(); } - diff --git a/src/mock.ts b/src/mock.ts index 220b1e3..5afe1db 100644 --- a/src/mock.ts +++ b/src/mock.ts @@ -3,9 +3,9 @@ import { Student } from "./student-common.ts"; import { buildGroups } from "./group.ts"; const students = [ - new Student(1, 'foo bar', 'test'), - new Student(2, 'maxi mustermensch', 'test'), - new Student(3, 'b b b', '5a') + new Student(1, "foo bar", "test"), + new Student(2, "maxi mustermensch", "test"), + new Student(3, "b b b", "5a"), ]; // Build the groups from our mock students @@ -16,7 +16,7 @@ async function fetchStudentsMock(_id?: number, _name?: string, _group?: string) } async function fetchSubjectsMock() { - return ['Mathe', 'Deutsch', 'Englisch']; + return ["Mathe", "Deutsch", "Englisch"]; } function fetchProgressMock(subject: string) { @@ -36,23 +36,30 @@ function fetchProgressMock(subject: string) { const graduations = new Map(); for (const s of students) { switch (s.name) { - case "foo bar": - graduations.set(s, Graduation.from(s, [ - GraduationChange.newGreenPointChange("Gute Arbeit", "Florian Fischer"), - GraduationChange.newOrangePointChange("", "Florian Fischer"), - ])); - break; - case "maxi mustermensch": - graduations.set(s, Graduation.from(s, [ - GraduationChange.newGreenPointChange("", "Florian Fischer"), - GraduationChange.newGreenPointChange("", "Florian Fischer"), - new GraduationChange(new Date(), s.id, "ObservationStart", "", "Florian Fischer", ""), - ])); - break; - case "b b b": - graduations.set(s, Graduation.from(s, [ - GraduationChange.newRedPointChange("", "Florian Fischer"), - ])); + case "foo bar": + graduations.set( + s, + Graduation.from(s, [ + GraduationChange.newGreenPointChange("Gute Arbeit", "Florian Fischer"), + GraduationChange.newOrangePointChange("", "Florian Fischer"), + ]), + ); + break; + case "maxi mustermensch": + graduations.set( + s, + Graduation.from(s, [ + GraduationChange.newGreenPointChange("", "Florian Fischer"), + GraduationChange.newGreenPointChange("", "Florian Fischer"), + new GraduationChange(new Date(), s.id, "ObservationStart", "", "Florian Fischer", ""), + ]), + ); + break; + case "b b b": + graduations.set( + s, + Graduation.from(s, [GraduationChange.newRedPointChange("", "Florian Fischer")]), + ); } } diff --git a/src/selection.js b/src/selection.js index bfaebc0..b7968af 100644 --- a/src/selection.js +++ b/src/selection.js @@ -27,7 +27,7 @@ async function initSelection(idPrefix, fetchCandidates, fmtCandidate, onSelectio let currentFocus = -1; let visibleItems = []; function setActive() { - visibleItems.forEach(item => item.classList.remove("active")); + visibleItems.forEach((item) => item.classList.remove("active")); if (currentFocus >= 0 && visibleItems[currentFocus]) { visibleItems[currentFocus].classList.add("active"); } @@ -37,11 +37,11 @@ async function initSelection(idPrefix, fetchCandidates, fmtCandidate, onSelectio const item = document.createElement("li"); item.candidate = candidate; item.innerHTML = fmtCandidate(candidate); - item.style.display = 'none'; + item.style.display = "none"; - item.addEventListener('click', function() { + item.addEventListener("click", function () { sel.value = ""; - sel.dispatchEvent(new Event('keyup')); + sel.dispatchEvent(new Event("keyup")); onSelection(candidate); }); @@ -49,9 +49,8 @@ async function initSelection(idPrefix, fetchCandidates, fmtCandidate, onSelectio items.push(item); } - sel.addEventListener('keyup', function(e) { - if ((["ArrowDown", "ArrowUp", "Enter"]).includes(e.key)) - return; + sel.addEventListener("keyup", function (e) { + if (["ArrowDown", "ArrowUp", "Enter"].includes(e.key)) return; const filter = sel.value.toLowerCase(); visibleItems = []; @@ -63,10 +62,10 @@ async function initSelection(idPrefix, fetchCandidates, fmtCandidate, onSelectio visibleItems.push(item); // Highlight matched text - const regex = new RegExp(`(${filter})`, 'gi'); + const regex = new RegExp(`(${filter})`, "gi"); item.innerHTML = item.textContent.replace( regex, - "$1" + "$1", ); } else { item.style.display = "none"; @@ -82,26 +81,23 @@ async function initSelection(idPrefix, fetchCandidates, fmtCandidate, onSelectio noResults.style.display = visibleItems.length || filter === "" ? "none" : "block"; }); - clearBtn.addEventListener('click', function() { + clearBtn.addEventListener("click", function () { sel.value = ""; - sel.dispatchEvent(new Event('keyup')); // reset list + sel.dispatchEvent(new Event("keyup")); // reset list sel.focus(); }); - sel.addEventListener('keydown', function(e) { + sel.addEventListener("keydown", function (e) { if (e.key === "ArrowDown" || e.key === "ArrowUp") { - if(e.key === "ArrowDown") - currentFocus = (currentFocus + 1) % visibleItems.length; - else - currentFocus = (currentFocus - 1 + visibleItems.length) % visibleItems.length; + if (e.key === "ArrowDown") currentFocus = (currentFocus + 1) % visibleItems.length; + else currentFocus = (currentFocus - 1 + visibleItems.length) % visibleItems.length; setActive(); e.preventDefault(); } else if (e.key === "Enter") { if (currentFocus > -1 && visibleItems[currentFocus]) { - const visibleItem = visibleItems[currentFocus]; sel.value = ""; - sel.dispatchEvent(new Event('keyup')); + sel.dispatchEvent(new Event("keyup")); onSelection(visibleItem.candidate); } e.preventDefault(); diff --git a/src/student-mock.ts b/src/student-mock.ts index 93b45b0..bf817d2 100644 --- a/src/student-mock.ts +++ b/src/student-mock.ts @@ -3,20 +3,19 @@ import { Student } from "./student-common.ts"; import { fetchStudentsMock as fetchStudents, fetchGraduationMock } from "./mock.ts"; declare module "./student-common.ts" { - interface Student { - getGraduation(): Promise; - getIconUrl(): Promise; - } + interface Student { + getGraduation(): Promise; + getIconUrl(): Promise; + } } Student.prototype.getGraduation = function () { - return fetchGraduationMock(this); + return fetchGraduationMock(this); }; Student.prototype.getIconUrl = async function () { - return ""; + return ""; }; - async function fetchStudent(_idFilter?: number, _nameFilter?: string, _groupFilter?: string) { const students = await fetchStudents(); return students[0]; diff --git a/src/student-prod.ts b/src/student-prod.ts index 24ac869..67379d9 100644 --- a/src/student-prod.ts +++ b/src/student-prod.ts @@ -1,20 +1,20 @@ import type { Graduation } from "./graduation-common.ts"; import { Student } from "./student-common.ts"; -import { getUserIconUrl, getCourseParticipantsUrl } from "./utils-prod.js" +import { getUserIconUrl, getCourseParticipantsUrl } from "./utils-prod.js"; import { fetchGraduation } from "./graduation-prod.ts"; declare module "./student-common.ts" { - interface Student { - getGraduation(): Promise; - getIconUrl(): Promise; - } + interface Student { + getGraduation(): Promise; + getIconUrl(): Promise; + } } Student.prototype.getGraduation = function () { - return fetchGraduation(this); + return fetchGraduation(this); }; Student.prototype.getIconUrl = function () { - return getUserIconUrl(this.id); + return getUserIconUrl(this.id); }; // Cache the fetched students. @@ -26,9 +26,8 @@ async function _fetchStudents() { const doc = new DOMParser().parseFromString(await res.text(), "text/html"); const table = doc.querySelector("tbody")!; const fetchedStudents: Array = []; - table.querySelectorAll("tr").forEach(row => { - if (row.classList.contains("emptyrow")) - return; + table.querySelectorAll("tr").forEach((row) => { + if (row.classList.contains("emptyrow")) return; const roleCell = row.querySelector(".c4")!; // TODO(muhq): Is this locale dependent? @@ -39,10 +38,8 @@ async function _fetchStudents() { const nameCell = row.querySelector(".c1")!; let name; const c = nameCell.firstChild!.firstChild! as HTMLElement; - if (c.tagName == "SPAN") - name = c.title; - else - name = nameCell.innerText; + if (c.tagName == "SPAN") name = c.title; + else name = nameCell.innerText; const profileUrl = nameCell.querySelector("a.aabtn")!.href; const match = idRegex.exec(profileUrl); @@ -76,10 +73,12 @@ async function fetchStudents(idFilter?: number, nameFilter?: string, groupFilter } } - return students.filter((s) => - (typeof idFilter === "undefined" || s.id === idFilter) && - (typeof nameFilter === "undefined" || s.name.includes(nameFilter)) && - (typeof groupFilter === "undefined" || s.group.includes(groupFilter))); + return students.filter( + (s) => + (typeof idFilter === "undefined" || s.id === idFilter) && + (typeof nameFilter === "undefined" || s.name.includes(nameFilter)) && + (typeof groupFilter === "undefined" || s.group.includes(groupFilter)), + ); } async function fetchStudent(idFilter: number, nameFilter: string, groupFilter: string) { diff --git a/src/utils-common.ts b/src/utils-common.ts index f3ad944..8053043 100644 --- a/src/utils-common.ts +++ b/src/utils-common.ts @@ -1,8 +1,18 @@ "use strict"; -export const DATE_FMT = new Intl.DateTimeFormat("de-DE", { month: "numeric", day: "numeric", year: "numeric"}); +export const DATE_FMT = new Intl.DateTimeFormat("de-DE", { + month: "numeric", + day: "numeric", + year: "numeric", +}); -export const DATETIME_FMT = new Intl.DateTimeFormat("de-DE", { month: "numeric", day: "numeric", year: "numeric", hour: "numeric", minute: "numeric" }); +export const DATETIME_FMT = new Intl.DateTimeFormat("de-DE", { + month: "numeric", + day: "numeric", + year: "numeric", + hour: "numeric", + minute: "numeric", +}); export function dateStringNow() { return DATE_FMT.format(new Date()); @@ -14,8 +24,8 @@ export function datetimeStringNow() { // TODO(muhq): Cache the retrieved URL export async function getUserIconUrl(userId: number): Promise { - const userRes = await fetch(`https://lernplattform.bycs.de/user/profile.php?id=${userId}`) - const userDoc = new DOMParser().parseFromString(await userRes.text(), 'text/html') + const userRes = await fetch(`https://lernplattform.bycs.de/user/profile.php?id=${userId}`); + const userDoc = new DOMParser().parseFromString(await userRes.text(), "text/html"); const userpicture = userDoc.querySelector(".userpicture"); if (userpicture === null) { return ""; diff --git a/src/utils-mock.js b/src/utils-mock.js index ab87ddc..9694500 100644 --- a/src/utils-mock.js +++ b/src/utils-mock.js @@ -4,11 +4,11 @@ export { DATETIME_FMT, dateStringNow, datetimeStringNow, - getUserIconUrl + getUserIconUrl, } from "./utils-common.ts"; export function isTeacher() { - return !(new URLSearchParams(document.location.search)).has("student"); + return !new URLSearchParams(document.location.search).has("student"); } export function getFirstAndLastname() { @@ -16,10 +16,8 @@ export function getFirstAndLastname() { let lastname = ""; const params = new URLSearchParams(document.location.search); - if (params.has("firstname")) - firstname = params.get("firstname"); - if (params.has("lastname")) - lastname = params.get("lastname"); + if (params.has("firstname")) firstname = params.get("firstname"); + if (params.has("lastname")) lastname = params.get("lastname"); return [firstname, lastname]; } @@ -28,10 +26,8 @@ export function getName() { let name = ""; const params = new URLSearchParams(document.location.search); - if (params.has("firstname")) - name = params.get("firstname"); - if (params.has("lastname")) - name += params.get("lastname"); + if (params.has("firstname")) name = params.get("firstname"); + if (params.has("lastname")) name += params.get("lastname"); return name; } @@ -39,7 +35,7 @@ export function getName() { export function getUserId() { const name = getName(); - return fetchStudentsMock.filter((s) => s.name === name )[0].id; + return fetchStudentsMock.filter((s) => s.name === name)[0].id; } export function getCourseId() { @@ -50,5 +46,3 @@ export function getCourseParticipantsUrl() { console.error("Try to get mocked participations URL"); return ""; } - - diff --git a/src/utils-prod.js b/src/utils-prod.js index f7c89e4..94d724a 100644 --- a/src/utils-prod.js +++ b/src/utils-prod.js @@ -3,12 +3,14 @@ export { DATETIME_FMT, dateStringNow, datetimeStringNow, - getUserIconUrl + getUserIconUrl, } from "./utils-common.ts"; export function isTeacher() { - return Boolean(document.querySelector('.editmode-switch-form')) - || document.body.classList.contains('editing'); + return ( + Boolean(document.querySelector(".editmode-switch-form")) || + document.body.classList.contains("editing") + ); } export function getFirstAndLastname() { @@ -24,7 +26,8 @@ export function getFirstAndLastname() { } export function getName() { - return document.querySelector("bycs-topbar").shadowRoot.querySelector("div.user-name").textContent; + return document.querySelector("bycs-topbar").shadowRoot.querySelector("div.user-name") + .textContent; } export function getUserId() { @@ -40,4 +43,3 @@ export function getCourseId() { export function getCourseParticipantsUrl() { return `https://lernplattform.bycs.de/user/index.php?id=${getCourseId()}&perpage=5000`; } - -- cgit v1.2.3