diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a73d37..c7fb632 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,42 @@ Vor `npm version` wandert der Abschnitt „Unveröffentlicht" unter eine neue ## [Unveröffentlicht] +## [1.1.0] – 2026-10-05 + +Module lassen sich abschalten. + +### Hinzugefügt + +- **Verwaltung → Module.** Merkkarten, Praxisaufgaben, Checklisten, + Berichtsheft, Lernzielkontrollen und Feedbackgespräch lassen sich für die + ganze Lern-Bar ab- und wieder einschalten, sofort und ohne Neustart. Zu jedem + Modul steht dort, was es tut, was sich beim Abschalten ändert und wer es + zuletzt umgeschaltet hat. Wochenplan, Handouts, Glossar, Auswertung und + Verwaltung bleiben immer an +- Ein abgeschaltetes Modul ist **überall weg**: Navigation, Wochenplan und + Wochenfortschritt (eine Woche erreicht ohne das Modul trotzdem 100 %), „Was + auf dich wartet", „Mein Stand", Ergebnisverlauf, Rahmenplanabdeckung, + Vorschläge fürs Berichtsheft, Merkkarten im Handout, Kurzbefehle im + App-Symbol +- Ein abgeschaltetes Modul ist **gesperrt, nicht nur ausgeblendet**: Seiten, + PDF-Ausgaben, Anhänge und alle 37 Serveraktionen der Module prüfen den + Schalter. Die Lernstand-Schnittstelle antwortet mit 410, und Geräte verwerfen + daraufhin offline gesammelte Bewertungen +- **Abschalten löscht nichts.** Nach dem Einschalten ist alles unverändert da +- Die Verwaltung hat zwei Bereiche: Konten und Module +- Migration `0010_module` – eine bestehende Datenbank hat danach alle Module an + und verhält sich wie vorher +- 12 Tests für die Modulregeln, Abschnitt A8 im Abnahmelauf (abschalten, + Sperre für beide Rollen prüfen, einschalten, Daten noch da) +- Anleitung Kapitel 9 „Module ein- und ausschalten" mit Bildschirmfoto, + README-Abschnitt, Entscheidung E43 + +### Geändert + +- Das App-Manifest wird bei jedem Abruf erzeugt statt einmal beim Bau, damit + die Kurzbefehle zum Modulstand passen +- In der Anleitung haben sich die Kapitel ab 9 um eins verschoben + ## [1.0.5] – 2026-10-05 Das zweite Vierteljahr beginnt, mit Blick auf Teil 1 der Abschlussprüfung. diff --git a/ENTSCHEIDUNGEN.md b/ENTSCHEIDUNGEN.md index eb9fbd3..073c41d 100644 --- a/ENTSCHEIDUNGEN.md +++ b/ENTSCHEIDUNGEN.md @@ -493,3 +493,41 @@ oder eine erfolgreiche Anmeldung setzt den Zähler zurück. - **Gezählt wird vor der Prüfung.** Jeder Versuch gilt sofort als Fehlversuch und wird bei Erfolg zurückgenommen. Zwischen Sperrprüfung und Zählen liegt so kein `await`; sonst kämen gleichzeitige Anfragen alle an der Sperre vorbei. + +## E43 · Module schaltbar für die ganze Lern-Bar, gesperrt an drei Stellen, nie gelöscht + +Merkkarten, Praxisaufgaben, Checklisten, Berichtsheft, Lernzielkontrollen und +Feedbackgespräch lassen sich unter **Verwaltung → Module** abschalten. Wochenplan, +Handouts, Glossar, Auswertung und Verwaltung bleiben immer an – an ihnen hängt +alles andere, und die Auswertung passt sich ohnehin an. + +- **Für die ganze Lern-Bar, nicht je Azubi.** Ein Betrieb startet mit einer + Fachrichtung und entscheidet einmal, womit er arbeitet. Schalter je Azubi + hätten jede Ausbilderansicht je Person unterschiedlich gemacht. Ließe sich + später ergänzen, ohne das Bestehende umzubauen: Der Stand ist schon heute ein + Objekt, das an einer Stelle entsteht (`repos/module`). +- **In der Datenbank, nicht in einer Konfigurationsdatei.** Ein Ausbilder soll + ohne Zugang zum Server umschalten können, und die Änderung soll sofort + wirken, ohne Neustart. Gespeichert wird nur, was je umgeschaltet wurde; fehlt + die Zeile, ist das Modul an. Eine bestehende Datenbank verhält sich nach der + Migration also genau wie vorher. +- **Gesperrt an drei Stellen, nicht im Layout.** Seiten rufen `erfordereModul` + auf (Antwort „nicht gefunden", wie bei fehlender Berechtigung, E21), Routen + für PDF, Anhänge und Lernstand fragen `modulAn`, Serveraktionen rufen + `pruefeModul`. Ein Layout je Modul wäre kürzer gewesen, greift aber nicht + zuverlässig: Next.js rendert ein Layout beim Wechsel zwischen den Seiten + darunter nicht neu. +- **Abschalten löscht nichts.** Beim Berichtsheft ist das zwingend – es ist ein + Nachweis. Für alle anderen Module gilt dasselbe, damit niemand beim + Ausprobieren Daten verliert. +- **Abgeschaltet heißt: trägt nirgends bei.** Kein Eintrag im Wochenplan, kein + Anteil am Wochenfortschritt, kein Nachweis in der Rahmenplanabdeckung, kein + Vorschlag fürs Berichtsheft, kein Kurzbefehl im App-Symbol. Sonst stünden + Inhalte für immer als offen da, die niemand mehr bearbeiten kann. +- **Offline gesammelte Bewertungen werden verworfen**, wenn die Merkkarten aus + sind. Die Lernstand-Schnittstelle antwortet mit 410 statt 404, und das Gerät + leert daraufhin seine Warteschlange, statt sie bei jeder Verbindung erneut zu + schicken. +- **Die Prüfung der Anmeldung kommt zuerst**, die des Moduls danach. Sonst sähe + ein nicht angemeldeter Besucher an „nicht gefunden" statt der Anmeldeseite, + welche Module abgeschaltet sind. diff --git a/README.md b/README.md index 6124cdc..cc9759f 100644 --- a/README.md +++ b/README.md @@ -144,6 +144,21 @@ npm run inhalte:pruefen --- +## Module ein- und ausschalten + +Unter **Verwaltung → Module** lassen sich Merkkarten, Praxisaufgaben, +Checklisten, Berichtsheft, Lernzielkontrollen und Feedbackgespräch abschalten – +für die ganze Lern-Bar, sofort und ohne Neustart. Wochenplan, Handouts, Glossar, +Auswertung und Verwaltung bleiben immer an. + +Ein abgeschaltetes Modul verschwindet aus Navigation, Wochenplan, Fortschritt, +Auswertung und Rahmenplanabdeckung, und seine Seiten, PDFs und Serveraktionen +sind gesperrt. **Gelöscht wird nichts:** Nach dem Einschalten ist alles wieder +da. Einzelheiten in der [Anleitung](docs/ANLEITUNG.md#9-module-ein--und-ausschalten), +die Begründung in [E43](ENTSCHEIDUNGEN.md). + +--- + ## Datensicherung Gesichert werden **Datenbank und Anhänge**. Die Inhalte stecken im Repository @@ -244,7 +259,7 @@ Protokollzeilen. ```bash npm run typecheck # TypeScript npm run lint # ESLint -npm run test # Vitest – Logik, die wehtut (315 Tests) +npm run test # Vitest – Logik, die wehtut (341 Tests) npm run abnahme # der Abnahmelauf, siehe unten npm run abnahme:container # derselbe Weg gegen das Docker-Abbild ``` @@ -263,7 +278,10 @@ Datenbank** und spielt den ganzen Weg durch: 4. Der Azubi liest ein Handout, lernt eine Karte, meldet eine Aufgabe zur Abnahme 5. Der Ausbilder nimmt sie ab; sie schlägt in der Rahmenplanabdeckung durch 6. Das Wochenblatt wird angelegt und als PDF ausgegeben -7. **Gesichert, absichtlich beschädigt, zurückgespielt.** Eine Sicherung, die +7. Berichtsheft und Merkkarten werden über die Verwaltung abgeschaltet: Seite + und PDF sind für beide Rollen gesperrt, nach dem Einschalten ist das + Wochenblatt unverändert da +8. **Gesichert, absichtlich beschädigt, zurückgespielt.** Eine Sicherung, die nie zurückgespielt wurde, ist keine Sicherung Das Protokoll landet in [`docs/ABNAHME.md`](docs/ABNAHME.md). diff --git a/ROADMAP.md b/ROADMAP.md index 3ea624a..118a3ef 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -117,6 +117,17 @@ Legende: `[ ]` offen · `[~]` in Arbeit · `[x]` fertig - [x] Abnahmekriterien einzeln durchgespielt und protokolliert (`docs/ABNAHME.md`) +## 1.1 – Module + +- [x] **Module abschaltbar** unter Verwaltung → Module + - [x] Merkkarten, Praxisaufgaben, Checklisten, Berichtsheft, + Lernzielkontrollen, Feedbackgespräch; das Gerüst bleibt immer an + - [x] Gesperrt in Seiten, Routen und Serveraktionen, nicht nur ausgeblendet + - [x] Wochenplan, Fortschritt, Auswertung, Rahmenplanabdeckung, Vorschläge + und App-Kurzbefehle richten sich nach dem Stand + - [x] Abschalten löscht nichts + - [x] Im Abnahmelauf geprüft (A8) + --- ## Danach – bewusst zurückgestellt diff --git a/docs/ABNAHME.md b/docs/ABNAHME.md index 1d3f618..e51da21 100644 --- a/docs/ABNAHME.md +++ b/docs/ABNAHME.md @@ -1,6 +1,6 @@ # Abnahmeprotokoll -Erzeugt am 2026-10-04 16:24 Uhr +Erzeugt am 2026-10-05 14:48 Uhr Erzeugt von `scripts/pruefungen/abnahme.mjs` gegen eine **frische, leere Datenbank**. @@ -54,15 +54,25 @@ Erzeugt von `scripts/pruefungen/abnahme.mjs` gegen eine **frische, leere Datenba - ✓ Der Azubi legt das Wochenblatt der laufenden Woche an - ✓ Ein Wochenblatt lässt sich öffnen -- ✓ Das Wochenblatt kommt als PDF heraus — HTTP 200, 2649 Bytes +- ✓ Das Wochenblatt kommt als PDF heraus — HTTP 200, 2646 Bytes -## A8 · Sicherung zurückspielen +## A8 · Module abschalten -- ✓ Die Sicherung läuft durch — lernbar-20261004-182433.tar.gz +- ✓ Der Ausbilder schaltet das Berichtsheft ab +- ✓ Das Berichtsheft verschwindet aus der Navigation +- ✓ Die Seite ist für beide Rollen gesperrt, nicht nur ausgeblendet — Azubi HTTP 404, Ausbilder HTTP 404 +- ✓ Auch das PDF ist gesperrt — HTTP 404 +- ✓ Ohne Merkkarten zeigt das Handout keine Karten +- ✓ Ein Gerät mit gesammelten Bewertungen erfährt, dass es sie verwerfen soll — HTTP 410 +- ✓ Nach dem Einschalten ist das Wochenblatt unverändert wieder da — HTTP 200 + +## A9 · Sicherung zurückspielen + +- ✓ Die Sicherung läuft durch — lernbar-20261005-164818.tar.gz - ✓ Zum Beweis wird der Datenbestand beschädigt — 2 → 1 Konten - ✓ Die Rückspielung läuft durch — ohne Fehler - ✓ Der gelöschte Azubi ist wieder da — Tim Vogt - ✓ Auch der Lernverlauf kam mit zurück — 1 Einträge -- ✓ Der überschriebene Stand wurde zur Seite gelegt, nicht gelöscht — verdraengt-20261004-182436 +- ✓ Der überschriebene Stand wurde zur Seite gelegt, nicht gelöscht — verdraengt-20261005-164821 -**36 von 36 Prüfungen erfüllt.** +**43 von 43 Prüfungen erfüllt.** diff --git a/docs/ANLEITUNG.md b/docs/ANLEITUNG.md index b890082..9d3e00b 100644 --- a/docs/ANLEITUNG.md +++ b/docs/ANLEITUNG.md @@ -22,24 +22,25 @@ gemalt, sondern gemessen. 6. [Eine Lernzielkontrolle korrigieren](#6-eine-lernzielkontrolle-korrigieren) 7. [Die Rahmenplanabdeckung lesen](#7-die-rahmenplanabdeckung-lesen) 8. [Ein Feedbackgespräch führen](#8-ein-feedbackgespräch-führen) +9. [Module ein- und ausschalten](#9-module-ein--und-ausschalten) **Für den Azubi** -9. [Die Woche](#9-die-woche) -10. [Handouts lesen und suchen](#10-handouts-lesen-und-suchen) -11. [Merkkarten lernen](#11-merkkarten-lernen) -12. [Eine Praxisaufgabe abgeben](#12-eine-praxisaufgabe-abgeben) -13. [Eine Checkliste abarbeiten](#13-eine-checkliste-abarbeiten) -14. [Das Berichtsheft führen](#14-das-berichtsheft-führen) -15. [Eine Lernzielkontrolle schreiben](#15-eine-lernzielkontrolle-schreiben) +10. [Die Woche](#10-die-woche) +11. [Handouts lesen und suchen](#11-handouts-lesen-und-suchen) +12. [Merkkarten lernen](#12-merkkarten-lernen) +13. [Eine Praxisaufgabe abgeben](#13-eine-praxisaufgabe-abgeben) +14. [Eine Checkliste abarbeiten](#14-eine-checkliste-abarbeiten) +15. [Das Berichtsheft führen](#15-das-berichtsheft-führen) +16. [Eine Lernzielkontrolle schreiben](#16-eine-lernzielkontrolle-schreiben) **Überall** -16. [Auf dem Handy](#16-auf-dem-handy) -17. [Ohne Netz](#17-ohne-netz) -18. [Hell und dunkel](#18-hell-und-dunkel) -19. [Drucken](#19-drucken) -20. [Wenn etwas nicht geht](#20-wenn-etwas-nicht-geht) +17. [Auf dem Handy](#17-auf-dem-handy) +18. [Ohne Netz](#18-ohne-netz) +19. [Hell und dunkel](#19-hell-und-dunkel) +20. [Drucken](#20-drucken) +21. [Wenn etwas nicht geht](#21-wenn-etwas-nicht-geht) --- @@ -218,11 +219,49 @@ Unterschriftenfeldern. Abweichungen sind auch dort markiert. > anpassen. Ein bereits geführtes Gespräch behält seine Fassung, auch wenn du > die Vorlage später änderst. +### 9. Module ein- und ausschalten + +**Verwaltung → Module** + +![Verwaltung, Bereich Module, das Berichtsheft ist abgeschaltet](bilder/25-module.png) + +Nicht jeder Betrieb braucht alles. Führt ihr das Berichtsheft zum Beispiel im +Portal der Kammer, schaltest du es hier ab – für die ganze Lern-Bar, für alle +Azubis und Ausbilder zugleich. + +| Modul | Abschaltbar | +|---|---| +| Merkkarten, Praxisaufgaben, Checklisten, Berichtsheft, Lernzielkontrollen, Feedbackgespräch | ja | +| Wochenplan, Handouts, Glossar, Auswertung, Verwaltung | nein – das Gerüst | + +Was beim Abschalten passiert: + +- **Das Modul verschwindet** aus der Navigation, aus dem Wochenplan, aus „Was + auf dich wartet" und aus der Auswertung. Zu jedem Modul steht auf der Seite, + was sich genau ändert. +- **Seiten und PDFs sind gesperrt**, nicht nur ausgeblendet. Wer sich die + Adresse gemerkt hat, bekommt „Diese Seite gibt es nicht". +- **Der Wochenfortschritt** zählt das Modul nicht mehr mit. Eine Woche ohne + Merkkarten erreicht also trotzdem 100 %. +- **Die Rahmenplanabdeckung** zählt abgeschaltete Aufgaben und Checklisten + nicht mehr. Bleiben nur Handouts, gilt eine Position mit zwei gelesenen + Handouts als vermittelt. +- **Nichts wird gelöscht.** Was im Modul schon geschrieben wurde – Berichtshefte, + Bewertungen, Abnahmen –, bleibt gespeichert und ist nach dem Einschalten + unverändert wieder da. + +Unter jedem Modul steht, wer es wann zuletzt umgeschaltet hat. + +> **Berichtsheft abschalten heißt nicht, kein Berichtsheft zu führen.** Der +> Ausbildungsnachweis ist Pflicht und Voraussetzung für die Zulassung zur +> Abschlussprüfung. Er wird dann eben woanders geführt. In den Wochenplänen +> steht freitags weiterhin „Berichtsheft schreiben" – das gilt auch dann. + --- ## Für den Azubi -### 9. Die Woche +### 10. Die Woche ![Woche des Azubis](bilder/10-azubi-woche.png) @@ -232,7 +271,7 @@ Frage lautet „Was mache ich jetzt?", nicht „Wie ist meine Gesamtlage?". --- -### 10. Handouts lesen und suchen +### 11. Handouts lesen und suchen ![Handouts](bilder/11-handouts-liste.png) @@ -254,7 +293,7 @@ mit Querverweisen. --- -### 11. Merkkarten lernen +### 12. Merkkarten lernen ![Merkkarten](bilder/14-merkkarten.png) @@ -273,7 +312,7 @@ nachzuholen. --- -### 12. Eine Praxisaufgabe abgeben +### 13. Eine Praxisaufgabe abgeben ![Aufgaben](bilder/16-aufgaben-liste.png) @@ -287,7 +326,7 @@ Dann gibst du ab. Der Ausbilder nimmt ab oder gibt zurück, mit Bemerkung. --- -### 13. Eine Checkliste abarbeiten +### 14. Eine Checkliste abarbeiten ![Checklisten](bilder/18-checklisten.png) @@ -304,7 +343,7 @@ begonnen hast. Am Ende gibt es ein PDF – ein Beispiel liegt unter --- -### 14. Das Berichtsheft führen +### 15. Das Berichtsheft führen ![Berichtsheft](bilder/21-berichtsheft.png) @@ -323,7 +362,7 @@ Nach dem Abzeichnen ist das Blatt unveränderlich. --- -### 15. Eine Lernzielkontrolle schreiben +### 16. Eine Lernzielkontrolle schreiben Der Ausbilder gibt die Kontrolle frei, du siehst sie unter *Kontrollen*. Du schreibst deine Antworten und sendest ab. @@ -336,7 +375,7 @@ Kontrolle, deren Lösung vorher abrufbar wäre, misst nichts. ## Überall -### 16. Auf dem Handy +### 17. Auf dem Handy Die Anwendung ist für das Handy gebaut, nicht dafür angepasst. Der Azubi hat es in der Tasche, nicht den Laptop. @@ -355,7 +394,7 @@ Danach startet sie ohne Adresszeile und mit eigenem Symbol. --- -### 17. Ohne Netz +### 18. Ohne Netz Im Serverraum, im Keller, im Zug gibt es kein Netz. Deshalb: @@ -376,7 +415,7 @@ weggeräumt. --- -### 18. Hell und dunkel +### 19. Hell und dunkel ![Dunkle Fassung](bilder/20-dunkel.png) @@ -386,7 +425,7 @@ hast – sonst käme schwarzes Papier aus dem Drucker. --- -### 19. Drucken +### 20. Drucken Für die Dokumente, die eine Unterschrift tragen, gibt es **PDFs**: Wochenblatt, Checklisten-Durchlauf, Feedbackgespräch. @@ -397,11 +436,12 @@ mitten durchgeschnitten, aufklappbare Abschnitte drucken aufgeklappt. --- -### 20. Wenn etwas nicht geht +### 21. Wenn etwas nicht geht | Beobachtung | Woran es liegt | |---|---| | „Zu viele Fehlversuche" bei der Anmeldung | Nach fünf falschen Passwörtern wird die Adresse für eine Minute gesperrt, bei weiteren Fehlversuchen länger, höchstens 15 Minuten. Abwarten – oder Passwort vom Ausbilder neu setzen lassen. Hat sich das einzige Ausbilderkonto ausgesperrt: `docker compose restart lernbar` setzt die Sperre zurück. | +| Ein Bereich fehlt in der Navigation, oder seine Seite meldet „Diese Seite gibt es nicht" | Das Modul ist abgeschaltet. Ein Ausbilder schaltet es unter **Verwaltung → Module** wieder ein; die Daten sind noch da. | | „Diese Seite gibt es nicht" bei fremden Daten | Kein Fehler, sondern die Rechteprüfung. Ob es zu einer Kennung überhaupt Daten gibt, geht Unbefugte nichts an – deshalb 404 und nicht „kein Zugriff". | | Die Anwendung startet nicht, nennt aber Datei und Zeile | Ein Inhaltsfehler unter `content/`. Die Meldung sagt genau, wo. `npm run inhalte:pruefen` prüft ohne Start. | | Ein Anhang lässt sich nicht hochladen | Über 25 MB. Bei einem Reverse Proxy zusätzlich `client_max_body_size 30m` setzen (siehe README). | diff --git a/docs/bilder/25-module.png b/docs/bilder/25-module.png new file mode 100644 index 0000000..2970bb4 Binary files /dev/null and b/docs/bilder/25-module.png differ diff --git a/scripts/pruefungen/abnahme.mjs b/scripts/pruefungen/abnahme.mjs index 837dcd7..d6bdef4 100644 --- a/scripts/pruefungen/abnahme.mjs +++ b/scripts/pruefungen/abnahme.mjs @@ -404,6 +404,7 @@ try { ); const blatt = await z.$('.blattzeile-link'); + let blattAdresse = null; if (blatt) { await blatt.click(); // Auf die Adresse warten, nicht auf eine Überschrift: Die steht auch auf @@ -411,6 +412,7 @@ try { // die Anfrage landet auf der Sammelroute statt auf dem einzelnen Blatt. await z.waitForURL(/\/berichtsheft\/[0-9a-f-]{36}$/, { timeout: 30000 }); pruefe(true, 'Ein Wochenblatt lässt sich öffnen'); + blattAdresse = z.url(); const pdf = await azubi.request.get(`${z.url()}/pdf`); const puffer = await pdf.body(); @@ -425,9 +427,59 @@ try { pruefe(false, 'Ein Wochenblatt lässt sich öffnen', 'keine Blattzeile gefunden'); } - // --- A8 Sicherung und Rückspielung --------------------------------------- + // --- A8 Module abschalten ------------------------------------------------- - abschnitt('A8 · Sicherung zurückspielen'); + abschnitt('A8 · Module abschalten'); + + // Über die Oberfläche, wie im Betrieb: Verwaltung → Module. + const umschalten = async (modul) => { + await a.goto(`${BASIS}/verwaltung/module`); + await a.click(`form:has(input[name="modul"][value="${modul}"]) button[type=submit]`); + await a.waitForLoadState('networkidle'); + }; + const zustandIn = async (modul) => { + await a.goto(`${BASIS}/verwaltung/module`); + // Die Statusmarke steht direkt neben der Überschrift des Moduls. + return (await a.locator(`#modul-${modul} + .marke-status`).innerText()).trim(); + }; + + await umschalten('berichtsheft'); + await umschalten('karten'); + pruefe((await zustandIn('berichtsheft')).includes('aus'), 'Der Ausbilder schaltet das Berichtsheft ab'); + + await z.goto(`${BASIS}/`); + pruefe((await z.locator('nav a[href="/berichtsheft"]').count()) === 0, 'Das Berichtsheft verschwindet aus der Navigation'); + + const seiteAus = await azubi.request.get(`${BASIS}/berichtsheft`); + const ausbilderSeiteAus = await ausbilder.request.get(`${BASIS}/berichtsheft`); + pruefe( + seiteAus.status() === 404 && ausbilderSeiteAus.status() === 404, + 'Die Seite ist für beide Rollen gesperrt, nicht nur ausgeblendet', + `Azubi HTTP ${seiteAus.status()}, Ausbilder HTTP ${ausbilderSeiteAus.status()}`, + ); + if (blattAdresse) { + const pdfAus = await azubi.request.get(`${blattAdresse}/pdf`); + pruefe(pdfAus.status() === 404, 'Auch das PDF ist gesperrt', `HTTP ${pdfAus.status()}`); + } + + await z.goto(`${BASIS}/handouts/N3`); + pruefe( + (await z.locator('text=Merkkarten zu diesem Handout').count()) === 0, + 'Ohne Merkkarten zeigt das Handout keine Karten', + ); + const lernstandAus = await azubi.request.post(`${BASIS}/api/lernstand`, { data: { eintraege: [] } }); + pruefe(lernstandAus.status() === 410, 'Ein Gerät mit gesammelten Bewertungen erfährt, dass es sie verwerfen soll', `HTTP ${lernstandAus.status()}`); + + await umschalten('berichtsheft'); + await umschalten('karten'); + if (blattAdresse) { + const wieder = await azubi.request.get(blattAdresse); + pruefe(wieder.status() === 200, 'Nach dem Einschalten ist das Wochenblatt unverändert wieder da', `HTTP ${wieder.status()}`); + } + + // --- A9 Sicherung und Rückspielung --------------------------------------- + + abschnitt('A9 · Sicherung zurückspielen'); // Pfade für bash mit Schrägstrichen: Ein Backslash ist dort ein Fluchtzeichen. const alsPosix = (pfad) => pfad.split(path.sep).join('/'); diff --git a/scripts/screenshots.ts b/scripts/screenshots.ts index 832ddec..26eef17 100644 --- a/scripts/screenshots.ts +++ b/scripts/screenshots.ts @@ -74,6 +74,18 @@ async function main() { await seite.waitForSelector('#neu-name'); await bild(seite, '03-verwaltung'); + // Module: für das Bild ein Modul abschalten, danach den alten Stand herstellen. + const umschalten = async (modul: string) => { + await seite.goto(`${BASIS}/verwaltung/module`); + await seite.click(`form:has(input[name="modul"][value="${modul}"]) button[type=submit]`); + await seite.waitForLoadState('networkidle'); + }; + await umschalten('berichtsheft'); + await seite.goto(`${BASIS}/verwaltung/module`); + await seite.waitForSelector('#modul-karten'); + await bild(seite, '25-module'); + await umschalten('berichtsheft'); + await seite.goto(`${BASIS}/wochenplan`); await seite.waitForSelector('h1'); await bild(seite, '04-wochenplan'); diff --git a/src/app/(angemeldet)/WochenAnsicht.tsx b/src/app/(angemeldet)/WochenAnsicht.tsx index fe38917..c5f3f4e 100644 --- a/src/app/(angemeldet)/WochenAnsicht.tsx +++ b/src/app/(angemeldet)/WochenAnsicht.tsx @@ -155,58 +155,64 @@ export function WochenAnsicht({ )} -
-

