Files
LehrerApp/LehrerApp.Desktop/ViewModels/Settings/TrashViewModel.cs
T
adminandClaude Sonnet 5 331033db5c feat: Dunkelmodus, Fenstergröße merken, Papierkorb für Löschvorgänge (12.4, 14.3, 14.6)
Dunkelmodus über neuen Einstellungen-Tab "Darstellung" (Systemvorgabe/Hell/Dunkel),
Fenstergröße/Maximiert-Status wird über Sitzungen hinweg gemerkt (bewusst ohne
Fensterposition), und ein generischer Snapshot-basierter Papierkorb (30 Tage) für
Sitzpläne, Noten, Notenschlüssel-Vorlagen, Aufgaben und Zeiteinträge. Details und
bewusste Scope-Entscheidungen (Spaltenbreiten zurückgestellt, Farb-Audit für
Dunkelmodus offen, welche Entitäten der Papierkorb abdeckt) in TODO.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-20 16:26:10 +02:00

101 lines
3.8 KiB
C#

using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using LehrerApp.Core.Interfaces;
using LehrerApp.Core.Models;
using System.Collections.ObjectModel;
namespace LehrerApp.Desktop.ViewModels.Settings;
/// <summary>
/// Papierkorb (14.3): zeigt gelöschte Datensätze der abgedeckten Modelle (siehe
/// TODO.md 14.3 für die vollständige Liste und die bewusst ausgeschlossenen, kaskadierenden
/// Löschvorgänge wie eine ganze Lerngruppe) und erlaubt das Wiederherstellen. Rein lokal — der
/// Papierkorb selbst wird nicht synchronisiert (siehe TrashRepository-Klassenkommentar);
/// wiederhergestellte Einträge synchronisieren sich danach ganz normal wie jede andere Änderung.
/// </summary>
public partial class TrashViewModel : ObservableObject
{
private readonly ITrashRepository _trash;
private readonly IGradeRepository _grades;
private readonly IWorkTaskRepository _tasks;
private readonly ITimeEntryRepository _timeEntries;
private readonly ISeatingPlanRepository _seatingPlans;
private readonly IGradingKeyTemplateRepository _gradingKeyTemplates;
[ObservableProperty] private string _status = "";
public ObservableCollection<TrashItemViewModel> Items { get; } = [];
public bool HasItems => Items.Count > 0;
public TrashViewModel(ITrashRepository trash, IGradeRepository grades, IWorkTaskRepository tasks,
ITimeEntryRepository timeEntries, ISeatingPlanRepository seatingPlans,
IGradingKeyTemplateRepository gradingKeyTemplates)
{
_trash = trash;
_grades = grades;
_tasks = tasks;
_timeEntries = timeEntries;
_seatingPlans = seatingPlans;
_gradingKeyTemplates = gradingKeyTemplates;
Load();
}
public void Load()
{
Items.Clear();
foreach (var item in _trash.GetAll())
Items.Add(new TrashItemViewModel(item, TypeLabel(item.EntityType)));
OnPropertyChanged(nameof(HasItems));
}
[RelayCommand]
private void Restore(TrashItemViewModel? item)
{
if (item is null) return;
switch (item.EntityType)
{
case nameof(Grade): _grades.Restore(item.Id); break;
case nameof(WorkTask): _tasks.Restore(item.Id); break;
case nameof(TimeEntry): _timeEntries.Restore(item.Id); break;
case nameof(SeatingPlan): _seatingPlans.Restore(item.Id); break;
case nameof(GradingKeyTemplate): _gradingKeyTemplates.Restore(item.Id); break;
default: return; // Unbekannter Typ (sollte nicht vorkommen) - Eintrag unverändert lassen.
}
Status = $"„{item.Summary}“ wiederhergestellt.";
Load();
}
private static string TypeLabel(string entityType) => entityType switch
{
nameof(Grade) => "Note",
nameof(WorkTask) => "Aufgabe",
nameof(TimeEntry) => "Zeiteintrag",
nameof(SeatingPlan) => "Sitzplan",
nameof(GradingKeyTemplate) => "Notenschlüssel-Vorlage",
_ => entityType,
};
}
public class TrashItemViewModel
{
private const int RetentionDays = 30;
public Guid Id { get; }
public string EntityType { get; }
public string TypeLabel { get; }
public string Summary { get; }
public string DeletedAtDisplay { get; }
public string ExpiresInDisplay { get; }
public TrashItemViewModel(TrashedItem item, string typeLabel)
{
Id = item.Id;
EntityType = item.EntityType;
TypeLabel = typeLabel;
Summary = item.Summary;
DeletedAtDisplay = item.DeletedAt.ToLocalTime().ToString("dd.MM.yyyy HH:mm");
var daysLeft = RetentionDays - (DateTime.UtcNow - item.DeletedAt).Days;
ExpiresInDisplay = daysLeft <= 0 ? "läuft heute ab" : $"noch {daysLeft} Tag(e)";
}
}