Dashboard-Performance, CI-Workflow, Settings-Aufteilung, Backup-Härtung
- Dashboard: Fehlzeiten-Warnung lädt Mitarbeitssitzungen einmal vorab statt pro Schüler/Eintrag einzeln nachzuschlagen (N+1 vermieden); neues IParticipationSessionRepository.GetAll() dafür. - CI: .gitea/workflows/ci.yml baut und testet bei jedem Push/PR. Dabei fehlende Release|Any CPU-Konfiguration für 6 Projekte in der .sln behoben (LehrerApp.Data.Tests wurde bei Release-Builds der Solution bislang stillschweigend übersprungen). TreatWarningsAsErrors jetzt aktiv. - SettingsViewModel (1986 Zeilen) als partial class auf 20 Themen- dateien aufgeteilt, Verhalten unverändert. - Backup: optionaler zweiter Sicherungsordner (USB-Stick/Netzlaufwerk, best-effort) und Integritätsprüfung nach jedem Backup (DatabaseEncryptionService.CanOpenAndRead). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using LehrerApp.Core.Interfaces;
|
||||
using LehrerApp.Core.Models;
|
||||
using LehrerApp.Core.Services;
|
||||
using LehrerApp.Data;
|
||||
using LehrerApp.Desktop.Services;
|
||||
using LehrerApp.Desktop.ViewModels.Planning;
|
||||
using LehrerApp.Sync;
|
||||
using LehrerApp.Sync.Crypto;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Globalization;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace LehrerApp.Desktop.ViewModels.Settings;
|
||||
|
||||
public partial class SettingsViewModel
|
||||
{
|
||||
// ── Fächer ────────────────────────────────────────────────────────────────
|
||||
|
||||
[ObservableProperty] private string _newName = "";
|
||||
[ObservableProperty] private string _newShort = "";
|
||||
[ObservableProperty] private string _newNameError = "";
|
||||
|
||||
public ObservableCollection<SubjectListItem> Subjects { get; } = [];
|
||||
|
||||
// ── Fächer: Laden / Hinzufügen / Löschen ─────────────────────────────────
|
||||
|
||||
public void LoadSubjects()
|
||||
{
|
||||
Subjects.Clear();
|
||||
foreach (var s in _subjects.GetAll())
|
||||
Subjects.Add(new SubjectListItem(s));
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void AddSubject()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(NewName)) { NewNameError = "Name erforderlich."; return; }
|
||||
try
|
||||
{
|
||||
_subjects.Save(new Subject { Name = NewName.Trim(), ShortName = NewShort.Trim() });
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
NewNameError = ex.Message;
|
||||
return;
|
||||
}
|
||||
NewName = ""; NewShort = ""; NewNameError = "";
|
||||
LoadSubjects();
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void DeleteSubject(SubjectListItem? item)
|
||||
{
|
||||
if (item is null) return;
|
||||
try
|
||||
{
|
||||
_subjects.Delete(item.Id);
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
NewNameError = ex.Message;
|
||||
return;
|
||||
}
|
||||
NewNameError = "";
|
||||
if (CatalogSubject?.Id == item.Id) CatalogSubject = null;
|
||||
LoadSubjects();
|
||||
}
|
||||
}
|
||||
|
||||
public class SubjectListItem(Subject s)
|
||||
{
|
||||
public Guid Id { get; } = s.Id;
|
||||
public string Name { get; } = s.Name;
|
||||
public string ShortName { get; } = s.ShortName;
|
||||
}
|
||||
Reference in New Issue
Block a user