diff --git a/LehrerApp.Desktop.Tests/ParticipationSessionEditingTests.cs b/LehrerApp.Desktop.Tests/ParticipationSessionEditingTests.cs new file mode 100644 index 0000000..5950e7c --- /dev/null +++ b/LehrerApp.Desktop.Tests/ParticipationSessionEditingTests.cs @@ -0,0 +1,62 @@ +using LehrerApp.Core.Models; +using LehrerApp.Desktop.ViewModels.Groups; +using Xunit; + +namespace LehrerApp.Desktop.Tests; + +public sealed class ParticipationSessionEditingTests +{ + [Fact] + public void Bearbeitungsdialog_AendertBestehendeSessionOhneVerknuepfungenZuErsetzen() + { + var session = new ParticipationSession + { + GroupId = Guid.NewGuid(), + Date = new DateOnly(2026, 8, 19), + Comment = "Sitzplan", + LessonId = Guid.NewGuid(), + CompetencyCodes = ["K1"], + }; + var vm = new AddSessionDialogViewModel(session) + { + DateText = "20.08.2026", + Comment = "Elektrische Stromkreise", + }; + + vm.SaveCommand.Execute(null); + + Assert.Same(session, vm.Result); + Assert.Equal(new DateOnly(2026, 8, 20), session.Date); + Assert.Equal("Elektrische Stromkreise", session.Comment); + Assert.NotNull(session.LessonId); + Assert.Equal(["K1"], session.CompetencyCodes); + } + + [Fact] + public async Task BearbeitenBefehl_SpeichertSessionUndAktualisiertAnzeige() + { + var group = new LearningGroup { Name = "8a", SchoolYear = "2026/27" }; + var session = new ParticipationSession + { + GroupId = group.Id, + Date = new DateOnly(2026, 8, 19), + Comment = "Sitzplan", + }; + var sessions = new FakeSessions([session]); + var vm = new ParticipationTabViewModel( + sessions, new FakeEntries(), new FakeAspects(), new FakeStudents([]), + new FakeMemberships([]), new FakeGroups([group]), new FakeCompetencyDomains()); + vm.OnEditSession = existing => + { + existing.Comment = "Nachbesprechung Elektrizität"; + return Task.FromResult(existing); + }; + vm.Initialize(group.Id, group.SchoolYear); + + await vm.EditSessionCommand.ExecuteAsync(null); + + Assert.Equal(session.Id, vm.SelectedSession?.Id); + Assert.Equal("Nachbesprechung Elektrizität", sessions.GetById(session.Id)?.Comment); + Assert.Contains("Nachbesprechung Elektrizität", vm.SelectedSessionDisplay); + } +} diff --git a/LehrerApp.Desktop/ViewModels/Groups/ParticipationViewModels.cs b/LehrerApp.Desktop/ViewModels/Groups/ParticipationViewModels.cs index 0606b7f..ea6ef03 100644 --- a/LehrerApp.Desktop/ViewModels/Groups/ParticipationViewModels.cs +++ b/LehrerApp.Desktop/ViewModels/Groups/ParticipationViewModels.cs @@ -48,6 +48,7 @@ public partial class ParticipationTabViewModel : ObservableObject public ObservableCollection CompetencyTagGroups { get; } = []; public Func>? OnAddSession { get; set; } + public Func>? OnEditSession { get; set; } public Func? OnQuickInput { get; set; } public Func? OnStatusQuickInput { get; set; } public Func? OnComputeGrade { get; set; } @@ -118,6 +119,7 @@ public partial class ParticipationTabViewModel : ObservableObject partial void OnSelectedSessionChanged(ParticipationSessionItem? value) { OnPropertyChanged(nameof(SelectedSessionDisplay)); + EditSessionCommand.NotifyCanExecuteChanged(); if (value is null) { StudentRows.Clear(); @@ -265,6 +267,23 @@ public partial class ParticipationTabViewModel : ObservableObject SelectedSession = Sessions.FirstOrDefault(s => s.Id == session.Id); } + [RelayCommand(CanExecute = nameof(CanEditSession))] + private async Task EditSession() + { + if (SelectedSession is null || OnEditSession is null) return; + var session = _sessions.GetById(SelectedSession.Id); + if (session is null) return; + var edited = await OnEditSession(session); + if (edited is null) return; + edited.GroupId = _groupId; + _sessions.Save(edited); + LoadSessions(); + } + + private bool CanEditSession() => !IsReadOnly && SelectedSession is not null; + + partial void OnIsReadOnlyChanged(bool value) => EditSessionCommand.NotifyCanExecuteChanged(); + [RelayCommand(CanExecute = nameof(CanQuickInput))] private async Task QuickInput() { @@ -716,12 +735,26 @@ public class ParticipationSessionItem public partial class AddSessionDialogViewModel : ObservableObject { + private readonly ParticipationSession? _editingSession; + [ObservableProperty] private DateOnly _date = DateOnly.FromDateTime(DateTime.Today); [ObservableProperty] private string _comment = ""; [ObservableProperty] private string _dateText = DateOnly.FromDateTime(DateTime.Today).ToString("dd.MM.yyyy"); [ObservableProperty] private string _dateTextError = ""; public ParticipationSession? Result { get; private set; } + public bool IsEditing => _editingSession is not null; + public string DialogTitle => IsEditing ? "Bewertungszeitpunkt bearbeiten" : "Bewertungszeitpunkt anlegen"; + public string SaveButtonText => IsEditing ? "Speichern" : "Anlegen"; + + public AddSessionDialogViewModel(ParticipationSession? editingSession = null) + { + _editingSession = editingSession; + if (editingSession is null) return; + Date = editingSession.Date; + DateText = editingSession.Date.ToString("dd.MM.yyyy"); + Comment = editingSession.Comment ?? ""; + } [RelayCommand] private void Save() @@ -733,7 +766,10 @@ public partial class AddSessionDialogViewModel : ObservableObject return; } DateTextError = ""; - Result = new ParticipationSession { Date = date, Comment = Comment.Trim() }; + var session = _editingSession ?? new ParticipationSession(); + session.Date = date; + session.Comment = Comment.Trim(); + Result = session; } } diff --git a/LehrerApp.Desktop/Views/Groups/AddSessionDialog.axaml b/LehrerApp.Desktop/Views/Groups/AddSessionDialog.axaml index 9475110..5089d98 100644 --- a/LehrerApp.Desktop/Views/Groups/AddSessionDialog.axaml +++ b/LehrerApp.Desktop/Views/Groups/AddSessionDialog.axaml @@ -3,13 +3,13 @@ xmlns:vm="clr-namespace:LehrerApp.Desktop.ViewModels.Groups" x:Class="LehrerApp.Desktop.Views.Groups.AddSessionDialog" x:DataType="vm:AddSessionDialogViewModel" - Title="Bewertungszeitpunkt anlegen" + Title="{Binding DialogTitle}" Width="380" SizeToContent="Height" CanResize="False" WindowStartupLocation="CenterOwner"> - + @@ -20,13 +20,14 @@ - +