Kurs-Übersicht: fehlende Hausaufgaben; Erinnerungen als eigene Aufgabenart; Kalender-/Sitzplan-Bugfixes

Kurs-Übersicht: neue Karte "Fehlende Hausaufgaben" listet Schüler mit nicht
gemachter Hausaufgabe aus der letzten Mitarbeitssitzung.

Aufgabenverwaltung: WorkTask.Kind unterscheidet jetzt Arbeitsaufträge von
reinen Erinnerungen ohne Zeitbezug (z.B. "morgen Ansage an die Klasse
machen") - eigener Button "🔔 Erinnerung", eigenes Icon in Liste/Dashboard,
läuft nicht in die Zeitauswertung ein.

Drei Bugfixes aus Nutzer-Feedback:
- Dashboard-Kalender zeigte eine Stunde doppelt, wenn sie über "Sitzung
  erzeugen" mit einer Mitarbeitssitzung verknüpft war.
- Der Sitzplan-Tab legte beim bloßen Öffnen einer Gruppe (nicht erst bei
  echter Nutzung) eine leere "Sitzplan"-Sitzung für heute an.
- Der "Meine Klasse"-Ring im Kalender erschien erst, sobald für den Tag
  eine Lesson existierte, statt schon laut Stundenplan.

Außerdem: Drawer-Icons pinnen jetzt explizit auf die farbige Emoji-Schrift
(Windows kann sonst je nach Font-Fallback auf eine einfarbige Variante
ausweichen).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-19 23:17:18 +02:00
co-authored by Claude Sonnet 5
parent 4d2a89b14b
commit 52a1d45539
16 changed files with 505 additions and 57 deletions
+63 -9
View File
@@ -1112,7 +1112,16 @@ dadurch faktisch schon (Quick-Input-Dialog bzw. "Offene Entschuldigungen" im Das
(`OtherSchoolEvent`) zählt bewusst nicht als Fehlzeit des Schülers.
- [x] **5.2.3** Schwellenwert-Warnung (> 20 %) — `AttendanceBalance.ExceedsThreshold` im
Schülerdetail sowie eine neue "Fehlzeiten-Warnung"-Karte im Dashboard (alle Schüler über
dem Schwellenwert, sortiert nach Fehlquote).
dem Schwellenwert, sortiert nach Fehlquote). **Nachtrag (Nutzer-Feedback):** die
Dashboard-Karte meldete anfangs auch Schüler mit nur ein oder zwei erfassten Terminen — wer
zu Schuljahresbeginn einmal fehlt, steht damit rechnerisch schon bei 100 %, obwohl das noch
kein auffälliges Muster ist, nur eine zu kleine Stichprobe. `DashboardViewModel.LoadAttendanceWarnings`
meldet jetzt erst ab `AttendanceMinSampleSize` (8) im laufenden Schuljahr erfassten Terminen
(`AttendanceBalance.TotalChecked`) — dieselbe Konstante und Prüfung wie in der
Kurs-Übersicht (14.12, `GroupOverviewViewModel`), an der das zuerst aufgefallen ist.
`AttendanceBalanceService` selbst bleibt unverändert (liefert weiterhin die reine Quote ohne
Mindeststichprobe, z.B. für die Anzeige im Schülerdetail) — die Gate-Prüfung liegt bewusst
nur bei den beiden "Warnung"-Konsumenten.
- [x] **5.2.4** Nachträgliches Entschuldigen mit Frist-Hinweis — bereits vorhanden über die
"Offene Entschuldigungen"-Karte im Dashboard (21-Tage-Grenze, aus Kapitel 3).
@@ -1177,6 +1186,17 @@ CSV-Exports der Auswertung (6.3.3) über die gemeinsame Export-Infrastruktur aus
auf `Conducted` (Anbindung an 1.1.3) — Hook in `GroupDetailViewModel.SetExamStatus`, feuert
nur beim *erstmaligen* Wechsel von `Planned` auf `Conducted` (nicht bei jedem erneuten
Klick), Fälligkeit 14 Tage nach dem Klausurtermin, Kategorie `Correction`.
- [x] **6.1.6** "Erinnerung" als eigene Aufgabenart (Nutzer-Feedback): "Aufgaben" wirkte wie reine
Zeiterfassung, dabei braucht es auch schlichte Reminder ohne Zeitbezug (z.B. "morgen Ansage
an die Klasse machen"). Neues `WorkTask.Kind` (`TaskKind`: `WorkItem`/`Reminder`, Default
`WorkItem` — kein Migrationsschritt nötig, fehlendes BSON-Feld deserialisiert auf den
Enum-Default). Eigener Button "🔔 Erinnerung" neben " Neue Aufgabe"
(`WorkTaskListViewModel.AddReminderCommand`) öffnet denselben `AddEditWorkTaskDialog`, aber
mit der Checkbox "Nur Erinnerung" vorbelegt — dadurch entfällt automatisch das
"Geschätzte Dauer"-Feld (Erinnerungen bekommen nie einen Zeitwert). Läuft bewusst nicht in
die Zeitauswertung (6.3) ein — die bereits rein datenmodell-bedingt, da `WorkloadEvaluationViewModel`
nur tatsächlich erfasste `TimeEntry`-Zeilen auswertet, keine `WorkTask`-Metadaten. In der
Aufgabenliste und im Dashboard-Widget "Offene Aufgaben" durch ein 🔔-Symbol gekennzeichnet.
### 6.2 Zeiterfassung
- [x] **6.2.1** Timer starten/stoppen mit Zuordnung zu Aufgabe oder Kategorie —
@@ -1272,6 +1292,14 @@ Hinweis in Kapitel 1 — betrifft auch Kurse, nicht nur Klassen.
Mitarbeitsaspekte, Anwesenheit und Hausaufgaben. Die Eingabe unterstützt Maus sowie
Tastenkürzel und schreibt in die heutige Mitarbeitssitzung; falls noch keine existiert,
wird einmalig eine Sitzung „Sitzplan“ für heute angelegt.
**Bugfix (Nutzer-Feedback, "Geistereinträge"):** Diese Sitzung entstand ursprünglich schon
beim bloßen Initialisieren des Sitzplan-Tabs (`SeatingPlanTabViewModel.LoadTodaySessions`)
— und `GroupDetailViewModel.LoadGroup` initialisiert alle Tabs einer Gruppe sofort beim
Navigieren dorthin, unabhängig davon, welcher Tab tatsächlich angesehen wird. Ergebnis:
praktisch jede an dem Tag geöffnete Gruppe bekam eine leere "Sitzplan"-Sitzung, auch wenn nie
tatsächlich bewertet wurde. `LoadTodaySessions()` legt jetzt keine Sitzung mehr an; die
Erzeugung passiert erst über `EnsureTodaySession()` bei der ersten tatsächlichen Aktion
(Sitzplatz-Bewertung oder Situations-Tag).
### 7.2 Gruppen
- [x] **7.2.1** Gruppe bearbeiten und löschen — bereits vorhanden (`EditGroupCommand`/`DeleteGroupCommand`/
@@ -1366,6 +1394,18 @@ Basis vorhanden in [DashboardViewModel.cs](LehrerApp.Desktop/ViewModels/Dashboar
Kleiner Monatskalender ist bereits umgesetzt (Farbcodierung Unterricht/Klausur,
Hervorhebung "eigene Klasse" über `LearningGroup.IsOwnClass`, feste Kartenbreite/-position).
**Zwei Bugfixes am Kalender (Nutzer-Feedback):**
- Eine über "Sitzung erzeugen" (3.3.1) aus einer Stunde entstandene `ParticipationSession`
(`LessonId` gesetzt) erzeugte einen zweiten, redundanten Kalendereintrag neben der Stunde selbst
— dieselbe Unterrichtsstunde stand doppelt in der Tagesliste. `LoadCalendar()` überspringt
jetzt Sitzungen mit gesetzter `LessonId` (die zugehörige Lesson deckt den Tag bereits ab).
- Der "Meine Klasse"-Ring war nur gesetzt, wenn für den Tag schon eine Lesson/Exam/Sitzung
existierte — ein Tag, an dem laut Stundenplan (4.3) die eigene Klasse ansteht, aber noch keine
Lesson angelegt wurde (typischerweise "morgen"), zeigte den Ring fälschlich nicht. `LoadCalendar()`
projiziert `IsOwnClassDay` jetzt zusätzlich aus dem Stundenplan (`TimetableSlot`, abzüglich
Ferien/Feiertage und `SubstitutionKind.Cancelled`) — dieselbe Projektion wie bei den "ungeplanten
Stunden" (`LoadUnplannedLessons`), nur über den ganzen Kalenderraster statt nur die nächsten Tage.
- [x] **9.1** Heutige Stunden mit Uhrzeit und Raum anzeigen (Abhängigkeit zu 4.3, jetzt erfüllt).
**Umsetzung:** `DashboardViewModel.TodaysLessons` löst je Stunde den Raum über den zur
Stundennummer und dem heutigen Wochentag passenden `TimetableSlot` auf, die Uhrzeit aus
@@ -2185,7 +2225,16 @@ von 4.2.2) der Tab "Kürzel-Katalog" für die Von/Nach-Kürzel des Stundenverlau
- [ ] **14.9** Barrierefreiheit prüfen: Automation-Namen für Icon-Buttons, sichtbare Fokusrahmen,
Kontraste und Status nicht ausschließlich über Farbe/Emoji vermitteln.
- [ ] **14.10** Plattformübergreifend konsistentes SVG-/`PathIcon`-Set statt systemabhängiger
Emoji-Darstellung einführen.
Emoji-Darstellung einführen. **Konkreter Bericht (Nutzer-Feedback):** Drawer-Icons erscheinen
auf einem Windows-PC gegen 22 Uhr einfarbig schwarz statt farbig — passend zum bekannten
Windows-Verhalten, dass Emoji-Codepunkte je nach Font-Fallback statt der farbigen
"Segoe UI Emoji" auf die einfarbige "Segoe UI Symbol" ausweichen können (typischer Auslöser:
ein zeitgesteuerter Hell/Dunkel-Wechsel des Systemthemas). Als Sofortmaßnahme pinnt
`TextBlock.navicon` in [MainWindow.axaml](LehrerApp.Desktop/Views/MainWindow.axaml) jetzt
explizit `FontFamily="Segoe UI Emoji,Segoe UI Symbol,Segoe UI"` — auf anderen Plattformen
folgenlos, da unbekannte Fontnamen einfach übersprungen werden. Nur eine Abmilderung für die
Drawer-Navigation, kein Nachweis der Ursache und keine Lösung für die übrigen Emoji im Rest
der App — die eigentliche, dauerhafte Lösung bleibt dieser Punkt (echtes Icon-Set).
- [x] **14.11** Aktiven Navigationspunkt in der Seitenleiste sichtbar hervorheben; Zustand wird
über `MainWindowViewModel.ActiveNavItem` gesteuert.
- [x] **14.12** Tab "Übersicht" im Kurs (`GroupDetailView`, bislang nur Platzhaltertext) gefüllt —
@@ -2200,13 +2249,18 @@ von 4.2.2) der Tab "Kürzel-Katalog" für die Von/Nach-Kürzel des Stundenverlau
Karte wie im globalen Dashboard (9), hier nur auf den einen Kurs eingeschränkt statt über
alle Gruppen aggregiert. **Nachtrag (Nutzer-Feedback):** zwei weitere Karten — offene
Dokumentationen (`Documentation.IsDraft`-Zählung, dieselbe wie das Badge in
`GroupDocumentationTabViewModel`) und auffällige Fehlzeiten. Letztere bewusst KEIN 1:1-Abbild
der Dashboard-Fehlzeiten-Warnung: dieselbe Quote (`AttendanceBalanceService.WarningThresholdPercent`,
20 %), aber erst ab `GroupOverviewViewModel.AttendanceMinSampleSize` (8) erfassten
Anwesenheits-Terminen im laufenden Schuljahr gemeldet — wer zu Schuljahresbeginn zweimal
fehlt, hat rechnerisch schon 100 % Fehlquote, das ist noch kein auffälliges Muster, nur eine
zu kleine Stichprobe. Dasselbe Problem hat die Fehlzeiten-Warnung im Hauptdashboard (5.2.3)
aktuell noch — dort bewusst unangetastet gelassen, wird separat nachgezogen.
`GroupDocumentationTabViewModel`) und auffällige Fehlzeiten. Dieselbe Quote wie die
Dashboard-Fehlzeiten-Warnung (`AttendanceBalanceService.WarningThresholdPercent`, 20 %),
aber optisch zurückhaltender (kein rotes Warnfall-Badge) und erst ab
`GroupOverviewViewModel.AttendanceMinSampleSize` (8) erfassten Anwesenheits-Terminen im
laufenden Schuljahr gemeldet — wer zu Schuljahresbeginn zweimal fehlt, hat rechnerisch schon
100 % Fehlquote, das ist noch kein auffälliges Muster, nur eine zu kleine Stichprobe.
Dieselbe Mindeststichprobe wurde im Zuge dessen auch in die Dashboard-Fehlzeiten-Warnung
selbst nachgezogen, siehe 5.2.3. **Zweiter Nachtrag (Nutzer-Feedback):** dritte Karte
"Fehlende Hausaufgaben" — Schüler mit `ParticipationEntry.HomeworkMissing` aus der letzten
Mitarbeitssitzung (bewusst nur die letzte, nicht die gesamte Historie, analog zur
Hausaufgaben-Kontrolle oben), mit dem konkreten Status je Schüler (`HomeworkDisplay.Label`,
z.B. "Nicht gemacht Nachreichen offen").
---