Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
edf7510765 |
@@ -294,4 +294,44 @@ public class PlanningTabViewModelTests
|
|||||||
Assert.Single(sessions.GetByGroup(groupId));
|
Assert.Single(sessions.GetByGroup(groupId));
|
||||||
Assert.Equal("Für diese Stunde existiert bereits eine Sitzung.", notified);
|
Assert.Equal("Für diese Stunde existiert bereits eine Sitzung.", notified);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void CreateParticipationSession_AndereStundeAmSelbenTagBereitsVerknuepft_LegtKeineZweiteSitzungAn()
|
||||||
|
{
|
||||||
|
// Nutzer-Feedback: eine dritte Stunde am selben Tag (z.B. Vertretung) soll die bereits
|
||||||
|
// bestehende Sitzung des Tages weiterverwenden statt eine zweite anzulegen.
|
||||||
|
var groupId = Guid.NewGuid();
|
||||||
|
var group = new LearningGroup { Id = groupId, Name = "Testgruppe" };
|
||||||
|
var groups = new FakeGroups([group]);
|
||||||
|
var units = new FakeUnits();
|
||||||
|
var lessons = new FakeLessons();
|
||||||
|
var sessions = new FakeSessions([]);
|
||||||
|
var vm = new PlanningTabViewModel(units, lessons, groups, new FakeSubjects([]),
|
||||||
|
new FakeCompetencyDomains(), TestSupport.BuildAiSettingsService(), sessions);
|
||||||
|
vm.Initialize(groupId);
|
||||||
|
|
||||||
|
var unit = new Unit { GroupId = groupId, Title = "Optik" };
|
||||||
|
units.Add(unit);
|
||||||
|
var date = new DateOnly(2025, 9, 1);
|
||||||
|
var doubleLesson = new Lesson
|
||||||
|
{ UnitId = unit.Id, GroupId = groupId, Date = date, Topic = "Brechung" };
|
||||||
|
var thirdLesson = new Lesson
|
||||||
|
{ UnitId = unit.Id, GroupId = groupId, Date = date, Topic = "Vertretung" };
|
||||||
|
lessons.Add(doubleLesson);
|
||||||
|
lessons.Add(thirdLesson);
|
||||||
|
|
||||||
|
vm.RefreshPlanning(unit.Id, doubleLesson.Id);
|
||||||
|
vm.SelectedLesson = vm.Lessons.Single(l => l.Id == doubleLesson.Id);
|
||||||
|
vm.CreateParticipationSessionCommand.Execute(null);
|
||||||
|
|
||||||
|
string? notified = null;
|
||||||
|
vm.OnNotify = m => notified = m;
|
||||||
|
vm.RefreshPlanning(unit.Id, thirdLesson.Id);
|
||||||
|
vm.SelectedLesson = vm.Lessons.Single(l => l.Id == thirdLesson.Id);
|
||||||
|
vm.CreateParticipationSessionCommand.Execute(null);
|
||||||
|
|
||||||
|
var created = Assert.Single(sessions.GetByGroup(groupId));
|
||||||
|
Assert.Equal(doubleLesson.Id, created.LessonId);
|
||||||
|
Assert.Equal("Für diesen Tag existiert bereits eine Sitzung.", notified);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -256,6 +256,30 @@ public sealed class SeatingPlanViewModelTests
|
|||||||
Assert.Single(sessions.GetByGroup(groupId));
|
Assert.Single(sessions.GetByGroup(groupId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SelectOrCreateSessionForLesson_AndereStundeAmSelbenTagBereitsVerknuepft_LegtKeineZweiteSitzungAn()
|
||||||
|
{
|
||||||
|
// Nutzer-Feedback: eine dritte Stunde am selben Tag (z.B. durch Vertretung, eigene Lesson-
|
||||||
|
// Id) soll die bereits bestehende Sitzung der Doppelstunde weiterverwenden statt eine
|
||||||
|
// zweite, unabhängige Sitzung für denselben Tag anzulegen.
|
||||||
|
var groupId = Guid.NewGuid();
|
||||||
|
var today = DateOnly.FromDateTime(DateTime.Today);
|
||||||
|
var doubleLesson = new Lesson { GroupId = groupId, Date = today, Topic = "Redox" };
|
||||||
|
var thirdLesson = new Lesson { GroupId = groupId, Date = today, Topic = "Vertretung" };
|
||||||
|
var existingSession = new ParticipationSession
|
||||||
|
{ GroupId = groupId, Date = today, LessonId = doubleLesson.Id, Comment = "Redox" };
|
||||||
|
var sessions = new FakeSessions([existingSession]);
|
||||||
|
var plan = new SeatingPlan { GroupId = groupId, Name = "Standard", Rows = 1, Columns = 1 };
|
||||||
|
var vm = new SeatingPlanTabViewModel(new FakeSeatingPlans([plan]), new FakeStudents([]),
|
||||||
|
new FakeMemberships([]), sessions, new FakeEntries(), new FakeAspects());
|
||||||
|
vm.Initialize(groupId, isReadOnly: false);
|
||||||
|
|
||||||
|
vm.SelectOrCreateSessionForLesson(thirdLesson);
|
||||||
|
|
||||||
|
Assert.Equal(existingSession.Id, vm.SelectedSession?.Id);
|
||||||
|
Assert.Single(sessions.GetByGroup(groupId));
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void SelectOrCreateSessionForLesson_KeineSitzungVorhanden_LegtVerknuepfteAnUndWaehltSieAus()
|
public void SelectOrCreateSessionForLesson_KeineSitzungVorhanden_LegtVerknuepfteAnUndWaehltSieAus()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -364,16 +364,25 @@ public partial class PlanningTabViewModel : ObservableObject
|
|||||||
/// Übernimmt Datum + Thema der Stunde in eine neue Mitarbeitssitzung (3.3.1) — verknüpft über
|
/// Übernimmt Datum + Thema der Stunde in eine neue Mitarbeitssitzung (3.3.1) — verknüpft über
|
||||||
/// das bisher ungenutzte Lesson.LessonId-Feld auf ParticipationSession, damit ein zweiter Klick
|
/// das bisher ungenutzte Lesson.LessonId-Feld auf ParticipationSession, damit ein zweiter Klick
|
||||||
/// auf dieselbe Stunde keine doppelte Sitzung anlegt, sondern nur darauf hinweist.
|
/// auf dieselbe Stunde keine doppelte Sitzung anlegt, sondern nur darauf hinweist.
|
||||||
|
///
|
||||||
|
/// Prüft dabei zusätzlich auf JEDE bereits an diesem Tag bestehende Sitzung, nicht nur eine
|
||||||
|
/// exakt mit `lesson.Id` verknüpfte (Nutzer-Feedback, analog
|
||||||
|
/// <see cref="SeatingPlanTabViewModel.SelectOrCreateSessionForLesson"/>): kommt neben einer
|
||||||
|
/// Doppelstunde noch eine dritte Stunde desselben Tages hinzu (eigene `Lesson`, z.B. durch
|
||||||
|
/// Vertretung), soll das nicht zu einer zweiten Mitarbeitssitzung für den Tag führen.
|
||||||
[RelayCommand(CanExecute = nameof(HasSelectedLesson))]
|
[RelayCommand(CanExecute = nameof(HasSelectedLesson))]
|
||||||
private void CreateParticipationSession()
|
private void CreateParticipationSession()
|
||||||
{
|
{
|
||||||
if (SelectedLesson is null) return;
|
if (SelectedLesson is null) return;
|
||||||
var lesson = SelectedLesson.Model;
|
var lesson = SelectedLesson.Model;
|
||||||
var existing = _participationSessions.GetByGroup(lesson.GroupId)
|
var sessionsForGroup = _participationSessions.GetByGroup(lesson.GroupId);
|
||||||
.FirstOrDefault(s => s.LessonId == lesson.Id);
|
var existing = sessionsForGroup.FirstOrDefault(s => s.LessonId == lesson.Id)
|
||||||
|
?? sessionsForGroup.FirstOrDefault(s => s.Date == lesson.Date);
|
||||||
if (existing is not null)
|
if (existing is not null)
|
||||||
{
|
{
|
||||||
OnNotify?.Invoke("Für diese Stunde existiert bereits eine Sitzung.");
|
OnNotify?.Invoke(existing.LessonId == lesson.Id
|
||||||
|
? "Für diese Stunde existiert bereits eine Sitzung."
|
||||||
|
: "Für diesen Tag existiert bereits eine Sitzung.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -141,10 +141,18 @@ public partial class SeatingPlanTabViewModel : ObservableObject
|
|||||||
/// erlaubt: welche Stunde gemeint ist, steht durch die explizite Auswahl der Lehrkraft
|
/// erlaubt: welche Stunde gemeint ist, steht durch die explizite Auswahl der Lehrkraft
|
||||||
/// (Klick auf "Unterrichtsmodus starten" für genau diese Stunde) bereits unzweideutig fest -
|
/// (Klick auf "Unterrichtsmodus starten" für genau diese Stunde) bereits unzweideutig fest -
|
||||||
/// keine Geistersitzungs-Gefahr wie beim bloßen Öffnen eines Tabs.
|
/// keine Geistersitzungs-Gefahr wie beim bloßen Öffnen eines Tabs.
|
||||||
|
///
|
||||||
|
/// Fällt bewusst auf JEDE an diesem Tag bereits bestehende Sitzung zurück, nicht nur auf eine
|
||||||
|
/// exakt mit `lesson.Id` verknüpfte (Nutzer-Feedback): kommt neben einer Doppelstunde noch eine
|
||||||
|
/// dritte Stunde am selben Tag hinzu (z.B. Vertretung, eigene `Lesson` mit eigener Id), soll
|
||||||
|
/// keine zweite Mitarbeitssitzung für denselben Tag entstehen — die Lehrkraft passt stattdessen
|
||||||
|
/// die Einschätzung der bereits bestehenden Sitzung an. Das entspricht dem Verhalten von
|
||||||
|
/// <see cref="EnsureTodaySession"/>, das schon immer pro Tag statt pro Stunde arbeitet.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void SelectOrCreateSessionForLesson(Lesson lesson)
|
public void SelectOrCreateSessionForLesson(Lesson lesson)
|
||||||
{
|
{
|
||||||
var existing = TodaySessions.FirstOrDefault(s => s.LessonId == lesson.Id);
|
var existing = TodaySessions.FirstOrDefault(s => s.LessonId == lesson.Id)
|
||||||
|
?? TodaySessions.FirstOrDefault(s => s.Date == lesson.Date);
|
||||||
if (existing is not null) { SelectedSession = existing; return; }
|
if (existing is not null) { SelectedSession = existing; return; }
|
||||||
if (!IsEditable) return;
|
if (!IsEditable) return;
|
||||||
|
|
||||||
|
|||||||
@@ -45,9 +45,9 @@
|
|||||||
<ComboBoxItem Content="Heute"/><ComboBoxItem Content="Letzte 7 Tage"/><ComboBoxItem Content="Letzte 30 Tage"/>
|
<ComboBoxItem Content="Heute"/><ComboBoxItem Content="Letzte 7 Tage"/><ComboBoxItem Content="Letzte 30 Tage"/>
|
||||||
</ComboBox>
|
</ComboBox>
|
||||||
<TextBlock Grid.Column="1" Text="von" VerticalAlignment="Center" Opacity="0.6"/>
|
<TextBlock Grid.Column="1" Text="von" VerticalAlignment="Center" Opacity="0.6"/>
|
||||||
<CalendarDatePicker Grid.Column="2" SelectedDate="{Binding StartDate}" HorizontalAlignment="Stretch"/>
|
<DatePicker Grid.Column="2" SelectedDate="{Binding StartDate}" HorizontalAlignment="Stretch"/>
|
||||||
<TextBlock Grid.Column="3" Text="bis" VerticalAlignment="Center" Opacity="0.6"/>
|
<TextBlock Grid.Column="3" Text="bis" VerticalAlignment="Center" Opacity="0.6"/>
|
||||||
<CalendarDatePicker Grid.Column="4" SelectedDate="{Binding EndDate}" HorizontalAlignment="Stretch"/>
|
<DatePicker Grid.Column="4" SelectedDate="{Binding EndDate}" HorizontalAlignment="Stretch"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid Grid.Row="1" ColumnDefinitions="*,Auto,Auto" ColumnSpacing="8">
|
<Grid Grid.Row="1" ColumnDefinitions="*,Auto,Auto" ColumnSpacing="8">
|
||||||
<TextBox Grid.Column="0" Text="{Binding StudentFilter, Mode=TwoWay}" PlaceholderText="Schüler*in filtern…"/>
|
<TextBox Grid.Column="0" Text="{Binding StudentFilter, Mode=TwoWay}" PlaceholderText="Schüler*in filtern…"/>
|
||||||
|
|||||||
@@ -45,9 +45,9 @@
|
|||||||
<ComboBoxItem Content="Heute"/><ComboBoxItem Content="Letzte 7 Tage"/><ComboBoxItem Content="Letzte 30 Tage"/>
|
<ComboBoxItem Content="Heute"/><ComboBoxItem Content="Letzte 7 Tage"/><ComboBoxItem Content="Letzte 30 Tage"/>
|
||||||
</ComboBox>
|
</ComboBox>
|
||||||
<TextBlock Grid.Column="1" Text="von" VerticalAlignment="Center" Opacity="0.6"/>
|
<TextBlock Grid.Column="1" Text="von" VerticalAlignment="Center" Opacity="0.6"/>
|
||||||
<CalendarDatePicker Grid.Column="2" SelectedDate="{Binding StartDate}" HorizontalAlignment="Stretch"/>
|
<DatePicker Grid.Column="2" SelectedDate="{Binding StartDate}" HorizontalAlignment="Stretch"/>
|
||||||
<TextBlock Grid.Column="3" Text="bis" VerticalAlignment="Center" Opacity="0.6"/>
|
<TextBlock Grid.Column="3" Text="bis" VerticalAlignment="Center" Opacity="0.6"/>
|
||||||
<CalendarDatePicker Grid.Column="4" SelectedDate="{Binding EndDate}" HorizontalAlignment="Stretch"/>
|
<DatePicker Grid.Column="4" SelectedDate="{Binding EndDate}" HorizontalAlignment="Stretch"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid Grid.Row="1" ColumnDefinitions="*,Auto,Auto" ColumnSpacing="8">
|
<Grid Grid.Row="1" ColumnDefinitions="*,Auto,Auto" ColumnSpacing="8">
|
||||||
<TextBox Grid.Column="0" Text="{Binding StudentFilter, Mode=TwoWay}" PlaceholderText="Schüler*in filtern…"/>
|
<TextBox Grid.Column="0" Text="{Binding StudentFilter, Mode=TwoWay}" PlaceholderText="Schüler*in filtern…"/>
|
||||||
|
|||||||
@@ -12,9 +12,9 @@
|
|||||||
FontSize="12" Opacity="0.65" TextWrapping="Wrap"/>
|
FontSize="12" Opacity="0.65" TextWrapping="Wrap"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<StackPanel Grid.Row="1" Orientation="Horizontal" Spacing="8">
|
<StackPanel Grid.Row="1" Orientation="Horizontal" Spacing="8">
|
||||||
<DatePicker SelectedDate="{Binding StartDate}"/>
|
<CalendarDatePicker SelectedDate="{Binding StartDate}"/>
|
||||||
<TextBlock Text="bis" VerticalAlignment="Center"/>
|
<TextBlock Text="bis" VerticalAlignment="Center"/>
|
||||||
<DatePicker SelectedDate="{Binding EndDate}"/>
|
<CalendarDatePicker SelectedDate="{Binding EndDate}"/>
|
||||||
<Button Content="Fehlzeiten laden" Command="{Binding LoadCommand}" IsEnabled="{Binding !Busy}"/>
|
<Button Content="Fehlzeiten laden" Command="{Binding LoadCommand}" IsEnabled="{Binding !Busy}"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<Grid Grid.Row="2" ColumnDefinitions="Auto,1.2*,1.2*,80,80,1.1*,1.1*" ColumnSpacing="8" Margin="4,0">
|
<Grid Grid.Row="2" ColumnDefinitions="Auto,1.2*,1.2*,80,80,1.1*,1.1*" ColumnSpacing="8" Margin="4,0">
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
<DataTemplate x:DataType="svc:UntisTeacherDto"><TextBlock Text="{Binding DisplayName}"/></DataTemplate>
|
<DataTemplate x:DataType="svc:UntisTeacherDto"><TextBlock Text="{Binding DisplayName}"/></DataTemplate>
|
||||||
</ComboBox.ItemTemplate>
|
</ComboBox.ItemTemplate>
|
||||||
</ComboBox>
|
</ComboBox>
|
||||||
<CalendarDatePicker Grid.Column="1" SelectedDate="{Binding WeekDate}"/>
|
<DatePicker Grid.Column="1" SelectedDate="{Binding WeekDate}"/>
|
||||||
<Button Grid.Column="2" Content="Woche laden" Command="{Binding LoadCommand}" IsEnabled="{Binding !Busy}"/>
|
<Button Grid.Column="2" Content="Woche laden" Command="{Binding LoadCommand}" IsEnabled="{Binding !Busy}"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<ScrollViewer Grid.Row="2">
|
<ScrollViewer Grid.Row="2">
|
||||||
|
|||||||
@@ -12,9 +12,9 @@
|
|||||||
Text="Nur eigene WebUntis-Einträge (Benutzer = eigener Login). Zeilen ohne automatische Zuordnung bitte manuell einem/einer Schüler*in zuweisen. Bereits lokal vorhandene Einträge sind gesperrt."/>
|
Text="Nur eigene WebUntis-Einträge (Benutzer = eigener Login). Zeilen ohne automatische Zuordnung bitte manuell einem/einer Schüler*in zuweisen. Bereits lokal vorhandene Einträge sind gesperrt."/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<StackPanel Grid.Row="1" Orientation="Horizontal" Spacing="8">
|
<StackPanel Grid.Row="1" Orientation="Horizontal" Spacing="8">
|
||||||
<CalendarDatePicker SelectedDate="{Binding StartDate}"/>
|
<DatePicker SelectedDate="{Binding StartDate}"/>
|
||||||
<TextBlock Text="bis" VerticalAlignment="Center"/>
|
<TextBlock Text="bis" VerticalAlignment="Center"/>
|
||||||
<CalendarDatePicker SelectedDate="{Binding EndDate}"/>
|
<DatePicker SelectedDate="{Binding EndDate}"/>
|
||||||
<Button Content="Klassenbucheinträge laden" Command="{Binding LoadCommand}" IsEnabled="{Binding !Busy}"/>
|
<Button Content="Klassenbucheinträge laden" Command="{Binding LoadCommand}" IsEnabled="{Binding !Busy}"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
|
|||||||
@@ -1393,16 +1393,13 @@ Zugangsdaten; Schülerdaten, Fehlzeiten und der unverschlüsselte CSV-Report pas
|
|||||||
unentschuldigt übernommen werden; fremde/ganztägige Abwesenheiten erzeugen keine lokale Stunde.
|
unentschuldigt übernommen werden; fremde/ganztägige Abwesenheiten erzeugen keine lokale Stunde.
|
||||||
|
|
||||||
**Nachtrag (September 2026, Nutzer-Feedback) — Zeitraum-Datumsfelder ließen sich nicht ändern:**
|
**Nachtrag (September 2026, Nutzer-Feedback) — Zeitraum-Datumsfelder ließen sich nicht ändern:**
|
||||||
Avalonias WinUI-artiger Spinner-`DatePicker` übernimmt Änderungen im Tag/Monat/Jahr-Flyout nur über
|
die beiden `DatePicker` oben im Dialog ([WebUntisLessonAbsenceComparisonDialog.axaml](LehrerApp.Desktop/Views/Groups/WebUntisLessonAbsenceComparisonDialog.axaml))
|
||||||
einen separaten Häkchen-Button; ein Klick daneben verwirft sie stillschweigend. Alle verbliebenen
|
sind Avalonias WinUI-artiger Spinner-`DatePicker` — Änderungen im Tag/Monat/Jahr-Flyout werden nur
|
||||||
Zeitraum-Datumsfelder mit diesem `DatePicker` auf `CalendarDatePicker` umgestellt (gleiche
|
über einen separaten Häkchen-Button im Flyout übernommen, ein Klick daneben verwirft sie
|
||||||
`DateTimeOffset?`-Bindung, kein Typwechsel nötig) — bereits das etablierte Muster für frei wählbare
|
stillschweigend. Ersetzt durch `CalendarDatePicker` (gleiche `DateTimeOffset?`-Bindung, kein
|
||||||
Einzeldatumsfelder in dieser Codebasis (`WithdrawStudentDialog`, `CreateLetterDialog`, 7.2.3), dort
|
Typwechsel nötig) — bereits das etablierte Muster für frei wählbare Einzeldatumsfelder in dieser
|
||||||
ohne dieses Problem, da ein Klick auf einen Kalendertag sofort übernimmt statt einen
|
Codebasis (`WithdrawStudentDialog`, `CreateLetterDialog`, 7.2.3), dort ohne dieses Problem, da
|
||||||
Bestätigungsschritt zu verlangen. Betroffen: [ClassTeacherRegisterView.axaml](LehrerApp.Desktop/Views/ClassTeacher/ClassTeacherRegisterView.axaml),
|
ein Klick auf einen Kalendertag sofort übernimmt statt einen Bestätigungsschritt zu verlangen.
|
||||||
[ClassTeacherAbsencesView.axaml](LehrerApp.Desktop/Views/ClassTeacher/ClassTeacherAbsencesView.axaml),
|
|
||||||
[WebUntisTimetableImportDialog.axaml](LehrerApp.Desktop/Views/Planning/WebUntisTimetableImportDialog.axaml)
|
|
||||||
und [WebUntisDocumentationComparisonDialog.axaml](LehrerApp.Desktop/Views/Students/WebUntisDocumentationComparisonDialog.axaml).
|
|
||||||
|
|
||||||
**Nachtrag zu 4.3, Fehlzeiten je Unterricht (August 2026):** Der ursprüngliche Fehlzeitenabgleich
|
**Nachtrag zu 4.3, Fehlzeiten je Unterricht (August 2026):** Der ursprüngliche Fehlzeitenabgleich
|
||||||
rief `getTimetableWithAbsences` ohne Element auf und bekam damit den kompletten Lehrer-Stundenplan
|
rief `getTimetableWithAbsences` ohne Element auf und bekam damit den kompletten Lehrer-Stundenplan
|
||||||
@@ -2153,6 +2150,22 @@ folgenden Punkte gehören direkt in `LehrerApp.Desktop`:
|
|||||||
den vollen Verlaufsplan-Editor öffnen müssen. Neue kleine
|
den vollen Verlaufsplan-Editor öffnen müssen. Neue kleine
|
||||||
`TeachingModeHomeworkViewModel : ObservableObject`, da `TeachingModeViewModel` selbst (wie
|
`TeachingModeHomeworkViewModel : ObservableObject`, da `TeachingModeViewModel` selbst (wie
|
||||||
`LessonViewerViewModel`) keine Bindable-Basisklasse hat.
|
`LessonViewerViewModel`) keine Bindable-Basisklasse hat.
|
||||||
|
|
||||||
|
**Nachtrag (September 2026, Nutzer-Feedback) — zweite Sitzung bei zusätzlicher Stunde am
|
||||||
|
selben Tag:** `SelectOrCreateSessionForLesson` prüfte bisher ausschließlich auf eine bereits
|
||||||
|
exakt mit `lesson.Id` verknüpfte Sitzung. Kam neben einer Doppelstunde noch eine dritte
|
||||||
|
Stunde desselben Tages hinzu (eigene `Lesson`-Id, z.B. durch Vertretung), fand die Methode
|
||||||
|
keinen Treffer und legte eine zweite, unabhängige Mitarbeitssitzung für denselben Tag an —
|
||||||
|
dadurch zeigten Unterrichtsmodus und der normale Mitarbeit-Tab der Gruppe (der über
|
||||||
|
`ParticipationTabViewModel.LoadSessions()` unabhängig davon die nach Datum jüngste Sitzung
|
||||||
|
wählt) je nach Reihenfolge unterschiedliche Sitzungen für denselben Tag. Nutzer-Entscheidung:
|
||||||
|
strikt nach Datum statt nach Stunde gehen — eine zusätzliche Stunde am selben Tag (Vertretung
|
||||||
|
o.ä.) bekommt keine eigene Sitzung, sondern die Lehrkraft passt die Einschätzung der bereits
|
||||||
|
bestehenden Sitzung des Tages an. `SelectOrCreateSessionForLesson` fällt jetzt, wenn keine
|
||||||
|
exakt verknüpfte Sitzung existiert, zusätzlich auf jede andere Sitzung desselben Tages
|
||||||
|
zurück (Verhalten analog zu `EnsureTodaySession`, das schon immer pro Tag statt pro Stunde
|
||||||
|
arbeitet). Dieselbe Lücke bestand in `PlanningTabViewModel.CreateParticipationSession`
|
||||||
|
("Sitzung aus der Stunde erstellen", 3.3.1) — gleicher Fallback dort ergänzt.
|
||||||
- [x] **4.5.24** Popup-Menü im Wochenraster für Unterrichtsansicht/Sitzplan/Planung/Planungsviewer
|
- [x] **4.5.24** Popup-Menü im Wochenraster für Unterrichtsansicht/Sitzplan/Planung/Planungsviewer
|
||||||
(August 2026, Nutzer-Feedback, zweite Runde). Die erste Fassung hatte das Problem am
|
(August 2026, Nutzer-Feedback, zweite Runde). Die erste Fassung hatte das Problem am
|
||||||
falschen Ort gelöst — ein Dropdown in der "Heute"-**Tagesliste** (unten angedockt), obwohl
|
falschen Ort gelöst — ein Dropdown in der "Heute"-**Tagesliste** (unten angedockt), obwohl
|
||||||
|
|||||||
Reference in New Issue
Block a user