presence/Presence.Desktop/ViewModels/GroupViewModel.cs
2024-12-19 10:27:17 +03:00

263 lines
8.5 KiB
C#

using Avalonia.Controls.ApplicationLifetimes;
using domain.Models;
using domain.UseCase;
using Presence.Desktop.Views;
using ReactiveUI;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reactive;
using System.Reactive.Linq;
using System.Windows.Input;
using Avalonia;
namespace Presence.Desktop.ViewModels
{
public class GroupViewModel : ViewModelBase, IRoutableViewModel
{
public string? UrlPathSegment { get; }
public IScreen HostScreen { get; }
private readonly GroupUseCase _groupUseCase;
private List<GroupPresenter> groupPresentersDataSource = new List<GroupPresenter>();
private ObservableCollection<GroupPresenter> _groups;
public ObservableCollection<GroupPresenter> Groups => _groups;
private GroupPresenter? _selectedGroupItem;
public GroupPresenter? SelectedGroupItem
{
get => _selectedGroupItem;
set => this.RaiseAndSetIfChanged(ref _selectedGroupItem, value);
}
public ObservableCollection<UserPresenter> Users { get => _users; }
private ObservableCollection<UserPresenter> _users;
// Список опций сортировки
public List<string> SortOptions { get; } = new List<string> { "По фамилии", "По убыванию" };
private string _selectedSortOption;
public string SelectedSortOption
{
get => _selectedSortOption;
set => this.RaiseAndSetIfChanged(ref _selectedSortOption, value);
}
public bool CanDelete => SelectedUsers?.Count > 0;
public bool CanEdit => SelectedUsers?.Count == 1;
public ObservableCollection<UserPresenter> SelectedUsers { get; set; } = new ObservableCollection<UserPresenter>();
public ReactiveCommand<Unit, Unit> OnDeleteUserClicks { get; }
public ReactiveCommand<Unit, Unit> EditUserCommand { get; }
public ReactiveCommand<Unit, Unit> NextPageCommand { get; }
public ICommand RemoveAllStudentsCommand { get; }
public ICommand AddStudentCommand { get; }
public GroupViewModel(IScreen screen, GroupUseCase groupUseCase)
{
_groupUseCase = groupUseCase;
HostScreen = screen;
OnDeleteUserClicks = ReactiveCommand.Create(OnDeleteUserClick, this.WhenAnyValue(vm => vm.CanDelete));
EditUserCommand = ReactiveCommand.Create(OnEditUserClick, this.WhenAnyValue(vm => vm.CanEdit));
RefreshGroups();
_groups = new ObservableCollection<GroupPresenter>(groupPresentersDataSource);
_users = new ObservableCollection<UserPresenter>();
this.WhenAnyValue(vm => vm.SelectedGroupItem)
.Subscribe(vm => SetUsers());
this.WhenAnyValue(vm => vm.SelectedSortOption)
.Subscribe(_ => SortUsers());
RemoveAllStudentsCommand = ReactiveCommand.Create(RemoveAllStudents);
AddStudentCommand = ReactiveCommand.Create(AddStudent);
SelectedUsers.CollectionChanged += (s, e) =>
{
this.RaisePropertyChanged(nameof(CanDelete));
this.RaisePropertyChanged(nameof(CanEdit));
};
NextPageCommand = ReactiveCommand.Create(NextPageButton);
}
private void SetUsers()
{
if (SelectedGroupItem?.users == null) return;
Users.Clear();
foreach (var item in SelectedGroupItem.users)
{
Users.Add(item);
}
SortUsers();
}
private void SortUsers()
{
if (SelectedGroupItem?.users == null) return;
var sortedUsers = SelectedGroupItem.users.ToList();
switch (SelectedSortOption)
{
case "По фамилии":
sortedUsers = sortedUsers.OrderBy(u => u.Name).ToList();
break;
case "По убыванию":
sortedUsers = sortedUsers.OrderByDescending(u => u.Name).ToList();
break;
}
Users.Clear();
foreach (var item in sortedUsers)
{
Users.Add(item);
}
}
private void RemoveAllStudents()
{
if (SelectedGroupItem == null) return;
_groupUseCase.RemoveAllStudentsFromGroup(SelectedGroupItem.Id);
SelectedGroupItem.users = new List<UserPresenter>();
SetUsers();
}
private void NextPageButton()
{
HostScreen.Router.Navigate.Execute(new PresenceViewModel());
}
private void AddStudent()
{
if (SelectedGroupItem == null) return;
var newStudent = new UserPresenter
{
Name = "Новый студент",
Guid = Guid.NewGuid(),
Group = SelectedGroupItem
};
_groupUseCase.AddStudentToGroup(SelectedGroupItem.Id, new User
{
Guid = newStudent.Guid,
FIO = newStudent.Name
});
var updatedUsers = SelectedGroupItem.users?.ToList() ?? new List<UserPresenter>();
updatedUsers.Add(newStudent);
SelectedGroupItem.users = updatedUsers;
SetUsers();
}
public void OnDeleteUserClick()
{
if (SelectedUsers.Count == 0 || SelectedGroupItem?.users == null)
return;
foreach (var user in SelectedUsers.ToList())
{
_groupUseCase.RemoveUserByGuid(user.Guid);
var updatedUsers = SelectedGroupItem.users.Where(u => u.Guid != user.Guid).ToList();
SelectedGroupItem.users = new List<UserPresenter>(updatedUsers);
}
SetUsers();
SelectedUsers.Clear();
this.RaisePropertyChanged(nameof(CanDelete));
this.RaisePropertyChanged(nameof(CanEdit));
}
public async void OnEditUserClick()
{
var user = SelectedUsers.FirstOrDefault();
if (user == null) return;
var groups = _groupUseCase.GetAllGroups();
// Преобразуем группы из domain.Models.Group в GroupPresenter
var groupPresenters = groups.Select(g => new GroupPresenter
{
Id = g.Id,
Name = g.Name,
users = g.Users?.Select(u => new UserPresenter
{
Name = u.FIO,
Guid = u.Guid,
Group = new GroupPresenter { Id = g.Id, Name = g.Name }
}).ToList()
}).ToList();
var editDialog = new EditUserDialog(user.Guid, user.Name, user.Group.Id, groupPresenters);
var mainWindow = (Application.Current.ApplicationLifetime as IClassicDesktopStyleApplicationLifetime)?.MainWindow;
if (mainWindow == null) return;
var result = await editDialog.ShowDialog(mainWindow);
if (result != (null, null))
{
var newName = result.Item1;
var newGroup = result.Item2;
user.Name = newName;
user.Group = newGroup;
_groupUseCase.UpdateUser(user.Guid, user.Name, user.Group.Id);
SetUsers();
SelectedUsers.Clear();
this.RaisePropertyChanged(nameof(CanEdit));
this.RaisePropertyChanged(nameof(CanDelete));
}
RefreshGroups();
}
private void RefreshGroups()
{
groupPresentersDataSource.Clear();
foreach (var item in _groupUseCase.GetAllGroups())
{
GroupPresenter groupPresenter = new GroupPresenter
{
Id = item.Id,
Name = item.Name,
users = item.Users?.Select(user => new UserPresenter
{
Name = user.FIO,
Guid = user.Guid,
Group = new GroupPresenter { Id = item.Id, Name = item.Name }
}).ToList()
};
groupPresentersDataSource.Add(groupPresenter);
}
_groups = new ObservableCollection<GroupPresenter>(groupPresentersDataSource);
}
}
}