From 975d5e6894e5559b75047593f769ddc6179a212e Mon Sep 17 00:00:00 2001 From: TheXamlGuy Date: Sun, 12 May 2024 17:09:59 +0100 Subject: [PATCH] Ensure containers show up in the menu when they are created --- Bitvault.Avalonia/AddItemActionView.axaml | 6 +- .../AddItemCommandHeaderView.axaml.cs | 8 --- Bitvault.Avalonia/AddItemView.axaml | 18 ------ Bitvault.Avalonia/AddItemView.axaml.cs | 8 --- Bitvault.Avalonia/App.axaml.cs | 15 ++--- Bitvault.Avalonia/Bitvault.Avalonia.csproj | 7 +-- ...View.axaml => ItemCommandHeaderView.axaml} | 4 +- .../ItemCommandHeaderView.axaml.cs | 8 +++ Bitvault.Avalonia/ItemNavigationView.axaml | 15 +++-- Bitvault.Avalonia/ItemView.axaml | 8 ++- Bitvault/AddItemViewModel.cs | 40 -------------- Bitvault/Bitvault.csproj | 1 + Bitvault/Container.cs | 12 ++-- Bitvault/ContainerActivatedHandler.cs | 26 +++++++++ Bitvault/ContainerConfiguration.cs | 2 +- Bitvault/ContainerFactory.cs | 4 +- Bitvault/ContainerHeaderViewModel.cs | 4 +- Bitvault/ContainerNavigationViewModel.cs | 16 +++--- Bitvault/ContainerViewModel.cs | 8 +-- Bitvault/ContainerViewModelHandler.cs | 55 ++++++++++++++----- Bitvault/CreateContainerHandler.cs | 20 ++++--- Bitvault/CreateContainerViewModel.cs | 2 +- .../FilterContainerNavigationViewModel.cs | 10 ++-- .../{IContainer.cs => IContainerFactory.cs} | 2 +- ...Model.cs => ItemCommandHeaderViewModel.cs} | 4 +- Bitvault/ItemConfigurationHandler.cs | 1 - Bitvault/ItemHeaderViewModel.cs | 4 +- Bitvault/ItemNavigationViewModel.cs | 4 ++ Bitvault/ItemViewModel.cs | 53 ++++++++++++++---- Bitvault/MainViewModelHandler.cs | 8 +-- Bitvault/OpenContainerHandler.cs | 8 +-- Bitvault/OpenContainerViewModel.cs | 4 +- 32 files changed, 211 insertions(+), 174 deletions(-) delete mode 100644 Bitvault.Avalonia/AddItemCommandHeaderView.axaml.cs delete mode 100644 Bitvault.Avalonia/AddItemView.axaml delete mode 100644 Bitvault.Avalonia/AddItemView.axaml.cs rename Bitvault.Avalonia/{AddItemCommandHeaderView.axaml => ItemCommandHeaderView.axaml} (93%) create mode 100644 Bitvault.Avalonia/ItemCommandHeaderView.axaml.cs delete mode 100644 Bitvault/AddItemViewModel.cs create mode 100644 Bitvault/ContainerActivatedHandler.cs rename Bitvault/{IContainer.cs => IContainerFactory.cs} (69%) rename Bitvault/{AddItemCommandHeaderViewModel.cs => ItemCommandHeaderViewModel.cs} (76%) diff --git a/Bitvault.Avalonia/AddItemActionView.axaml b/Bitvault.Avalonia/AddItemActionView.axaml index 068ab98..7c75400 100644 --- a/Bitvault.Avalonia/AddItemActionView.axaml +++ b/Bitvault.Avalonia/AddItemActionView.axaml @@ -15,9 +15,13 @@ ToolTip.Tip="Add item"> + diff --git a/Bitvault.Avalonia/AddItemCommandHeaderView.axaml.cs b/Bitvault.Avalonia/AddItemCommandHeaderView.axaml.cs deleted file mode 100644 index 44252a0..0000000 --- a/Bitvault.Avalonia/AddItemCommandHeaderView.axaml.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Avalonia.Controls; - -namespace Bitvault.Avalonia; - -public partial class AddItemCommandHeaderView : UserControl -{ - public AddItemCommandHeaderView() => InitializeComponent(); -} diff --git a/Bitvault.Avalonia/AddItemView.axaml b/Bitvault.Avalonia/AddItemView.axaml deleted file mode 100644 index fc6849e..0000000 --- a/Bitvault.Avalonia/AddItemView.axaml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - diff --git a/Bitvault.Avalonia/AddItemView.axaml.cs b/Bitvault.Avalonia/AddItemView.axaml.cs deleted file mode 100644 index da8fba7..0000000 --- a/Bitvault.Avalonia/AddItemView.axaml.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Avalonia.Controls; - -namespace Bitvault.Avalonia; - -public partial class AddItemView : UserControl -{ - public AddItemView() => InitializeComponent(); -} diff --git a/Bitvault.Avalonia/App.axaml.cs b/Bitvault.Avalonia/App.axaml.cs index e917a00..7937b05 100644 --- a/Bitvault.Avalonia/App.axaml.cs +++ b/Bitvault.Avalonia/App.axaml.cs @@ -35,6 +35,8 @@ public partial class App : Application services.AddTemplate("MainWindow"); } + services.AddHandler(); + services.AddTransient (provider => Component.Create(provider, args => { args.AddServices(services => @@ -47,14 +49,14 @@ public partial class App : Application services.AddTransient(); services.AddTransient(); - services.AddTransient(); - services.TryAddSingleton, Container>(); - services.TryAddSingleton, Container>(); + services.AddTransient(); + services.TryAddSingleton, ValueStore>(); + services.TryAddSingleton, ValueStore>(); services.AddDbContextFactory((provider, args) => { - if (provider.GetRequiredService>() - is IContainer connection) + if (provider.GetRequiredService>() + is IValueStore connection) { args.UseSqlite($"{connection.Value}"); } @@ -80,8 +82,7 @@ public partial class App : Application services.AddTemplate(); services.AddTemplate("Item"); - services.AddTemplate("AddItem"); - services.AddTemplate("AddVaultContentCommandHeader"); + services.AddTemplate("ItemCommandHeader"); services.AddTemplate(); services.AddTemplate(); diff --git a/Bitvault.Avalonia/Bitvault.Avalonia.csproj b/Bitvault.Avalonia/Bitvault.Avalonia.csproj index fc42bd5..b04ec4f 100644 --- a/Bitvault.Avalonia/Bitvault.Avalonia.csproj +++ b/Bitvault.Avalonia/Bitvault.Avalonia.csproj @@ -43,11 +43,8 @@ AddItemActionView.axaml - - AddItemCommandHeaderView.axaml - - - AddItemView.axaml + + ItemCommandHeaderView.axaml ConfirmItemActionView.axaml diff --git a/Bitvault.Avalonia/AddItemCommandHeaderView.axaml b/Bitvault.Avalonia/ItemCommandHeaderView.axaml similarity index 93% rename from Bitvault.Avalonia/AddItemCommandHeaderView.axaml rename to Bitvault.Avalonia/ItemCommandHeaderView.axaml index 4c6f8ea..c97f1e6 100644 --- a/Bitvault.Avalonia/AddItemCommandHeaderView.axaml +++ b/Bitvault.Avalonia/ItemCommandHeaderView.axaml @@ -1,9 +1,9 @@ + x:DataType="vm:ItemCommandHeaderViewModel"> 40 diff --git a/Bitvault.Avalonia/ItemCommandHeaderView.axaml.cs b/Bitvault.Avalonia/ItemCommandHeaderView.axaml.cs new file mode 100644 index 0000000..9657d45 --- /dev/null +++ b/Bitvault.Avalonia/ItemCommandHeaderView.axaml.cs @@ -0,0 +1,8 @@ +using Avalonia.Controls; + +namespace Bitvault.Avalonia; + +public partial class ItemCommandHeaderView : UserControl +{ + public ItemCommandHeaderView() => InitializeComponent(); +} diff --git a/Bitvault.Avalonia/ItemNavigationView.axaml b/Bitvault.Avalonia/ItemNavigationView.axaml index d771851..4e3aa3d 100644 --- a/Bitvault.Avalonia/ItemNavigationView.axaml +++ b/Bitvault.Avalonia/ItemNavigationView.axaml @@ -3,15 +3,22 @@ xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:vm="using:Bitvault" - x:Name="Name" - x:CompileBindings="False" x:DataType="vm:ItemNavigationViewModel"> - + + + + + + + - + - Vault content placeholder + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:vm="using:Bitvault" + x:DataType="vm:ItemViewModel"> + + + diff --git a/Bitvault/AddItemViewModel.cs b/Bitvault/AddItemViewModel.cs deleted file mode 100644 index 2ad3847..0000000 --- a/Bitvault/AddItemViewModel.cs +++ /dev/null @@ -1,40 +0,0 @@ -using CommunityToolkit.Mvvm.ComponentModel; -using Toolkit.Foundation; - -namespace Bitvault; - -public partial class AddItemViewModel : - ObservableCollectionViewModel, - INotificationHandler> -{ - [ObservableProperty] - private string named; - - public AddItemViewModel(IServiceProvider provider, - IServiceFactory factory, - IMediator mediator, - IPublisher publisher, - ISubscriber subscriber, - IDisposer disposer, - IContentTemplate template, - NamedComponent named) : base(provider, factory, mediator, publisher, subscriber, disposer) - { - Template = template; - Named = $"{named}"; - - Add(); - } - - public IContentTemplate Template { get; set; } - - public async Task Handle(Confirm args, CancellationToken cancellationToken = default) - { - ItemConfiguration configuration = new(); - foreach (IItemViewModel item in this) - { - item.Invoke(configuration); - } - - await Mediator.Handle, bool>(Create.As(configuration), cancellationToken); - } -} diff --git a/Bitvault/Bitvault.csproj b/Bitvault/Bitvault.csproj index 6d31932..f380683 100644 --- a/Bitvault/Bitvault.csproj +++ b/Bitvault/Bitvault.csproj @@ -6,6 +6,7 @@ + diff --git a/Bitvault/Container.cs b/Bitvault/Container.cs index 18007bb..7ed1bad 100644 --- a/Bitvault/Container.cs +++ b/Bitvault/Container.cs @@ -2,25 +2,25 @@ namespace Bitvault; -public record SecureStorage(TValue? Value = default); +public record Container(TValue? Value = default); -public record Vault +public record Container { - public Vault(string name, string password) + public Container(string name, string password) { Name = name; Password = password; } - public Vault(string password) + public Container(string password) { Password = password; } - public static SecureStorage As(TValue value) => new(value); + public static Container As(TValue value) => new(value); - public static SecureStorage As() where TValue : new() => new(new TValue()); + public static Container As() where TValue : new() => new(new TValue()); [MaybeNull] diff --git a/Bitvault/ContainerActivatedHandler.cs b/Bitvault/ContainerActivatedHandler.cs new file mode 100644 index 0000000..aafb093 --- /dev/null +++ b/Bitvault/ContainerActivatedHandler.cs @@ -0,0 +1,26 @@ +using Microsoft.Extensions.DependencyInjection; +using Toolkit.Foundation; + +namespace Bitvault; + +public record ContainerActivatedHandler(IPublisher publisher) : + INotificationHandler> +{ + public async Task Handle(Activated args, CancellationToken cancellationToken = default) + { + if (args.Value is IComponentHost container) + { + if (container.Services.GetRequiredService() is ContainerConfiguration configuration) + { + if (container.Services.GetRequiredService() is IServiceFactory factory) + { + if (factory.Create(configuration.Name) is ContainerNavigationViewModel viewModel) + { + await publisher.Publish(new Create(viewModel), + nameof(MainViewModel), cancellationToken); + } + } + } + } + } +} \ No newline at end of file diff --git a/Bitvault/ContainerConfiguration.cs b/Bitvault/ContainerConfiguration.cs index 27db0ca..d45c5ac 100644 --- a/Bitvault/ContainerConfiguration.cs +++ b/Bitvault/ContainerConfiguration.cs @@ -7,4 +7,4 @@ public record ContainerConfiguration : ComponentConfiguration public string? Name { get; set; } public string? Key { get; set; } -} \ No newline at end of file +} diff --git a/Bitvault/ContainerFactory.cs b/Bitvault/ContainerFactory.cs index 2034992..fbac9bb 100644 --- a/Bitvault/ContainerFactory.cs +++ b/Bitvault/ContainerFactory.cs @@ -6,10 +6,10 @@ using Toolkit.Foundation; namespace Bitvault; -public class ContainerFactory(IContainer connection, +public class ContainerFactory(IValueStore connection, IHostEnvironment environment, IServiceProvider provider) : - IContainer + IContainerFactory { public async Task Create(string name, SecurityKey key) diff --git a/Bitvault/ContainerHeaderViewModel.cs b/Bitvault/ContainerHeaderViewModel.cs index b4df358..aff9c41 100644 --- a/Bitvault/ContainerHeaderViewModel.cs +++ b/Bitvault/ContainerHeaderViewModel.cs @@ -3,7 +3,7 @@ namespace Bitvault; public partial class ContainerHeaderViewModel : ObservableCollectionViewModel, - INotificationHandler>> + INotificationHandler>> { public ContainerHeaderViewModel(IServiceProvider provider, IServiceFactory factory, @@ -20,7 +20,7 @@ public partial class ContainerHeaderViewModel : ObservableCollectionViewModel> args, + public Task Handle(Container> args, CancellationToken cancellationToken = default) { if (args.Value is Filter filter) diff --git a/Bitvault/ContainerNavigationViewModel.cs b/Bitvault/ContainerNavigationViewModel.cs index fa895ce..6af880f 100644 --- a/Bitvault/ContainerNavigationViewModel.cs +++ b/Bitvault/ContainerNavigationViewModel.cs @@ -6,10 +6,10 @@ namespace Bitvault; public partial class ContainerNavigationViewModel : ObservableCollectionViewModel, IMainNavigationViewModel, - INotificationHandler>, - INotificationHandler>, - INotificationHandler>, - INotificationHandler> + INotificationHandler>, + INotificationHandler>, + INotificationHandler>, + INotificationHandler> { [ObservableProperty] private bool activated; @@ -41,7 +41,7 @@ public partial class ContainerNavigationViewModel : public IContentTemplate Template { get; set; } - public Task Handle(SecureStorage args, + public Task Handle(Container args, CancellationToken cancellationToken = default) { Add("All"); @@ -53,7 +53,7 @@ public partial class ContainerNavigationViewModel : return Task.CompletedTask; } - public Task Handle(SecureStorage args, + public Task Handle(Container args, CancellationToken cancellationToken = default) { Opened = true; @@ -62,11 +62,11 @@ public partial class ContainerNavigationViewModel : return Task.CompletedTask; } - public Task Handle(SecureStorage args, + public Task Handle(Container args, CancellationToken cancellationToken = default) => Task.FromResult(Activated = false); - public Task Handle(SecureStorage args, + public Task Handle(Container args, CancellationToken cancellationToken = default) => Task.FromResult(Activated = true); } \ No newline at end of file diff --git a/Bitvault/ContainerViewModel.cs b/Bitvault/ContainerViewModel.cs index e8118b2..2ffeff2 100644 --- a/Bitvault/ContainerViewModel.cs +++ b/Bitvault/ContainerViewModel.cs @@ -14,7 +14,7 @@ public partial class ContainerViewModel(IServiceProvider provider, IContentTemplate template, NamedComponent named, string? filter = null) : ObservableCollectionViewModel(provider, factory, mediator, publisher, subscriber, disposer), - INotificationHandler>> + INotificationHandler>> { [ObservableProperty] private string? filter = filter; @@ -26,17 +26,17 @@ public partial class ContainerViewModel(IServiceProvider provider, public override async Task Activated() { - await Publisher.Publish(Vault.As()); + await Publisher.Publish(Container.As()); await base.Activated(); } public override async Task Deactivated() { - await Publisher.Publish(Vault.As()); + await Publisher.Publish(Container.As()); await base.Deactivated(); } - public async Task Handle(SecureStorage> args, + public async Task Handle(Container> args, CancellationToken cancellationToken = default) { if (args.Value is Filter filter) diff --git a/Bitvault/ContainerViewModelHandler.cs b/Bitvault/ContainerViewModelHandler.cs index 8a7ca9a..657a027 100644 --- a/Bitvault/ContainerViewModelHandler.cs +++ b/Bitvault/ContainerViewModelHandler.cs @@ -1,34 +1,59 @@ using Bitvault.Data; +using LinqKit; using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; using Toolkit.Foundation; namespace Bitvault; public class ContainerViewModelHandler(IDbContextFactory dbContextFactory, - IServiceFactory factory, + IServiceProvider serviceProvider, IPublisher publisher) : INotificationHandler> { public async Task Handle(Enumerate args, CancellationToken cancellationToken = default) { - var items = await Task.Run(async () => + if (args.Options is ContainerViewModelConfiguration configuration) { - using ContainerDbContext context = dbContextFactory.CreateDbContext(); - return await context.Set().Select(x => new - { - x.Name, - x.State - }).Where(x => x.State != 3).ToListAsync(); + ExpressionStarter predicate = PredicateBuilder.New(true); - }, cancellationToken); - - foreach (var item in items) - { - if (factory.Create(item.Name, "Description " + 1) is ItemNavigationViewModel viewModel) + if (configuration.Filter == "All") { - await publisher.Publish(new Create(viewModel), - nameof(ContainerViewModel), cancellationToken); + predicate = predicate.And(x => x.State != 3); + } + + if (configuration.Filter == "Starred") + { + predicate = predicate.And(x => x.State != 3 && x.State == 2); + } + + if (configuration.Filter == "Archive") + { + predicate = predicate.And(x => x.State == 3); + } + + var items = await Task.Run(async () => + { + using ContainerDbContext context = dbContextFactory.CreateDbContext(); + return await context.Set().Where(predicate).Select(x => new + { + x.Id, + x.Name + }).ToListAsync(); + + }, cancellationToken); + + foreach (var item in items) + { + IServiceScope serviceScope = serviceProvider.CreateScope(); + IServiceFactory serviceFactory = serviceScope.ServiceProvider.GetRequiredService(); + + if (serviceFactory.Create(item.Id, item.Name, "Description " + 1) is ItemNavigationViewModel viewModel) + { + await publisher.Publish(new Create(viewModel), + nameof(ContainerViewModel), cancellationToken); + } } } } diff --git a/Bitvault/CreateContainerHandler.cs b/Bitvault/CreateContainerHandler.cs index 5326c11..fb4298b 100644 --- a/Bitvault/CreateContainerHandler.cs +++ b/Bitvault/CreateContainerHandler.cs @@ -5,26 +5,27 @@ using Toolkit.Foundation; namespace Bitvault; -public class CreateContainerHandler(IContainerComponentFactory componentFactory) : - IHandler, bool> +public class CreateContainerHandler(IContainerComponentFactory componentFactory, + IPublisher publisher) : + IHandler, bool> { - public async Task Handle(Create args, + public async Task Handle(Create args, CancellationToken cancellationToken) { - if (args.Value is Vault vault && vault.Name is { Length: > 0 } name && - vault.Password is { Length: > 0 } password) + if (args.Value is Container container && container.Name is { Length: > 0 } name && + container.Password is { Length: > 0 } password) { if (componentFactory.Create(name) is IComponentHost host) { ISecurityKeyFactory keyVaultFactory = host.Services.GetRequiredService(); - IContainer vaultKeyContainer = host.Services.GetRequiredService>(); - IContainer vaultStorage = host.Services.GetRequiredService(); + IValueStore secureKeyStore = host.Services.GetRequiredService>(); + IContainerFactory containerFactory = host.Services.GetRequiredService(); if (keyVaultFactory.Create(Encoding.UTF8.GetBytes(password)) is SecurityKey key) { - vaultKeyContainer.Set(key); + secureKeyStore.Set(key); - if (await vaultStorage.Create(name, key)) + if (await containerFactory.Create(name, key)) { IWritableConfiguration configuration = host.Services.GetRequiredService>(); @@ -32,6 +33,7 @@ public class CreateContainerHandler(IContainerComponentFactory componentFactory) configuration.Write(args => args.Key = $"{Convert.ToBase64String(key.Salt)}:{Convert.ToBase64String(key.EncryptedKey)}:{Convert.ToBase64String(key.DecryptedKey)}"); host.Start(); + await publisher.Publish(Activated.As(host), cancellationToken); return true; } } diff --git a/Bitvault/CreateContainerViewModel.cs b/Bitvault/CreateContainerViewModel.cs index e21fd45..51d19e5 100644 --- a/Bitvault/CreateContainerViewModel.cs +++ b/Bitvault/CreateContainerViewModel.cs @@ -22,5 +22,5 @@ public partial class CreateContainerViewModel(IServiceProvider provider, private string password; public async Task Confirm() => - await Mediator.Handle, bool>(Create.As(new Vault(Name, Password))); + await Mediator.Handle, bool>(Create.As(new Container(Name, Password))); } \ No newline at end of file diff --git a/Bitvault/FilterContainerNavigationViewModel.cs b/Bitvault/FilterContainerNavigationViewModel.cs index ca7ecbf..6652041 100644 --- a/Bitvault/FilterContainerNavigationViewModel.cs +++ b/Bitvault/FilterContainerNavigationViewModel.cs @@ -6,8 +6,8 @@ namespace Bitvault; public partial class FilterContainerNavigationViewModel : ObservableViewModel, IContainerNavigationViewModel, - INotificationHandler>, - INotificationHandler> + INotificationHandler>, + INotificationHandler> { [ObservableProperty] private bool activated; @@ -29,14 +29,14 @@ public partial class FilterContainerNavigationViewModel : ObservableViewModel, Filter = filter; } - public Task Handle(SecureStorage args, + public Task Handle(Container args, CancellationToken cancellationToken = default) => Task.FromResult(Activated = false); - public Task Handle(SecureStorage args, + public Task Handle(Container args, CancellationToken cancellationToken = default) => Task.FromResult(Activated = true); [RelayCommand] - public async Task Invoke() => await Publisher.Publish(Vault.As(new Filter(Filter))); + public async Task Invoke() => await Publisher.Publish(Container.As(new Filter(Filter))); } \ No newline at end of file diff --git a/Bitvault/IContainer.cs b/Bitvault/IContainerFactory.cs similarity index 69% rename from Bitvault/IContainer.cs rename to Bitvault/IContainerFactory.cs index 81f7c09..0c3bd3e 100644 --- a/Bitvault/IContainer.cs +++ b/Bitvault/IContainerFactory.cs @@ -1,6 +1,6 @@ namespace Bitvault; -public interface IContainer +public interface IContainerFactory { Task Create(string name, SecurityKey key); } \ No newline at end of file diff --git a/Bitvault/AddItemCommandHeaderViewModel.cs b/Bitvault/ItemCommandHeaderViewModel.cs similarity index 76% rename from Bitvault/AddItemCommandHeaderViewModel.cs rename to Bitvault/ItemCommandHeaderViewModel.cs index 662211b..bb2557b 100644 --- a/Bitvault/AddItemCommandHeaderViewModel.cs +++ b/Bitvault/ItemCommandHeaderViewModel.cs @@ -2,9 +2,9 @@ namespace Bitvault; -public partial class AddItemCommandHeaderViewModel : ObservableCollectionViewModel +public partial class ItemCommandHeaderViewModel : ObservableCollectionViewModel { - public AddItemCommandHeaderViewModel(IServiceProvider provider, + public ItemCommandHeaderViewModel(IServiceProvider provider, IServiceFactory factory, IMediator mediator, IPublisher publisher, diff --git a/Bitvault/ItemConfigurationHandler.cs b/Bitvault/ItemConfigurationHandler.cs index a5fa2eb..0502e21 100644 --- a/Bitvault/ItemConfigurationHandler.cs +++ b/Bitvault/ItemConfigurationHandler.cs @@ -17,7 +17,6 @@ public class ItemConfigurationHandler(IDbContextFactory dbCo await Task.Run(async () => { using ContainerDbContext context = dbContextFactory.CreateDbContext(); - await context.AddAsync(new Data.Item { Name = configuration.Name }, cancellationToken); await context.SaveChangesAsync(cancellationToken); }, cancellationToken); diff --git a/Bitvault/ItemHeaderViewModel.cs b/Bitvault/ItemHeaderViewModel.cs index 37e4747..11df9c5 100644 --- a/Bitvault/ItemHeaderViewModel.cs +++ b/Bitvault/ItemHeaderViewModel.cs @@ -7,9 +7,11 @@ public partial class ItemHeaderViewModel(IServiceProvider provider, IMediator mediator, IPublisher publisher, ISubscriber subscriber, - IDisposer disposer) : ObservableViewModel(provider, factory, mediator, publisher, subscriber, disposer), + IDisposer disposer, + string? value = null) : ObservableViewModel(provider, factory, mediator, publisher, subscriber, disposer, value), IItemViewModel { public void Invoke(ItemConfiguration args) => args.Name = Value; + } diff --git a/Bitvault/ItemNavigationViewModel.cs b/Bitvault/ItemNavigationViewModel.cs index 4a40816..f8e1897 100644 --- a/Bitvault/ItemNavigationViewModel.cs +++ b/Bitvault/ItemNavigationViewModel.cs @@ -11,6 +11,7 @@ public partial class ItemNavigationViewModel(IServiceProvider provider, IDisposer disposer, IContentTemplate template, NamedComponent named, + int id, string name, string description) : ObservableViewModel(provider, factory, mediator, publisher, subscriber, disposer) @@ -18,6 +19,9 @@ public partial class ItemNavigationViewModel(IServiceProvider provider, [ObservableProperty] private string? description = description; + [ObservableProperty] + private int id = id; + [ObservableProperty] private string? name = name; diff --git a/Bitvault/ItemViewModel.cs b/Bitvault/ItemViewModel.cs index c4933d8..8fa5f43 100644 --- a/Bitvault/ItemViewModel.cs +++ b/Bitvault/ItemViewModel.cs @@ -1,15 +1,46 @@ -using Toolkit.Foundation; +using CommunityToolkit.Mvvm.ComponentModel; +using Toolkit.Foundation; namespace Bitvault; -public class ItemViewModel(IServiceProvider provider, - IServiceFactory factory, - IMediator mediator, - IPublisher publisher, - ISubscriber subscriber, - IDisposer disposer, - IContentTemplate template) : - ObservableViewModel(provider, factory, mediator, publisher, subscriber, disposer) +public partial class ItemViewModel : + ObservableCollectionViewModel, + INotificationHandler> { - public IContentTemplate Template { get; set; } = template; -} \ No newline at end of file + [ObservableProperty] + private int? id; + + [ObservableProperty] + private string named; + + public ItemViewModel(IServiceProvider provider, + IServiceFactory factory, + IMediator mediator, + IPublisher publisher, + ISubscriber subscriber, + IDisposer disposer, + IContentTemplate template, + NamedComponent named, + int? id = null, + string? name = null) : base(provider, factory, mediator, publisher, subscriber, disposer) + { + Template = template; + Named = $"{named}"; + Id = id; + + Add(name ?? ""); + } + + public IContentTemplate Template { get; set; } + + public async Task Handle(Confirm args, CancellationToken cancellationToken = default) + { + ItemConfiguration configuration = new(); + foreach (IItemViewModel item in this) + { + item.Invoke(configuration); + } + + await Mediator.Handle, bool>(Create.As(configuration), cancellationToken); + } +} diff --git a/Bitvault/MainViewModelHandler.cs b/Bitvault/MainViewModelHandler.cs index 364020b..e3d871e 100644 --- a/Bitvault/MainViewModelHandler.cs +++ b/Bitvault/MainViewModelHandler.cs @@ -4,17 +4,17 @@ using Toolkit.Foundation; namespace Bitvault; public class MainViewModelHandler(IPublisher publisher, - IContainerHostCollection vaults) : + IContainerHostCollection containers) : INotificationHandler> { public async Task Handle(Enumerate args, CancellationToken cancellationToken = default) { - foreach (IComponentHost vault in vaults) + foreach (IComponentHost container in containers) { - if (vault.Services.GetRequiredService() is ContainerConfiguration configuration) + if (container.Services.GetRequiredService() is ContainerConfiguration configuration) { - if (vault.Services.GetRequiredService() is IServiceFactory factory) + if (container.Services.GetRequiredService() is IServiceFactory factory) { if (factory.Create(configuration.Name) is ContainerNavigationViewModel viewModel) { diff --git a/Bitvault/OpenContainerHandler.cs b/Bitvault/OpenContainerHandler.cs index ab0709b..6af761e 100644 --- a/Bitvault/OpenContainerHandler.cs +++ b/Bitvault/OpenContainerHandler.cs @@ -5,13 +5,13 @@ namespace Bitvault; public class OpenContainerHandler(ContainerConfiguration configuration, ISecurityKeyFactory keyVaultFactory, - IContainer vaultStorage) : - IHandler, bool> + IContainerFactory vaultStorage) : + IHandler, bool> { - public async Task Handle(Open args, + public async Task Handle(Open args, CancellationToken cancellationToken) { - if (args.Value is Vault vault && configuration.Name is { Length: > 0 } name && vault.Password is { Length: > 0 } password) + if (args.Value is Container container && configuration.Name is { Length: > 0 } name && container.Password is { Length: > 0 } password) { if (configuration.Key?.Split(':') is { Length: >= 2 } keyPart) { diff --git a/Bitvault/OpenContainerViewModel.cs b/Bitvault/OpenContainerViewModel.cs index f64c1e2..a75e50b 100644 --- a/Bitvault/OpenContainerViewModel.cs +++ b/Bitvault/OpenContainerViewModel.cs @@ -20,9 +20,9 @@ public partial class OpenContainerViewModel(IServiceProvider provider, { if (Password is { Length: > 0 }) { - if (await Mediator.Handle, bool>(Open.As(new Vault(Password)))) + if (await Mediator.Handle, bool>(Open.As(new Container(Password)))) { - await Publisher.Publish(Vault.As()); + await Publisher.Publish(Container.As()); } } }