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:
@@ -97,7 +97,8 @@ public partial class WorkTaskListViewModel : ObservableObject
|
||||
public ObservableCollection<WorkTaskListItem> Tasks { get; } = [];
|
||||
public string CountSummary => $"{Tasks.Count} Aufgabe(n)";
|
||||
|
||||
public Func<WorkTask?, Task<WorkTask?>>? OnEditTask { get; set; }
|
||||
/// Zweiter Parameter = Dialog startet vorbelegt als Erinnerung (nur bei AddReminder true).
|
||||
public Func<WorkTask?, bool, Task<WorkTask?>>? OnEditTask { get; set; }
|
||||
|
||||
private Dictionary<Guid, string> _groupNames = [];
|
||||
|
||||
@@ -166,7 +167,20 @@ public partial class WorkTaskListViewModel : ObservableObject
|
||||
private async Task AddTask()
|
||||
{
|
||||
if (OnEditTask is null) return;
|
||||
var result = await OnEditTask(null);
|
||||
var result = await OnEditTask(null, false);
|
||||
if (result is null) return;
|
||||
_tasks.Save(result);
|
||||
Refresh();
|
||||
}
|
||||
|
||||
/// Eigener Einstieg statt eines Umschalters im selben Dialog-Aufruf wie AddTask (6.1.1
|
||||
/// Nutzer-Feedback): "Erinnerung" soll sich nicht wie eine Variante der Zeiterfassung anfühlen,
|
||||
/// sondern wie eine eigene, schnelle Aktion.
|
||||
[RelayCommand]
|
||||
private async Task AddReminder()
|
||||
{
|
||||
if (OnEditTask is null) return;
|
||||
var result = await OnEditTask(null, true);
|
||||
if (result is null) return;
|
||||
_tasks.Save(result);
|
||||
Refresh();
|
||||
@@ -176,7 +190,7 @@ public partial class WorkTaskListViewModel : ObservableObject
|
||||
private async Task EditTask(WorkTaskListItem? item)
|
||||
{
|
||||
if (item is null || OnEditTask is null) return;
|
||||
var result = await OnEditTask(item.Model);
|
||||
var result = await OnEditTask(item.Model, false);
|
||||
if (result is null) return;
|
||||
_tasks.Save(result);
|
||||
Refresh();
|
||||
@@ -203,6 +217,7 @@ public partial class WorkTaskListViewModel : ObservableObject
|
||||
? dueDate.AddDays(7) : dueDate.AddMonths(1),
|
||||
EstimatedMinutes = item.Model.EstimatedMinutes,
|
||||
Recurrence = item.Model.Recurrence,
|
||||
Kind = item.Model.Kind,
|
||||
Notes = item.Model.Notes,
|
||||
Status = WorkTaskStatus.Open,
|
||||
});
|
||||
@@ -224,7 +239,8 @@ public class WorkTaskListItem(WorkTask model, string? groupName, int actualMinut
|
||||
{
|
||||
public WorkTask Model { get; } = model;
|
||||
public string Title => Model.Title;
|
||||
public string CategoryLabel => TaskCategoryDisplay.Label(Model.Category);
|
||||
public bool IsReminder => Model.Kind == TaskKind.Reminder;
|
||||
public string CategoryLabel => IsReminder ? "Erinnerung" : TaskCategoryDisplay.Label(Model.Category);
|
||||
public string GroupName => groupName ?? "";
|
||||
public string DueDateDisplay => Model.DueDate?.ToString("dd.MM.yyyy", CultureInfo.InvariantCulture) ?? "";
|
||||
public bool IsOverdue => Model.DueDate is { } d && d < DateOnly.FromDateTime(DateTime.Today)
|
||||
@@ -258,21 +274,26 @@ public partial class AddEditWorkTaskDialogViewModel : ObservableObject
|
||||
[ObservableProperty] private string _estimatedMinutesText = "";
|
||||
[ObservableProperty] private string _selectedRecurrence = TaskRecurrenceDisplay.Options[0];
|
||||
[ObservableProperty] private string _notes = "";
|
||||
[ObservableProperty] private bool _isReminder;
|
||||
[ObservableProperty] private string _titleError = "";
|
||||
[ObservableProperty] private string _dueDateError = "";
|
||||
[ObservableProperty] private string _estimatedMinutesError = "";
|
||||
|
||||
public string DialogTitle => _source is null ? "Aufgabe anlegen" : "Aufgabe bearbeiten";
|
||||
public string DialogTitle => _source is null
|
||||
? (IsReminder ? "Erinnerung anlegen" : "Aufgabe anlegen")
|
||||
: (IsReminder ? "Erinnerung bearbeiten" : "Aufgabe bearbeiten");
|
||||
public List<string> CategoryOptions { get; } = [.. TaskCategoryDisplay.Options];
|
||||
public List<string> RecurrenceOptions { get; } = [.. TaskRecurrenceDisplay.Options];
|
||||
public List<LearningGroup> Groups { get; }
|
||||
public WorkTask? Result { get; private set; }
|
||||
|
||||
public AddEditWorkTaskDialogViewModel(WorkTask? source, List<LearningGroup> groups)
|
||||
partial void OnIsReminderChanged(bool value) => OnPropertyChanged(nameof(DialogTitle));
|
||||
|
||||
public AddEditWorkTaskDialogViewModel(WorkTask? source, List<LearningGroup> groups, bool startAsReminder = false)
|
||||
{
|
||||
_source = source;
|
||||
Groups = groups;
|
||||
if (source is null) return;
|
||||
if (source is null) { IsReminder = startAsReminder; return; }
|
||||
|
||||
Title = source.Title;
|
||||
SelectedCategory = TaskCategoryDisplay.Label(source.Category);
|
||||
@@ -281,6 +302,7 @@ public partial class AddEditWorkTaskDialogViewModel : ObservableObject
|
||||
EstimatedMinutesText = source.EstimatedMinutes?.ToString(CultureInfo.InvariantCulture) ?? "";
|
||||
SelectedRecurrence = TaskRecurrenceDisplay.Label(source.Recurrence);
|
||||
Notes = source.Notes ?? "";
|
||||
IsReminder = source.Kind == TaskKind.Reminder;
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
@@ -303,8 +325,9 @@ public partial class AddEditWorkTaskDialogViewModel : ObservableObject
|
||||
if (recurrence != TaskRecurrence.None && dueDate is null)
|
||||
{ DueDateError = "Fälligkeitsdatum erforderlich, damit die nächste Instanz geplant werden kann."; valid = false; }
|
||||
|
||||
// Erinnerungen haben bewusst keinen Zeitbezug — die Minutenschätzung entfällt.
|
||||
int? estimatedMinutes = null;
|
||||
if (!string.IsNullOrWhiteSpace(EstimatedMinutesText))
|
||||
if (!IsReminder && !string.IsNullOrWhiteSpace(EstimatedMinutesText))
|
||||
{
|
||||
if (!int.TryParse(EstimatedMinutesText, out var m) || m <= 0)
|
||||
{ EstimatedMinutesError = "Ganze Zahl > 0 erwartet."; valid = false; }
|
||||
@@ -322,6 +345,7 @@ public partial class AddEditWorkTaskDialogViewModel : ObservableObject
|
||||
DueDate = dueDate,
|
||||
EstimatedMinutes = estimatedMinutes,
|
||||
Recurrence = recurrence,
|
||||
Kind = IsReminder ? TaskKind.Reminder : TaskKind.WorkItem,
|
||||
Status = _source?.Status ?? WorkTaskStatus.Open,
|
||||
Notes = string.IsNullOrWhiteSpace(Notes) ? null : Notes.Trim(),
|
||||
CreatedAt = _source?.CreatedAt ?? DateTime.UtcNow,
|
||||
|
||||
Reference in New Issue
Block a user