feat: unbenutzte Sitzplätze ausblenden können

Manche Räume sind unregelmäßig bestückt (z.B. eine Klasse mit 3 Reihen, in zwei davon fehlt ein
Einzeltisch) - das feste Rows x Columns-Raster kennt aber keine per-Reihe abweichende Spaltenzahl.

Neues Feld SeatingPlan.HiddenSeats für Plätze ohne physischen Tisch. Ein ausgeblendeter Platz
bleibt Teil des Rasters (für die Spalten-/Reihenausrichtung von SeatingPlanPanel), wird im
Ansichtsmodus aber nicht gerendert; im Bearbeitungsmodus bleibt er sichtbar (abgeblendet) mit
einem Umschalt-Button direkt auf dem Platz. Nur leere Plätze lassen sich ausblenden; Zuweisen/
Verschieben eines Schülers auf einen ausgeblendeten Platz wird sowohl im ViewModel als auch im
Drag&Drop-Ziel-Check verhindert. SeatingPlanRepository.Save filtert HiddenSeats zusätzlich auf
das gültige Raster und blendet einen Platz automatisch wieder ein, falls er trotzdem belegt wird.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-20 12:06:26 +02:00
co-authored by Claude Sonnet 5
parent 391628ae36
commit c5a1157a7d
8 changed files with 334 additions and 8 deletions
+23
View File
@@ -1333,6 +1333,29 @@ Hinweis in Kapitel 1 — betrifft auch Kurse, nicht nur Klassen.
Erzeugung passiert erst über `EnsureTodaySession()` bei der ersten tatsächlichen Aktion
(Sitzplatz-Bewertung oder Situations-Tag).
**Nachtrag (Feature-Ergänzung, Nutzerwunsch): unbenutzte Plätze ausblenden.** Manche Räume
sind unregelmäßig bestückt (z. B. eine Klasse mit 3 Reihen, in zwei davon fehlt ein
Einzeltisch) — das feste `Rows × Columns`-Raster kennt aber keine per-Reihe abweichende
Spaltenzahl. Statt einer negativen "Schüler-ID" als Sonderfall (das war der ursprünglich
vorgeschlagene Ansatz, scheidet aber aus, da `SeatAssignment.StudentId` ein `Guid` ist, kein
vorzeichenbehafteter Zahlentyp) gibt es jetzt ein eigenes Feld `SeatingPlan.HiddenSeats`
(`List<HiddenSeat { Row, Column }>`, analog zu `SeatAssignment`) für Plätze ohne physischen
Tisch. Ein ausgeblendeter Platz bleibt Teil des Rasters (für die Spalten-/Reihenausrichtung
der `SeatingPlanPanel`-Layoutmathematik), wird im Ansichtsmodus aber nicht gerendert
(`SeatCellViewModel.ShowSeat`); im Bearbeitungsmodus bleibt er sichtbar (abgeblendet), mit
einem Umschalt-Button "Kein Tisch hier" / "Tisch einblenden" direkt auf dem Platz. Nur leere
Plätze lassen sich ausblenden (`CanToggleHidden`); Zuweisen/Verschieben eines Schülers auf
einen ausgeblendeten Platz wird sowohl im ViewModel (`AssignStudent`/`MoveSeat`) als auch im
Drag&Drop-Ziel-Check der View verhindert. `SeatingPlanRepository.Save` filtert
`HiddenSeats` zusätzlich auf das gültige Raster und blendet einen Platz automatisch wieder
ein, falls er (z. B. durch einen älteren, noch nicht aktualisierten Client per Sync)
trotzdem belegt wird — die Zuordnung eines Schülers ist wertvoller als das Ausblenden und
geht nie verloren. Keine Änderungen an `EventApplier`/`SyncEngine` nötig, `SeatingPlan` wird
bereits als Ganzes synchronisiert. Neue Tests: `RepositoryTests`
(Rasterfilterung, automatisches Wiedereinblenden bei Belegung), `SeatingPlanViewModelTests`
(Laden, Umschalten inkl. Persistieren, Sperre für belegte Plätze, verhinderte Zuweisung auf
ausgeblendete Plätze, `ShowSeat`/`CanToggleHidden` je nach Modus).
### 7.2 Gruppen
- [x] **7.2.1** Gruppe bearbeiten und löschen — bereits vorhanden (`EditGroupCommand`/`DeleteGroupCommand`/
`ToggleArchiveCommand` in `GroupListViewModel`), nicht Teil der aktuellen Klausuren-Arbeit,