diff --git a/Presence.Desktop/App.axaml b/Presence.Desktop/App.axaml index 3821948..92a16bc 100644 --- a/Presence.Desktop/App.axaml +++ b/Presence.Desktop/App.axaml @@ -1,14 +1,8 @@ - - - - - diff --git a/Presence.Desktop/App.axaml.cs b/Presence.Desktop/App.axaml.cs index 377dfdd..0f4bce1 100644 --- a/Presence.Desktop/App.axaml.cs +++ b/Presence.Desktop/App.axaml.cs @@ -20,13 +20,13 @@ namespace Presence.Desktop var serviceCollection = new ServiceCollection(); serviceCollection.AddCommonService(); var services = serviceCollection.BuildServiceProvider(); - var mainViewModel = services.GetRequiredService(); + var mainViewModel = services.GetRequiredService(); if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) { - desktop.MainWindow = new MainWindow + desktop.MainWindow = new MainWindow() { - DataContext = mainViewModel, + DataContext = new MainWindowViewModel(services), }; } diff --git a/Presence.Desktop/DI/ServiceColletionExtensions.cs b/Presence.Desktop/DI/ServiceColletionExtensions.cs index 614da26..5b02bdd 100644 --- a/Presence.Desktop/DI/ServiceColletionExtensions.cs +++ b/Presence.Desktop/DI/ServiceColletionExtensions.cs @@ -21,7 +21,7 @@ namespace Presence.Desktop.DI .AddSingleton() .AddTransient() .AddTransient() - .AddTransient(); + .AddTransient(); } } } \ No newline at end of file diff --git a/Presence.Desktop/Models/UserPresenter.cs b/Presence.Desktop/Models/UserPresenter.cs index 2574e42..787ad48 100644 --- a/Presence.Desktop/Models/UserPresenter.cs +++ b/Presence.Desktop/Models/UserPresenter.cs @@ -12,4 +12,4 @@ namespace Presence.Desktop.Models public string Name { get; set; } public GroupPresenter Group { get; set; } } -} \ No newline at end of file +} diff --git a/Presence.Desktop/Presence.Desktop.csproj b/Presence.Desktop/Presence.Desktop.csproj index 36f75c7..993989b 100644 --- a/Presence.Desktop/Presence.Desktop.csproj +++ b/Presence.Desktop/Presence.Desktop.csproj @@ -9,7 +9,6 @@ - @@ -27,8 +26,8 @@ - - - + + + diff --git a/Presence.Desktop/ViewLocator.cs b/Presence.Desktop/ViewLocator.cs index dc21db5..3c91c1b 100644 --- a/Presence.Desktop/ViewLocator.cs +++ b/Presence.Desktop/ViewLocator.cs @@ -2,31 +2,18 @@ using Avalonia.Controls; using Avalonia.Controls.Templates; using Presence.Desktop.ViewModels; using System; +using Presence.Desktop.Views; +using ReactiveUI; namespace Presence.Desktop { - public class ViewLocator : IDataTemplate + public class ViewLocator : IViewLocator { - - public Control? Build(object? param) + public IViewFor? ResolveView(T? viewModel, string? contract = null) => viewModel switch { - if (param is null) - return null; - - var name = param.GetType().FullName!.Replace("ViewModel", "View", StringComparison.Ordinal); - var type = Type.GetType(name); - - if (type != null) - { - return (Control)Activator.CreateInstance(type)!; - } - - return new TextBlock { Text = "Not Found: " + name }; - } - - public bool Match(object? data) - { - return data is ViewModelBase; - } + GroupViewModel groupViewModel => new GroupView{DataContext = groupViewModel}, + PresenceViewModel presenceViewModel => new PresenceView{DataContext = presenceViewModel}, + _ => throw new ArgumentOutOfRangeException(nameof(viewModel)) + }; } } \ No newline at end of file diff --git a/Presence.Desktop/ViewModels/GroupViewModel.cs b/Presence.Desktop/ViewModels/GroupViewModel.cs new file mode 100644 index 0000000..963e21e --- /dev/null +++ b/Presence.Desktop/ViewModels/GroupViewModel.cs @@ -0,0 +1,148 @@ +using Demo.Domain.UseCase; +using Presence.Desktop.Models; +using ReactiveUI; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Reactive; +using System.Reactive.Linq; +using Avalonia.Controls; +using System.IO; +using Demo.Domain.Models; + +namespace Presence.Desktop.ViewModels +{ + public class GroupViewModel : ViewModelBase, IRoutableViewModel + { + private readonly List _groupPresentersDataSource = new List(); + private ObservableCollection _groups; + public ObservableCollection Groups => _groups; + + public GroupPresenter? SelectedGroupItem { + get => _selectedGroupItem; + set => this.RaiseAndSetIfChanged(ref _selectedGroupItem, value); } + + private GroupPresenter? _selectedGroupItem; + + public ReactiveCommand DeleteUsersByGroupCommand { get; } + + public ReactiveCommand ImportStudentsCommand { get; } + + public ObservableCollection Users { get => _users;} + public ObservableCollection _users; + + public GroupViewModel(IGroupUseCase groupUseCase, IUserUseCase userUseCase) + { + foreach (var item in groupUseCase.GetAllGroupsWithUsers()) + { + 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(_groupPresentersDataSource); + + _users = new ObservableCollection(); + + DeleteUsersByGroupCommand = ReactiveCommand.Create(() => DeleteUsersByGroupID(userUseCase)); + + this.WhenAnyValue(vm => vm.SelectedGroupItem) + .Subscribe(_ => SetUsers()); + + ImportStudentsCommand = ReactiveCommand.CreateFromTask(async () => + { + var openFileDialog = new OpenFileDialog + { + Filters = new List + { + new FileDialogFilter { Name = "CSV Files", Extensions = { "csv" } } + }, + AllowMultiple = false + }; + + var result = await openFileDialog.ShowAsync(new Window()); + if (result?.Length > 0) { + var filePath = result[0]; + ImportStudents(filePath, userUseCase); + } + }); + } + + private void ImportStudents(string filePath, IUserUseCase userUseCase) + { + if (SelectedGroupItem == null || SelectedGroupItem.Id == null) + { + return; + } + var lines = File.ReadAllLines(filePath); + + foreach (var line in lines.Skip(1)) + { + var columns = line.Split(','); + if (columns.Length < 1) continue; + + var fio = columns[0]; + + var newUser = new User + { + FIO = fio, + Group = new Group + { + Name = SelectedGroupItem.Name, + ID = SelectedGroupItem.Id + } + }; + + var result = userUseCase.CreateUser(newUser); + + if (result) + { + var userPresenter = new UserPresenter + { + Name = fio, + Guid = Guid.NewGuid(), + Group = SelectedGroupItem + }; + _users.Add(userPresenter); + } + } + } + + private void DeleteUsersByGroupID(IUserUseCase userUseCase) { + + if (SelectedGroupItem == null) + return; + + var groupID = SelectedGroupItem.Id; + bool res = userUseCase.RemoveUsersByGroupID(groupID); + + if (res) { + Users.Clear(); + } + } + + private void SetUsers() + { + if(SelectedGroupItem == null) return; + if (SelectedGroupItem.users == null) return; + Users.Clear(); + foreach (var item in SelectedGroupItem.users) + { + Users.Add(item); + } + } + + public string? UrlPathSegment { get; } + public IScreen HostScreen { get; } + } +} \ No newline at end of file diff --git a/Presence.Desktop/ViewModels/MainWindowViewModel.cs b/Presence.Desktop/ViewModels/MainWindowViewModel.cs index e1e7d72..0bfed38 100644 --- a/Presence.Desktop/ViewModels/MainWindowViewModel.cs +++ b/Presence.Desktop/ViewModels/MainWindowViewModel.cs @@ -1,72 +1,16 @@ -using Demo.Domain.UseCase; -using DynamicData; -using DynamicData.Binding; -using Presence.Desktop.Models; +using System; +using Microsoft.Extensions.DependencyInjection; using ReactiveUI; -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; -using System.Reactive.Linq; -using Tmds.DBus.Protocol; -namespace Presence.Desktop.ViewModels +namespace Presence.Desktop.ViewModels; + +public class MainWindowViewModel: ViewModelBase, IScreen { - public class MainWindowViewModel : ViewModelBase + public RoutingState Router { get; } = new RoutingState(); + + public MainWindowViewModel(IServiceProvider serviceProvider) { - private readonly IGroupUseCase _groupService; - private List groupPresentersDataSource = new List(); - private ObservableCollection _groups; - public ObservableCollection Groups => _groups; - - public GroupPresenter? SelectedGroupItem { - get => _selectedGroupItem; - set => this.RaiseAndSetIfChanged(ref _selectedGroupItem, value); } - - private GroupPresenter? _selectedGroupItem; - - - - public ObservableCollection Users { get => _users;} - public ObservableCollection _users; - public MainWindowViewModel(IGroupUseCase groupUseCase) - { - _groupService = groupUseCase; - - foreach (var item in _groupService.GetAllGroupsWithUsers()) - { - 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(groupPresentersDataSource); - - _users = new ObservableCollection(); - - this.WhenAnyValue(vm => vm.SelectedGroupItem) - .Subscribe(_ => SetUsers()); - - } - - private void SetUsers() - { - if(SelectedGroupItem == null) return; - if (SelectedGroupItem.users == null) return; - Users.Clear(); - foreach (var item in SelectedGroupItem.users) - { - Users.Add(item); - } - } + var groupViewModel = serviceProvider.GetRequiredService(); + Router.Navigate.Execute(groupViewModel); } } \ No newline at end of file diff --git a/Presence.Desktop/ViewModels/PresenceViewModel.cs b/Presence.Desktop/ViewModels/PresenceViewModel.cs new file mode 100644 index 0000000..290ac6f --- /dev/null +++ b/Presence.Desktop/ViewModels/PresenceViewModel.cs @@ -0,0 +1,9 @@ +using ReactiveUI; + +namespace Presence.Desktop.ViewModels; + +public class PresenceViewModel: ViewModelBase, IRoutableViewModel +{ + public string? UrlPathSegment { get; } + public IScreen HostScreen { get; } +} \ No newline at end of file diff --git a/Presence.Desktop/Views/GroupView.axaml b/Presence.Desktop/Views/GroupView.axaml new file mode 100644 index 0000000..26c48b3 --- /dev/null +++ b/Presence.Desktop/Views/GroupView.axaml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + +