Details Lerngruppe, Archiv, Stub Import
This commit is contained in:
@@ -16,13 +16,23 @@ public partial class GroupListViewModel : ObservableObject
|
||||
|
||||
public Action<Guid, int>? OnNavigateToDetail { get; set; }
|
||||
public Func<Task>? OnAddGroup { get; set; }
|
||||
public Func<Guid, Task>? OnEditGroup { get; set; }
|
||||
public Func<GroupListItem, Task<bool>>? OnConfirmDelete { get; set; }
|
||||
|
||||
[ObservableProperty] private string _selectedSchoolYear = "";
|
||||
[ObservableProperty] private string _searchText = "";
|
||||
[ObservableProperty] private GroupListItem? _selectedGroup;
|
||||
[ObservableProperty] private bool _showArchived;
|
||||
|
||||
public string SelectedGroupDisplayName => SelectedGroup?.DisplayName ?? "";
|
||||
public string SelectedGroupSubtitle => SelectedGroup?.Subtitle ?? "";
|
||||
public string ListSummary => ShowArchived
|
||||
? $"{Groups.Count} archivierte Gruppen · {SelectedSchoolYear}"
|
||||
: $"{Groups.Count} aktive Gruppen · {SelectedSchoolYear}";
|
||||
public bool HasNoGroups => Groups.Count == 0;
|
||||
public string EmptyListMessage => ShowArchived
|
||||
? "Keine archivierten Lerngruppen in diesem Schuljahr."
|
||||
: "Noch keine aktiven Lerngruppen in diesem Schuljahr.";
|
||||
|
||||
public ObservableCollection<string> SchoolYears { get; } = [];
|
||||
public ObservableCollection<GroupListItem> Groups { get; } = [];
|
||||
@@ -36,22 +46,32 @@ public partial class GroupListViewModel : ObservableObject
|
||||
|
||||
partial void OnSelectedSchoolYearChanged(string value) => LoadGroups();
|
||||
partial void OnSearchTextChanged(string value) => LoadGroups();
|
||||
partial void OnShowArchivedChanged(bool value) => LoadGroups();
|
||||
partial void OnSelectedGroupChanged(GroupListItem? value)
|
||||
{
|
||||
OnPropertyChanged(nameof(SelectedGroupDisplayName));
|
||||
OnPropertyChanged(nameof(SelectedGroupSubtitle));
|
||||
NavigateToSectionCommand.NotifyCanExecuteChanged();
|
||||
EditGroupCommand.NotifyCanExecuteChanged();
|
||||
ToggleArchiveCommand.NotifyCanExecuteChanged();
|
||||
DeleteGroupCommand.NotifyCanExecuteChanged();
|
||||
}
|
||||
|
||||
public void LoadGroups()
|
||||
{
|
||||
var selectedId = SelectedGroup?.Id;
|
||||
Groups.Clear();
|
||||
var all = _groups.GetBySchoolYear(SelectedSchoolYear);
|
||||
var all = _groups.GetBySchoolYear(SelectedSchoolYear, includeInactive: ShowArchived)
|
||||
.Where(g => g.IsActive != ShowArchived);
|
||||
var filtered = string.IsNullOrWhiteSpace(SearchText) ? all
|
||||
: all.Where(g => g.Name.Contains(SearchText, StringComparison.OrdinalIgnoreCase)
|
||||
|| (g.Subject?.Contains(SearchText, StringComparison.OrdinalIgnoreCase) ?? false));
|
||||
foreach (var g in filtered.OrderBy(g => g.Name))
|
||||
Groups.Add(new GroupListItem(g));
|
||||
SelectedGroup = Groups.FirstOrDefault(g => g.Id == selectedId);
|
||||
OnPropertyChanged(nameof(ListSummary));
|
||||
OnPropertyChanged(nameof(HasNoGroups));
|
||||
OnPropertyChanged(nameof(EmptyListMessage));
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
@@ -63,6 +83,37 @@ public partial class GroupListViewModel : ObservableObject
|
||||
}
|
||||
[RelayCommand] private void Refresh() => LoadGroups();
|
||||
|
||||
[RelayCommand(CanExecute = nameof(HasSelectedGroup))]
|
||||
private async Task EditGroup()
|
||||
{
|
||||
if (SelectedGroup is null || OnEditGroup is null) return;
|
||||
var id = SelectedGroup.Id;
|
||||
await OnEditGroup(id);
|
||||
LoadGroups();
|
||||
SelectedGroup = Groups.FirstOrDefault(g => g.Id == id);
|
||||
}
|
||||
|
||||
[RelayCommand(CanExecute = nameof(HasSelectedGroup))]
|
||||
private void ToggleArchive()
|
||||
{
|
||||
if (SelectedGroup is null) return;
|
||||
var group = _groups.GetById(SelectedGroup.Id);
|
||||
if (group is null) return;
|
||||
group.IsActive = !group.IsActive;
|
||||
_groups.Save(group);
|
||||
LoadGroups();
|
||||
}
|
||||
|
||||
[RelayCommand(CanExecute = nameof(HasSelectedGroup))]
|
||||
private async Task DeleteGroup()
|
||||
{
|
||||
if (SelectedGroup is null || OnConfirmDelete is null) return;
|
||||
var selected = SelectedGroup;
|
||||
if (!await OnConfirmDelete(selected)) return;
|
||||
_groups.Delete(selected.Id);
|
||||
LoadGroups();
|
||||
}
|
||||
|
||||
[RelayCommand(CanExecute = nameof(HasSelectedGroup))]
|
||||
private void NavigateToSection(string? tabIndex)
|
||||
{
|
||||
@@ -82,10 +133,13 @@ public class GroupListItem
|
||||
public string TypeLabel { get; }
|
||||
public string GradingLabel { get; }
|
||||
public string Subtitle { get; }
|
||||
public bool IsActive { get; }
|
||||
public string ArchiveActionLabel => IsActive ? "Archivieren" : "Wieder aktivieren";
|
||||
|
||||
public GroupListItem(LearningGroup g)
|
||||
{
|
||||
Id = g.Id;
|
||||
IsActive = g.IsActive;
|
||||
Name = g.Name;
|
||||
Subject = g.Subject ?? "";
|
||||
TypeLabel = g.Type == GroupType.Class ? "Klasse" : "Kurs";
|
||||
@@ -340,7 +394,10 @@ public partial class AddGroupDialogViewModel : ObservableObject
|
||||
private readonly IGroupRepository _groups;
|
||||
private readonly ISubjectRepository _subjects;
|
||||
private readonly SchoolYearService _sy;
|
||||
private readonly IEnrollmentRepository _enrollments;
|
||||
private List<Subject> _allSubjects = [];
|
||||
private LearningGroup? _editingGroup;
|
||||
private string? _originalSchoolYear;
|
||||
|
||||
public List<string> TypeOptions { get; } = ["Klasse", "Kurs"];
|
||||
[ObservableProperty] private string _selectedTypeName = "Kurs";
|
||||
@@ -359,17 +416,22 @@ public partial class AddGroupDialogViewModel : ObservableObject
|
||||
[ObservableProperty] private string _name = "";
|
||||
[ObservableProperty] private string _subject = "";
|
||||
[ObservableProperty] private int _gradeLevel = 10;
|
||||
[ObservableProperty] private GradingSystem _gradingSystem = GradingSystem.Grades1To6;
|
||||
[ObservableProperty] private string _selectedGradingName = "Noten 1–6";
|
||||
[ObservableProperty] private string _selectedSchoolYear = "";
|
||||
[ObservableProperty] private int? _hoursPerWeek;
|
||||
[ObservableProperty] private string _validationMessage = "";
|
||||
|
||||
public List<string> SchoolYears { get; }
|
||||
public List<string> GradingOptions { get; } = ["Noten 1–6", "Punkte 0–15"];
|
||||
public List<string> KnownSubjectNames { get; private set; } = [];
|
||||
public LearningGroup? Result { get; private set; }
|
||||
public string DialogTitle => _editingGroup is null ? "Neue Lerngruppe anlegen" : "Lerngruppe bearbeiten";
|
||||
public string SaveButtonText => _editingGroup is null ? "Anlegen" : "Speichern";
|
||||
|
||||
public AddGroupDialogViewModel(IGroupRepository groups, ISubjectRepository subjects, SchoolYearService sy)
|
||||
public AddGroupDialogViewModel(IGroupRepository groups, ISubjectRepository subjects,
|
||||
SchoolYearService sy, IEnrollmentRepository enrollments)
|
||||
{
|
||||
_groups = groups; _subjects = subjects; _sy = sy;
|
||||
_groups = groups; _subjects = subjects; _sy = sy; _enrollments = enrollments;
|
||||
_allSubjects = subjects.GetAll();
|
||||
KnownSubjectNames = _allSubjects.Select(s => s.Name).ToList();
|
||||
SchoolYears = sy.RecentSchoolYears(3);
|
||||
@@ -377,11 +439,26 @@ public partial class AddGroupDialogViewModel : ObservableObject
|
||||
PropertyChanged += (_, e) =>
|
||||
{
|
||||
if (e.PropertyName == nameof(GradeLevel))
|
||||
GradingSystem = GradeLevel >= 11 ? GradingSystem.Points0To15
|
||||
: GradingSystem.Grades1To6;
|
||||
SelectedGradingName = GradeLevel >= 11 ? "Punkte 0–15" : "Noten 1–6";
|
||||
};
|
||||
}
|
||||
|
||||
public void LoadForEdit(LearningGroup group)
|
||||
{
|
||||
_editingGroup = group;
|
||||
_originalSchoolYear = group.SchoolYear;
|
||||
SelectedTypeName = group.Type == GroupType.Class ? "Klasse" : "Kurs";
|
||||
Name = group.Name;
|
||||
Subject = group.Subject ?? "";
|
||||
GradeLevel = group.GradeLevel;
|
||||
SelectedGradingName = group.GradingSystem == GradingSystem.Grades1To6
|
||||
? "Noten 1–6" : "Punkte 0–15";
|
||||
SelectedSchoolYear = group.SchoolYear;
|
||||
HoursPerWeek = group.HoursPerWeek;
|
||||
OnPropertyChanged(nameof(DialogTitle));
|
||||
OnPropertyChanged(nameof(SaveButtonText));
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void Save()
|
||||
{
|
||||
@@ -407,16 +484,25 @@ public partial class AddGroupDialogViewModel : ObservableObject
|
||||
}
|
||||
}
|
||||
|
||||
Result = new LearningGroup
|
||||
{
|
||||
Name = Name.Trim(),
|
||||
Subject = subjectName,
|
||||
SubjectId = subjectId,
|
||||
Type = IsKurs ? GroupType.Course : GroupType.Class,
|
||||
GradeLevel = GradeLevel,
|
||||
GradingSystem = GradingSystem,
|
||||
SchoolYear = SelectedSchoolYear,
|
||||
};
|
||||
Result = _editingGroup ?? new LearningGroup();
|
||||
Result.Name = Name.Trim();
|
||||
Result.Subject = subjectName;
|
||||
Result.SubjectId = subjectId;
|
||||
Result.Type = IsKurs ? GroupType.Course : GroupType.Class;
|
||||
Result.GradeLevel = GradeLevel;
|
||||
Result.GradingSystem = SelectedGradingName == "Punkte 0–15"
|
||||
? GradingSystem.Points0To15 : GradingSystem.Grades1To6;
|
||||
Result.SchoolYear = SelectedSchoolYear;
|
||||
Result.HoursPerWeek = HoursPerWeek;
|
||||
_groups.Save(Result);
|
||||
|
||||
if (_editingGroup is not null && _originalSchoolYear != SelectedSchoolYear)
|
||||
{
|
||||
foreach (var enrollment in _enrollments.GetByGroup(Result.Id))
|
||||
{
|
||||
enrollment.SchoolYear = SelectedSchoolYear;
|
||||
_enrollments.Save(enrollment);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ public partial class MainWindowViewModel : ObservableObject
|
||||
ActiveNavItem = item;
|
||||
CurrentPage = item switch
|
||||
{
|
||||
NavItem.Dashboard => _services.GetRequiredService<DashboardViewModel>(),
|
||||
NavItem.Dashboard => GetDashboard(),
|
||||
NavItem.Groups => _services.GetRequiredService<GroupListViewModel>(),
|
||||
NavItem.Students => _services.GetRequiredService<StudentListViewModel>(),
|
||||
NavItem.Exams => new PlaceholderViewModel { Title = "Klausuren", Icon = "📝" },
|
||||
@@ -45,6 +45,13 @@ public partial class MainWindowViewModel : ObservableObject
|
||||
};
|
||||
}
|
||||
|
||||
private DashboardViewModel GetDashboard()
|
||||
{
|
||||
var dashboard = _services.GetRequiredService<DashboardViewModel>();
|
||||
dashboard.RefreshCommand.Execute(null);
|
||||
return dashboard;
|
||||
}
|
||||
|
||||
public void NavigateToGroupDetail(Guid groupId, int initialTab = 0)
|
||||
{
|
||||
ActiveNavItem = NavItem.Groups;
|
||||
|
||||
Reference in New Issue
Block a user