145 lines
5.6 KiB
C#
145 lines
5.6 KiB
C#
using CommunityToolkit.Mvvm.ComponentModel;
|
|
using CommunityToolkit.Mvvm.Input;
|
|
using LehrerApp.Core.Interfaces;
|
|
using LehrerApp.Core.Models;
|
|
using LehrerApp.Desktop.ViewModels.Students;
|
|
using System.Collections.ObjectModel;
|
|
|
|
namespace LehrerApp.Desktop.ViewModels.Groups;
|
|
|
|
/// <summary>
|
|
/// Gruppen-Tab "Dokumentation" (bisher Platzhalter): zeigt die Dokumentationseinträge aller
|
|
/// aktuellen/ehemaligen Schüler dieser Gruppe an einem Ort, statt sie einzeln im Schüler-Tab
|
|
/// aufsuchen zu müssen. Nutzer-Feedback: die Liste soll standardmäßig auch Einträge aus anderen
|
|
/// Lerngruppen desselben Schülers mit anzeigen (optisch abgesetzt statt ausgeblendet), damit
|
|
/// Muster aus anderen Fächern/Kursen nicht verborgen bleiben — ein Schalter blendet sie bei
|
|
/// Bedarf ganz aus.
|
|
/// </summary>
|
|
public partial class GroupDocumentationTabViewModel : ObservableObject
|
|
{
|
|
private readonly IDocumentationRepository _docs;
|
|
private readonly IStudentRepository _students;
|
|
private readonly IGroupRepository _groups;
|
|
|
|
private Guid _groupId;
|
|
private List<StudentOption> _groupStudents = [];
|
|
|
|
public static readonly StudentOption AllStudentsOption = new(Guid.Empty, "Alle Schüler");
|
|
public static readonly StudentOption WholeGroupOption = new(Guid.Empty, "Gesamte Lerngruppe");
|
|
|
|
public ObservableCollection<DocumentationItem> Entries { get; } = [];
|
|
public ObservableCollection<StudentOption> StudentFilterOptions { get; } = [AllStudentsOption];
|
|
|
|
[ObservableProperty] private StudentOption _selectedStudentFilter = AllStudentsOption;
|
|
[ObservableProperty] private bool _onlyThisGroup;
|
|
[ObservableProperty] private int _draftCount;
|
|
|
|
public Func<Guid, List<StudentOption>, Documentation?, Task<Documentation?>>? OnEditDocumentation { get; set; }
|
|
public Func<DocumentationItem, Task<bool>>? OnConfirmDeleteDocumentation { get; set; }
|
|
public Func<Documentation, string, Task<Documentation?>>? OnConductParentCall { get; set; }
|
|
|
|
public GroupDocumentationTabViewModel(IDocumentationRepository docs, IStudentRepository students,
|
|
IGroupRepository groups)
|
|
{
|
|
_docs = docs; _students = students; _groups = groups;
|
|
}
|
|
|
|
partial void OnSelectedStudentFilterChanged(StudentOption value) => Load();
|
|
partial void OnOnlyThisGroupChanged(bool value) => Load();
|
|
|
|
public void Initialize(Guid groupId)
|
|
{
|
|
_groupId = groupId;
|
|
_groupStudents = _students.GetByGroup(groupId)
|
|
.Select(s => new StudentOption(s.Id, s.FullName)).ToList();
|
|
|
|
StudentFilterOptions.Clear();
|
|
StudentFilterOptions.Add(AllStudentsOption);
|
|
foreach (var s in _groupStudents) StudentFilterOptions.Add(s);
|
|
SelectedStudentFilter = AllStudentsOption;
|
|
Load();
|
|
}
|
|
|
|
private void Load()
|
|
{
|
|
Entries.Clear();
|
|
var studentNameById = _groupStudents.ToDictionary(s => s.Id, s => s.Name);
|
|
var groupNameCache = new Dictionary<Guid, string>();
|
|
string GroupLabel(Guid id)
|
|
{
|
|
if (groupNameCache.TryGetValue(id, out var cached)) return cached;
|
|
var label = _groups.GetById(id)?.Name ?? "";
|
|
groupNameCache[id] = label;
|
|
return label;
|
|
}
|
|
|
|
var relevantStudentIds = SelectedStudentFilter.Id == Guid.Empty
|
|
? _groupStudents.Select(s => s.Id)
|
|
: [SelectedStudentFilter.Id];
|
|
|
|
var all = relevantStudentIds
|
|
.SelectMany(id => _docs.GetByStudent(id))
|
|
.Concat(SelectedStudentFilter.Id == Guid.Empty
|
|
? _docs.GetAll().Where(d => d.StudentId == Guid.Empty && d.GroupId == _groupId)
|
|
: [])
|
|
.DistinctBy(d => d.Id)
|
|
.Where(d => !OnlyThisGroup || d.GroupId == _groupId)
|
|
.OrderByDescending(d => d.IsDraft)
|
|
.ThenByDescending(d => d.Date)
|
|
.ToList();
|
|
DraftCount = all.Count(d => d.IsDraft && (d.GroupId is null || d.GroupId == _groupId));
|
|
|
|
foreach (var d in all)
|
|
{
|
|
var isOwnGroup = d.GroupId is null || d.GroupId == _groupId;
|
|
var otherGroupLabel = isOwnGroup ? "" : GroupLabel(d.GroupId!.Value);
|
|
var studentName = d.StudentId == Guid.Empty
|
|
? WholeGroupOption.Name
|
|
: studentNameById.GetValueOrDefault(d.StudentId, "");
|
|
Entries.Add(new DocumentationItem(d, studentName,
|
|
isOwnGroup, otherGroupLabel));
|
|
}
|
|
}
|
|
|
|
public void Refresh() => Load();
|
|
|
|
[RelayCommand]
|
|
private async Task AddDocumentation()
|
|
{
|
|
if (OnEditDocumentation is null) return;
|
|
var result = await OnEditDocumentation(_groupId, _groupStudents, null);
|
|
if (result is null) return;
|
|
_docs.Save(result);
|
|
Load();
|
|
}
|
|
|
|
[RelayCommand]
|
|
private async Task EditDocumentation(DocumentationItem? item)
|
|
{
|
|
if (item is null || OnEditDocumentation is null) return;
|
|
var result = await OnEditDocumentation(_groupId, _groupStudents, item.Model);
|
|
if (result is null) return;
|
|
_docs.Save(result);
|
|
Load();
|
|
}
|
|
|
|
[RelayCommand]
|
|
private async Task DeleteDocumentation(DocumentationItem? item)
|
|
{
|
|
if (item is null) return;
|
|
if (OnConfirmDeleteDocumentation is not null && !await OnConfirmDeleteDocumentation(item)) return;
|
|
_docs.Delete(item.Model.Id);
|
|
Load();
|
|
}
|
|
|
|
[RelayCommand]
|
|
private async Task ConductParentCall(DocumentationItem? item)
|
|
{
|
|
if (item is null || OnConductParentCall is null) return;
|
|
var result = await OnConductParentCall(item.Model, item.StudentName);
|
|
if (result is null) return;
|
|
_docs.Save(result);
|
|
Load();
|
|
}
|
|
}
|