- Praxisaufgaben -

- {sicht.aufgaben.length === 0 ? ( -

Keine.

- ) : ( - - )} -
+ {sicht.module.aufgaben ? ( +
+

+ Praxisaufgaben +

+ {sicht.aufgaben.length === 0 ? ( +

Keine.

+ ) : ( + + )} +
+ ) : null} -
-

- Checklisten -

- {sicht.checklisten.length === 0 ? ( -

Keine.

- ) : ( - - )} -
+ {sicht.module.checklisten ? ( +
+

+ Checklisten +

+ {sicht.checklisten.length === 0 ? ( +

Keine.

+ ) : ( + + )} +
+ ) : null} -
-

- Lernzielkontrolle -

- {sicht.kontrolle ? ( -

- {sicht.kontrolle.titel} -
- - {sicht.kontrolle.fragen.length} Fragen ·{' '} - {sicht.kontrolle.fragen.reduce((summe, f) => summe + f.punkte, 0)} Punkte - {sicht.kontrolle.dauer_minuten ? ` · ${sicht.kontrolle.dauer_minuten} Minuten` : ''} - -

- ) : ( -

Diese Woche keine.

- )} -
+ {sicht.module.kontrollen ? ( +
+

+ Lernzielkontrolle +

+ {sicht.kontrolle ? ( +

+ {sicht.kontrolle.titel} +
+ + {sicht.kontrolle.fragen.length} Fragen ·{' '} + {sicht.kontrolle.fragen.reduce((summe, f) => summe + f.punkte, 0)} Punkte + {sicht.kontrolle.dauer_minuten ? ` · ${sicht.kontrolle.dauer_minuten} Minuten` : ''} + +

+ ) : ( +

Diese Woche keine.

+ )} +
+ ) : null}