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
@@ -171,7 +171,7 @@ public sealed class WorkTaskListViewModelTests
{
var tasks = new FakeWorkTasks();
var vm = new WorkTaskListViewModel(tasks, new FakeGroups([]), new FakeTimeEntries());
vm.OnEditTask = _ => Task.FromResult<WorkTask?>(new WorkTask { Title = "Neu" });
vm.OnEditTask = (_, _) => Task.FromResult<WorkTask?>(new WorkTask { Title = "Neu" });
await vm.AddTaskCommand.ExecuteAsync(null);
@@ -179,6 +179,26 @@ public sealed class WorkTaskListViewModelTests
Assert.Equal("Neu", vm.Tasks[0].Title);
}
[Fact]
public async Task AddReminder_OeffnetDialogVorbelegtAlsErinnerungUndSpeichertErgebnis()
{
var tasks = new FakeWorkTasks();
var vm = new WorkTaskListViewModel(tasks, new FakeGroups([]), new FakeTimeEntries());
bool? passedStartAsReminder = null;
vm.OnEditTask = (_, startAsReminder) =>
{
passedStartAsReminder = startAsReminder;
return Task.FromResult<WorkTask?>(new WorkTask { Title = "Ansage machen", Kind = TaskKind.Reminder });
};
await vm.AddReminderCommand.ExecuteAsync(null);
Assert.True(passedStartAsReminder);
var item = Assert.Single(vm.Tasks);
Assert.True(item.IsReminder);
Assert.Equal("Erinnerung", item.CategoryLabel);
}
[Fact]
public void Tasks_SindNachFaelligkeitSortiertUnbefristeteAmEnde()
{
@@ -285,6 +305,38 @@ public sealed class AddEditWorkTaskDialogViewModelTests
Assert.NotNull(vm.Result);
Assert.Equal(TaskRecurrence.Monthly, vm.Result!.Recurrence);
}
[Fact]
public void Save_AlsErinnerung_SetztKindUndVerwirftGeschaetzteDauer()
{
var vm = new AddEditWorkTaskDialogViewModel(null, [])
{
Title = "Ansage an die Klasse machen",
IsReminder = true,
EstimatedMinutesText = "90", // sollte ignoriert werden
};
vm.SaveCommand.Execute(null);
Assert.NotNull(vm.Result);
Assert.Equal(TaskKind.Reminder, vm.Result!.Kind);
Assert.Null(vm.Result.EstimatedMinutes);
}
[Fact]
public void Konstruktor_StartAsReminder_SetztIsReminderVorbelegt()
{
var vm = new AddEditWorkTaskDialogViewModel(null, [], startAsReminder: true);
Assert.True(vm.IsReminder);
}
[Fact]
public void Konstruktor_BestehendeErinnerung_ErkenntKindWieder()
{
var source = new WorkTask { Title = "Alt", Kind = TaskKind.Reminder };
var vm = new AddEditWorkTaskDialogViewModel(source, []);
Assert.True(vm.IsReminder);
}
}
public sealed class TimeTrackingViewModelTests