diff --git a/Bitvault.Avalonia/App.axaml.cs b/Bitvault.Avalonia/App.axaml.cs index 22133f2..3a14af1 100644 --- a/Bitvault.Avalonia/App.axaml.cs +++ b/Bitvault.Avalonia/App.axaml.cs @@ -129,6 +129,9 @@ public partial class App : Application services.AddTemplate(); services.AddTemplate("EmptyItemCollection"); + + services.AddScoped, DecoratorService>(); + services.AddTemplate("Item"); services.AddTemplate(); services.AddTemplate(); diff --git a/Bitvault/ConfirmCreateItemHandler.cs b/Bitvault/ConfirmCreateItemHandler.cs index 86559dc..5166072 100644 --- a/Bitvault/ConfirmCreateItemHandler.cs +++ b/Bitvault/ConfirmCreateItemHandler.cs @@ -3,28 +3,23 @@ namespace Bitvault; public class ConfirmCreateItemHandler(IMediator mediator, + IDecoratorService decoratorItemConfiguration, IPublisher publisher) : INotificationHandler> { public async Task Handle(ConfirmEventArgs args) { - string? name = await mediator.Handle, - string>(Confirm.As()); - - if (name is not null) + if (decoratorItemConfiguration.Value is ItemConfiguration configuration) { - IList<(int, string)> sections = await mediator.HandleMany, - (int, string)>(Confirm.As()); + string? name = await mediator.Handle, string>(Confirm.As()); + if (name is not null) + { + Guid id = Guid.NewGuid(); + publisher.Publish(Created.As(new Item<(Guid, string)>((id, name)))); - IList<(int, ItemEntryConfiguration)> entries = await mediator.HandleMany, - (int, ItemEntryConfiguration)>(Confirm.As()); - - Guid id = Guid.NewGuid(); - publisher.Publish(Created.As(new Item<(Guid, string)>((id, name)))); - - await mediator.Handle, bool>(new CreateEventArgs<(Guid, string, string, ItemConfiguration)>((id, name, "", - new ItemConfiguration()))); + await mediator.Handle, bool>(new CreateEventArgs<(Guid, string, string, ItemConfiguration)>((id, name, "", configuration))); + } } } } diff --git a/Bitvault/ConfirmItemActionViewModel.cs b/Bitvault/ConfirmItemActionViewModel.cs index 5cbdeb8..ffe6447 100644 --- a/Bitvault/ConfirmItemActionViewModel.cs +++ b/Bitvault/ConfirmItemActionViewModel.cs @@ -8,10 +8,8 @@ public partial class ConfirmItemActionViewModel(IServiceProvider provider, IMediator mediator, IPublisher publisher, ISubscription subscriber, - IDisposer disposer, - ItemState state) : Observable(provider, factory, mediator, publisher, subscriber, disposer) + IDisposer disposer) : Observable(provider, factory, mediator, publisher, subscriber, disposer) { [RelayCommand] - public void Invoke() => Publisher.Publish(Confirm.As(), - state is ItemState.New ? nameof(ItemState.New) : nameof(ItemState.Write)); + public void Invoke() => Publisher.Publish(Confirm.As()); } \ No newline at end of file diff --git a/Bitvault/ConfirmUpdateItemHandler.cs b/Bitvault/ConfirmUpdateItemHandler.cs index 3caa074..65e45b7 100644 --- a/Bitvault/ConfirmUpdateItemHandler.cs +++ b/Bitvault/ConfirmUpdateItemHandler.cs @@ -2,7 +2,8 @@ namespace Bitvault; -public class ConfirmUpdateItemHandler(IDecoratorService> store, +public class ConfirmUpdateItemHandler(IDecoratorService> decoratorItem, + IDecoratorService decoratorItemConfiguration, IMediator mediator, IPublisher publisher) : INotificationHandler> @@ -14,17 +15,16 @@ public class ConfirmUpdateItemHandler(IDecoratorService> st if (name is not null) { - - + var dd = decoratorItemConfiguration; publisher.Publish(Notify.As(new ItemHeader(name))); - if (store?.Value is Item<(Guid, string)> item) + if (decoratorItem?.Value is Item<(Guid, string)> item) { (Guid id, string _) = item.Value; Item<(Guid, string)> newItem = new((id, name)); publisher.Publish(Modified.As(item, newItem)); - store.Set(newItem); + decoratorItem.Set(newItem); await mediator.Handle, bool>(new UpdateEventArgs<(Guid, string, ItemConfiguration)>((id, name, new ItemConfiguration()))); diff --git a/Bitvault/ItemContentEntry.cs b/Bitvault/ItemContentEntry.cs deleted file mode 100644 index d9d4ecd..0000000 --- a/Bitvault/ItemContentEntry.cs +++ /dev/null @@ -1,5 +0,0 @@ -namespace Bitvault; - -public record ItemContentEntry(TValue Value); - -public record ItemContentEntry; diff --git a/Bitvault/ItemContentViewModel.cs b/Bitvault/ItemContentViewModel.cs index 8e4e8c2..61fe059 100644 --- a/Bitvault/ItemContentViewModel.cs +++ b/Bitvault/ItemContentViewModel.cs @@ -8,8 +8,7 @@ public partial class ItemContentViewModel(IServiceProvider provider, IPublisher publisher, ISubscription subscriber, IDisposer disposer, - IContentTemplate template, - ItemState state = ItemState.Read) : + IContentTemplate template) : ObservableCollection(provider, factory, mediator, publisher, subscriber, disposer), IItemEntryViewModel, INotificationHandler>> @@ -22,8 +21,7 @@ public partial class ItemContentViewModel(IServiceProvider provider, { if (category.Value is string value) { - Fetch(() => new SynchronizeExpression(new SynchronizeEventArgs)>((value, this))), true); + Fetch(() => new SynchronizeExpression(new SynchronizeEventArgs(value)), true); } } diff --git a/Bitvault/ItemDropdownEntryViewModel.cs b/Bitvault/ItemDropdownEntryViewModel.cs index b1a1bd4..795eca9 100644 --- a/Bitvault/ItemDropdownEntryViewModel.cs +++ b/Bitvault/ItemDropdownEntryViewModel.cs @@ -8,7 +8,6 @@ public partial class ItemDropdownEntryViewModel(IServiceProvider provider, IPublisher publisher, ISubscription subscriber, IDisposer disposer, - ISynchronizationCollection synchronization, ItemEntryConfiguration configuration, string? key = default, - string? value = default) : ItemEntryViewModel(provider, factory, mediator, publisher, subscriber, disposer, synchronization, configuration, key, value); \ No newline at end of file + object? value = default) : ItemEntryViewModel(provider, factory, mediator, publisher, subscriber, disposer, configuration, key, value); \ No newline at end of file diff --git a/Bitvault/ItemDropdownEntryViewModelHandler.cs b/Bitvault/ItemDropdownEntryViewModelHandler.cs index 34e31f2..012110a 100644 --- a/Bitvault/ItemDropdownEntryViewModelHandler.cs +++ b/Bitvault/ItemDropdownEntryViewModelHandler.cs @@ -10,7 +10,7 @@ public class ItemDropdownEntryViewModelHandler(IServiceFactory serviceFactory) : { if (args.Value is DropdownEntryConfiguration configuration) { - if (serviceFactory.Create([.. args.Parameters, configuration, configuration.Label, configuration.Value ?? ""]) + if (serviceFactory.Create(configuration, configuration.Label, configuration.Value ?? "") is ItemDropdownEntryViewModel viewModel) { return Task.FromResult(viewModel); diff --git a/Bitvault/ItemEntryViewModel.cs b/Bitvault/ItemEntryViewModel.cs index f8ad9cd..8450b25 100644 --- a/Bitvault/ItemEntryViewModel.cs +++ b/Bitvault/ItemEntryViewModel.cs @@ -1,24 +1,19 @@ -using Toolkit.Foundation; +using System.ComponentModel; +using Toolkit.Foundation; namespace Bitvault; -public partial class ItemEntryViewModel(IServiceProvider provider, +public partial class ItemEntryViewModel(IServiceProvider provider, IServiceFactory factory, IMediator mediator, IPublisher publisher, ISubscription subscriber, IDisposer disposer, - ISynchronizationCollection synchronization, ItemEntryConfiguration configuration, - TKey? key = default, - TValue? value = default) : - Observable(provider, factory, mediator, publisher, subscriber, disposer, key, value), - IHandler, (int, ItemEntryConfiguration)>, - IItemEntryViewModel, - IIndexable + string? key = default, + object? value = default) : + Observable(provider, factory, mediator, publisher, subscriber, disposer, key, value), + IItemEntryViewModel { - public int Index => synchronization.IndexOf(this); - - public Task<(int, ItemEntryConfiguration)> Handle(ConfirmEventArgs args, - CancellationToken cancellationToken) => Task.FromResult((Index, configuration with { Value = Value })); + protected override void OnValueChanged() => configuration.Value = Value; } diff --git a/Bitvault/ItemMaskedTextEntryViewModel.cs b/Bitvault/ItemMaskedTextEntryViewModel.cs index 76e1463..b472804 100644 --- a/Bitvault/ItemMaskedTextEntryViewModel.cs +++ b/Bitvault/ItemMaskedTextEntryViewModel.cs @@ -8,7 +8,6 @@ public partial class ItemMaskedTextEntryViewModel(IServiceProvider provider, IPublisher publisher, ISubscription subscriber, IDisposer disposer, - ISynchronizationCollection synchronization, ItemEntryConfiguration configuration, string? key = default, - string? value = default) : ItemEntryViewModel(provider, factory, mediator, publisher, subscriber, disposer, synchronization, configuration, key, value); \ No newline at end of file + object? value = default) : ItemEntryViewModel(provider, factory, mediator, publisher, subscriber, disposer, configuration, key, value); \ No newline at end of file diff --git a/Bitvault/ItemMaskedTextEntryViewModelHandler.cs b/Bitvault/ItemMaskedTextEntryViewModelHandler.cs index a85104e..29c7f0d 100644 --- a/Bitvault/ItemMaskedTextEntryViewModelHandler.cs +++ b/Bitvault/ItemMaskedTextEntryViewModelHandler.cs @@ -10,7 +10,7 @@ public class ItemMaskedTextEntryViewModelHandler(IServiceFactory serviceFactory) { if (args.Value is MaskedTextEntryConfiguration configuration) { - if (serviceFactory.Create([.. args.Parameters, configuration, configuration.Label, configuration.Value ?? ""]) + if (serviceFactory.Create(configuration, configuration.Label, configuration.Value ?? "") is ItemMaskedTextEntryViewModel viewModel) { return Task.FromResult(viewModel); diff --git a/Bitvault/ItemNavigationViewModel.cs b/Bitvault/ItemNavigationViewModel.cs index 2443fd6..fe73bec 100644 --- a/Bitvault/ItemNavigationViewModel.cs +++ b/Bitvault/ItemNavigationViewModel.cs @@ -24,6 +24,7 @@ public partial class ItemNavigationViewModel(IServiceProvider provider, INotificationHandler>, INotificationHandler>, INotificationHandler>>, + IKeyed, ISelectable, IRemovable { diff --git a/Bitvault/ItemPasswordEntryViewModel.cs b/Bitvault/ItemPasswordEntryViewModel.cs index 9eda6e1..90c92fe 100644 --- a/Bitvault/ItemPasswordEntryViewModel.cs +++ b/Bitvault/ItemPasswordEntryViewModel.cs @@ -8,7 +8,6 @@ public partial class ItemPasswordEntryViewModel(IServiceProvider provider, IPublisher publisher, ISubscription subscriber, IDisposer disposer, - ISynchronizationCollection synchronization, ItemEntryConfiguration configuration, string? key = default, - string? value = default) : ItemEntryViewModel(provider, factory, mediator, publisher, subscriber, disposer, synchronization, configuration, key, value); \ No newline at end of file + object? value = default) : ItemEntryViewModel(provider, factory, mediator, publisher, subscriber, disposer, configuration, key, value); \ No newline at end of file diff --git a/Bitvault/ItemPasswordEntryViewModelHandler.cs b/Bitvault/ItemPasswordEntryViewModelHandler.cs index fe8da09..295e019 100644 --- a/Bitvault/ItemPasswordEntryViewModelHandler.cs +++ b/Bitvault/ItemPasswordEntryViewModelHandler.cs @@ -10,7 +10,7 @@ public class ItemPasswordEntryViewModelHandler(IServiceFactory serviceFactory) : { if (args.Value is PasswordEntryConfiguration configuration) { - if (serviceFactory.Create([.. args.Parameters, configuration, configuration.Label, configuration.Value ?? ""]) + if (serviceFactory.Create(configuration, configuration.Label, configuration.Value ?? "") is ItemPasswordEntryViewModel viewModel) { return Task.FromResult(viewModel); diff --git a/Bitvault/ItemSectionViewModel.cs b/Bitvault/ItemSectionViewModel.cs index da91471..48ec838 100644 --- a/Bitvault/ItemSectionViewModel.cs +++ b/Bitvault/ItemSectionViewModel.cs @@ -1,9 +1,8 @@ -using CommunityToolkit.Mvvm.ComponentModel; -using Toolkit.Foundation; +using Toolkit.Foundation; namespace Bitvault; -[Notification(typeof(CreateEventArgs), nameof(Section))] +[Notification(typeof(CreateEventArgs), nameof(Id))] public partial class ItemSectionViewModel(IServiceProvider provider, IServiceFactory factory, IMediator mediator, @@ -11,18 +10,10 @@ public partial class ItemSectionViewModel(IServiceProvider provider, ISubscription subscriber, IDisposer disposer, IContentTemplate template, - ISynchronizationCollection synchronization, - string section) : ObservableCollection(provider, factory, mediator, publisher, subscriber, disposer), - IHandler, (int, string)>, - IIndexable + string id) : ObservableCollection(provider, factory, mediator, publisher, subscriber, disposer), + IKeyed { - [ObservableProperty] - private string section = section; + public string Id => id; public IContentTemplate Template { get; set; } = template; - - public int Index => synchronization.IndexOf(this); - - public Task<(int, string)> Handle(ConfirmEventArgs args, - CancellationToken cancellationToken) => Task.FromResult((0, Section)); } diff --git a/Bitvault/ItemTextEntryViewModel.cs b/Bitvault/ItemTextEntryViewModel.cs index ebe522c..1e66169 100644 --- a/Bitvault/ItemTextEntryViewModel.cs +++ b/Bitvault/ItemTextEntryViewModel.cs @@ -8,7 +8,6 @@ public partial class ItemTextEntryViewModel(IServiceProvider provider, IPublisher publisher, ISubscription subscriber, IDisposer disposer, - ISynchronizationCollection synchronization, ItemEntryConfiguration configuration, string? key = default, - string? value = default) : ItemEntryViewModel(provider, factory, mediator, publisher, subscriber, disposer, synchronization, configuration, key, value); \ No newline at end of file + object? value = default) : ItemEntryViewModel(provider, factory, mediator, publisher, subscriber, disposer, configuration, key, value); \ No newline at end of file diff --git a/Bitvault/ItemTextEntryViewModelHandler.cs b/Bitvault/ItemTextEntryViewModelHandler.cs index 4d30ba0..946aa54 100644 --- a/Bitvault/ItemTextEntryViewModelHandler.cs +++ b/Bitvault/ItemTextEntryViewModelHandler.cs @@ -10,7 +10,7 @@ public class ItemTextEntryViewModelHandler(IServiceFactory serviceFactory) : { if (args.Value is TextEntryConfiguration configuration) { - if (serviceFactory.Create([.. args.Parameters, configuration, configuration.Label, configuration.Value ?? ""]) + if (serviceFactory.Create(configuration, configuration.Label, configuration.Value ?? "") is ItemTextEntryViewModel viewModel) { return Task.FromResult(viewModel); diff --git a/Bitvault/ItemViewModel.cs b/Bitvault/ItemViewModel.cs index ee1a23c..d0bdfa2 100644 --- a/Bitvault/ItemViewModel.cs +++ b/Bitvault/ItemViewModel.cs @@ -3,12 +3,10 @@ using Toolkit.Foundation; namespace Bitvault; -[Notification(typeof(ConfirmEventArgs), nameof(ItemState.New))] -[Notification(typeof(ConfirmEventArgs), nameof(ItemState.Write))] public partial class ItemViewModel : ObservableCollection, - INotificationHandler>, INotificationHandler>, + INotificationHandler>, INotificationHandler> { [ObservableProperty] @@ -51,8 +49,8 @@ public partial class ItemViewModel : Archived = archived; Name = name; - Add(state, name); - Add(state); + Add(name, state); + Add(); } public IContentTemplate Template { get; set; } @@ -61,7 +59,7 @@ public partial class ItemViewModel : { Publisher.Publish(Notify.As(Factory.Create(new List { - Factory.Create(ItemState.Write), + Factory.Create(), Factory.Create(), }))); @@ -97,6 +95,9 @@ public partial class ItemViewModel : Factory.Create(), Factory.Create(), }))); + + Publisher.Publish(Confirm.As(), + State is ItemState.New ? nameof(ItemState.New) : nameof(ItemState.Write)); State = ItemState.Read; return Task.CompletedTask; diff --git a/Bitvault/SynchronizeItemContentFromCategoryViewModelHandler.cs b/Bitvault/SynchronizeItemContentFromCategoryViewModelHandler.cs index 3ef3b89..ed76780 100644 --- a/Bitvault/SynchronizeItemContentFromCategoryViewModelHandler.cs +++ b/Bitvault/SynchronizeItemContentFromCategoryViewModelHandler.cs @@ -4,36 +4,40 @@ using Toolkit.Foundation; namespace Bitvault; public class SynchronizeItemContentFromCategoryViewModelHandler(IItemConfigurationCollection configurations, + IDecoratorService decoratorItemConfiguration, IServiceFactory serviceFactory, IMediator mediator, IPublisher publisher) : - INotificationHandler)>> + INotificationHandler> { - public async Task Handle(SynchronizeEventArgs)> args) + public async Task Handle(SynchronizeEventArgs args) { - (string category, ISynchronizationCollection synchronization) = args.Value; - if (configurations.TryGetValue(category, out Func? factory)) + if (args.Value is string category) { - if (factory.Invoke() is ItemConfiguration configuration) + if (configurations.TryGetValue(category, out Func? configurationFactory)) { - foreach (ItemSectionConfiguration configurationSection in configuration.Sections) + if (configurationFactory.Invoke() is ItemConfiguration configuration) { - string section = $"{nameof(ItemSection)}:{Guid.NewGuid()}"; - if (serviceFactory.Create(synchronization, section) - is ItemSectionViewModel sectionViewModel) + decoratorItemConfiguration.Set(configuration); + foreach (ItemSectionConfiguration configurationSection in configuration.Sections) { - publisher.Publish(Create.As(sectionViewModel), nameof(ItemContentViewModel)); - foreach (IItemEntryConfiguration entryConfiguration in configurationSection.Entries) + string id = $"{nameof(ItemSection)}:{Guid.NewGuid()}"; + if (serviceFactory.Create(id) + is ItemSectionViewModel sectionViewModel) { - Type messageType = typeof(CreateEventArgs<>).MakeGenericType(entryConfiguration.GetType()); - ConstructorInfo? constructor = messageType.GetConstructor([entryConfiguration.GetType(), typeof(object[])]); - - if (constructor?.Invoke(new object[] { entryConfiguration, new object[] { sectionViewModel } }) is object message) + publisher.Publish(Create.As(sectionViewModel), nameof(ItemContentViewModel)); + foreach (IItemEntryConfiguration entryConfiguration in configurationSection.Entries) { - if (await mediator.Handle(message, entryConfiguration.GetType().Name) is IItemEntryViewModel entryViewModel) + Type messageType = typeof(CreateEventArgs<>).MakeGenericType(entryConfiguration.GetType()); + ConstructorInfo? constructor = messageType.GetConstructor([entryConfiguration.GetType(), typeof(object[])]); + + if (constructor?.Invoke(new object[] { entryConfiguration, new object[] { sectionViewModel } }) is object message) { - publisher.Publish(Create.As(entryViewModel), section); + if (await mediator.Handle(message, + entryConfiguration.GetType().Name) is IItemEntryViewModel entryViewModel) + { + publisher.Publish(Create.As(entryViewModel), id); + } } } } @@ -41,6 +45,5 @@ public class SynchronizeItemContentFromCategoryViewModelHandler(IItemConfigurati } } } - } }