Edit Stammdaten Mitarbeitsessions
This commit is contained in:
@@ -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<ParticipationSession?>(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);
|
||||
}
|
||||
}
|
||||
@@ -48,6 +48,7 @@ public partial class ParticipationTabViewModel : ObservableObject
|
||||
public ObservableCollection<CompetencyTagGroup> CompetencyTagGroups { get; } = [];
|
||||
|
||||
public Func<Task<ParticipationSession?>>? OnAddSession { get; set; }
|
||||
public Func<ParticipationSession, Task<ParticipationSession?>>? OnEditSession { get; set; }
|
||||
public Func<ParticipationTabViewModel, Task>? OnQuickInput { get; set; }
|
||||
public Func<ParticipationTabViewModel, Task>? OnStatusQuickInput { get; set; }
|
||||
public Func<ParticipationTabViewModel, Task>? 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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">
|
||||
|
||||
<Grid RowDefinitions="*,Auto" Margin="24">
|
||||
<StackPanel Grid.Row="0" Spacing="14">
|
||||
<TextBlock Text="Neuer Bewertungszeitpunkt" Classes="dialogtitle"/>
|
||||
<TextBlock Text="{Binding DialogTitle}" Classes="dialogtitle"/>
|
||||
|
||||
<StackPanel Spacing="4">
|
||||
<TextBlock Text="Datum *" FontSize="12" Opacity="0.7"/>
|
||||
@@ -20,13 +20,14 @@
|
||||
|
||||
<StackPanel Spacing="4">
|
||||
<TextBlock Text="Kommentar (optional)" FontSize="12" Opacity="0.7"/>
|
||||
<TextBox Text="{Binding Comment}" PlaceholderText="z. B. Stunde 12 – Säure-Base-Reaktion"/>
|
||||
<TextBox Text="{Binding Comment}" PlaceholderText="z. B. Stunde 12 – Säure-Base-Reaktion"
|
||||
x:Name="CommentBox"/>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
|
||||
<Grid Grid.Row="1" ColumnDefinitions="*,8,*" Margin="0,20,0,0">
|
||||
<Button Grid.Column="0" Content="Abbrechen" HorizontalAlignment="Stretch" Click="OnCancel"/>
|
||||
<Button Grid.Column="2" Content="Anlegen" HorizontalAlignment="Stretch" Click="OnSave"/>
|
||||
<Button Grid.Column="2" Content="{Binding SaveButtonText}" HorizontalAlignment="Stretch" Click="OnSave"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Window>
|
||||
|
||||
@@ -11,8 +11,17 @@ public partial class AddSessionDialog : Window
|
||||
protected override void OnOpened(EventArgs e)
|
||||
{
|
||||
base.OnOpened(e);
|
||||
if (DataContext is AddSessionDialogViewModel { IsEditing: true })
|
||||
{
|
||||
var commentBox = this.FindControl<TextBox>("CommentBox");
|
||||
commentBox?.Focus();
|
||||
commentBox?.SelectAll();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.FindControl<TextBox>("DateBox")?.Focus();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSave(object? s, RoutedEventArgs e)
|
||||
{
|
||||
|
||||
@@ -53,13 +53,16 @@
|
||||
Text="{Binding SelectedSessionDisplay}"
|
||||
FontSize="13" FontWeight="SemiBold"
|
||||
VerticalAlignment="Center"/>
|
||||
<StackPanel Grid.Column="1" Orientation="Horizontal" Spacing="6"
|
||||
IsVisible="{Binding HasCompetencyCatalog}">
|
||||
<StackPanel Grid.Column="1" Orientation="Horizontal" Spacing="6">
|
||||
<Button Content="✎ Sitzung bearbeiten" Command="{Binding EditSessionCommand}"
|
||||
IsVisible="{Binding !IsReadOnly}" FontSize="11" Padding="8,3"/>
|
||||
<ToggleButton Content="◇ Kompetenzen"
|
||||
IsChecked="{Binding CompetencyTagsVisible}"
|
||||
IsVisible="{Binding HasCompetencyCatalog}"
|
||||
FontSize="11" Padding="8,3"/>
|
||||
<ToggleButton Content="◈ Schüler-Bewertungen"
|
||||
IsChecked="{Binding StudentCompetencyRatingsVisible}"
|
||||
IsVisible="{Binding HasCompetencyCatalog}"
|
||||
FontSize="11" Padding="8,3"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
|
||||
@@ -23,6 +23,7 @@ public partial class ParticipationTabView : UserControl
|
||||
{
|
||||
_vm = vm;
|
||||
vm.OnAddSession = ShowAddSessionDialog;
|
||||
vm.OnEditSession = ShowEditSessionDialog;
|
||||
vm.OnQuickInput = ShowQuickInputDialog;
|
||||
vm.OnStatusQuickInput = ShowStatusQuickInputDialog;
|
||||
vm.OnComputeGrade = ShowComputeGradeDialog;
|
||||
@@ -283,6 +284,17 @@ public partial class ParticipationTabView : UserControl
|
||||
return ok ? vm.Result : null;
|
||||
}
|
||||
|
||||
private async Task<LehrerApp.Core.Models.ParticipationSession?> ShowEditSessionDialog(
|
||||
LehrerApp.Core.Models.ParticipationSession session)
|
||||
{
|
||||
var vm = new AddSessionDialogViewModel(session);
|
||||
var dialog = new AddSessionDialog { DataContext = vm };
|
||||
var owner = TopLevel.GetTopLevel(this) as Window;
|
||||
if (owner is null) return null;
|
||||
var ok = await dialog.ShowDialog<bool>(owner);
|
||||
return ok ? vm.Result : null;
|
||||
}
|
||||
|
||||
private async Task ShowQuickInputDialog(ParticipationTabViewModel tabVm)
|
||||
{
|
||||
if (tabVm.StudentRows.Count == 0) return;
|
||||
|
||||
Reference in New Issue
Block a user