Fixed more edge cases
This commit is contained in:
@@ -42,8 +42,7 @@ public partial class App : Application
|
||||
{
|
||||
args.AddServices(services =>
|
||||
{
|
||||
services.AddTransient<IComparer<Item>>(provider => Comparer<Item>.Create((x, z) =>
|
||||
x.Name!.CompareTo(z.Name) == 0 ? 1 : x.Name!.CompareTo(z.Name)));
|
||||
services.AddTransient<IComparer<Item>>(provider => Comparer<Item>.Create((x, z) => x.Name.CompareTo(z.Name)));
|
||||
|
||||
services.AddCache<Item>();
|
||||
|
||||
@@ -69,7 +68,8 @@ public partial class App : Application
|
||||
});
|
||||
|
||||
services.AddHandler<QueryContainerHandler>();
|
||||
services.AddHandler<CreateItemHander>();
|
||||
services.AddHandler<CreateItemHandler>();
|
||||
services.AddHandler<EditItemHander>();
|
||||
|
||||
services.AddHandler<OpenContainerHandler>();
|
||||
|
||||
@@ -108,13 +108,14 @@ public partial class App : Application
|
||||
|
||||
services.AddScoped<IValueStore<Item>, ValueStore<Item>>();
|
||||
|
||||
services.AddHandler<ConfirmItemHandler>(ServiceLifetime.Scoped);
|
||||
services.AddHandler<ArchiveItemHandler>(ServiceLifetime.Scoped);
|
||||
services.AddHandler<UnarchiveItemHandler>(ServiceLifetime.Scoped);
|
||||
services.AddHandler<FavouriteItemHandler>(ServiceLifetime.Scoped);
|
||||
services.AddHandler<UnfavouriteItemHandler>(ServiceLifetime.Scoped);
|
||||
services.AddHandler<ConfirmItemHandler>();
|
||||
services.AddHandler<ArchiveItemHandler>();
|
||||
services.AddHandler<UnarchiveItemHandler>();
|
||||
services.AddHandler<FavouriteItemHandler>();
|
||||
services.AddHandler<UnfavouriteItemHandler>();
|
||||
|
||||
services.AddHandler<ItemActivatedHandler>(ServiceLifetime.Singleton);
|
||||
services.AddHandler<CreatedItemHandler>(ServiceLifetime.Singleton);
|
||||
services.AddHandler<ModifiedItemHandler>(ServiceLifetime.Singleton);
|
||||
});
|
||||
})!);
|
||||
|
||||
|
||||
@@ -28,14 +28,10 @@
|
||||
</Grid>
|
||||
<Interaction.Behaviors>
|
||||
<EventTriggerBehavior EventName="Click">
|
||||
<NavigateAction
|
||||
Region="{Binding Named, StringFormat='{}{0}:ContentHeader'}"
|
||||
Route="ItemCommandHeader"
|
||||
Scope="self" />
|
||||
<NavigateAction
|
||||
Region="{Binding Named, StringFormat='{}{0}:Content'}"
|
||||
Route="Item"
|
||||
Scope="self">
|
||||
Scope="new">
|
||||
<NavigateAction.ParameterBindings>
|
||||
<ParameterBinding Key="Immutable" Value="{x:False}" />
|
||||
</NavigateAction.ParameterBindings>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<TextBox
|
||||
MaxWidth="360"
|
||||
IsVisible="{Binding !Immutable}"
|
||||
Text="{Binding Value}"
|
||||
Text="{Binding Value, UpdateSourceTrigger=PropertyChanged}"
|
||||
TextAlignment="Center"
|
||||
Watermark="Enter name" />
|
||||
<SelectableTextBlock
|
||||
|
||||
@@ -10,15 +10,12 @@
|
||||
</ListBoxItem.Resources>
|
||||
<Interaction.Behaviors>
|
||||
<DataTriggerBehavior Binding="{Binding Selected}" Value="True">
|
||||
<NavigateAction
|
||||
Region="{Binding Named, StringFormat='{}{0}:ContentHeader'}"
|
||||
Route="ItemCommandHeader"
|
||||
Scope="self" />
|
||||
<NavigateAction
|
||||
Region="{Binding Named, StringFormat='{}{0}:Content'}"
|
||||
Route="Item"
|
||||
Scope="self">
|
||||
<NavigateAction.ParameterBindings>
|
||||
<ParameterBinding Key="Name" Value="{Binding Name}" />
|
||||
<ParameterBinding Key="Immutable" Value="{x:True}" />
|
||||
<ParameterBinding Key="Archived" Value="{Binding Archived}" />
|
||||
<ParameterBinding Key="Favourite" Value="{Binding Favourite}" />
|
||||
|
||||
@@ -4,6 +4,14 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:vm="using:Bitvault"
|
||||
x:DataType="vm:ItemViewModel">
|
||||
<Interaction.Behaviors>
|
||||
<AttachedBehaviour>
|
||||
<NavigateAction
|
||||
Region="{Binding Named, StringFormat='{}{0}:ContentHeader'}"
|
||||
Route="ItemCommandHeader"
|
||||
Scope="self" />
|
||||
</AttachedBehaviour>
|
||||
</Interaction.Behaviors>
|
||||
<ScrollViewer Padding="12,12,12,0">
|
||||
<ItemsControl ItemTemplate="{ReflectionBinding Template}" ItemsSource="{Binding}" />
|
||||
</ScrollViewer>
|
||||
|
||||
@@ -9,7 +9,7 @@ public record ItemEntry
|
||||
[Key]
|
||||
public int Id { get; set; }
|
||||
|
||||
public string? Name { get; set; }
|
||||
public required string Name { get; set; }
|
||||
|
||||
public string? Description { get; set; }
|
||||
|
||||
|
||||
@@ -18,13 +18,13 @@ public class AggerateContainerViewModelHandler(IMediator mediator,
|
||||
bool selected = true;
|
||||
|
||||
if (await mediator.Handle<RequestEventArgs<QueryContainerConfiguration>,
|
||||
IReadOnlyCollection<(int Id, string? Name, bool Favourite, bool Archived)>>(Request.As(new QueryContainerConfiguration
|
||||
IReadOnlyCollection<(int Id, string Name, bool Favourite, bool Archived)>>(Request.As(new QueryContainerConfiguration
|
||||
{
|
||||
Filter = configuration.Filter,
|
||||
Query = configuration.Query
|
||||
})) is IReadOnlyCollection<(int Id, string? Name, bool Favourite, bool Archived)> results)
|
||||
})) is IReadOnlyCollection<(int Id, string Name, bool Favourite, bool Archived)> results)
|
||||
{
|
||||
foreach ((int Id, string? Name, bool Favourite, bool Archived) in results)
|
||||
foreach ((int Id, string Name, bool Favourite, bool Archived) in results)
|
||||
{
|
||||
IServiceScope serviceScope = serviceProvider.CreateScope();
|
||||
IServiceFactory serviceFactory = serviceScope.ServiceProvider.GetRequiredService<IServiceFactory>();
|
||||
@@ -35,6 +35,7 @@ public class AggerateContainerViewModelHandler(IMediator mediator,
|
||||
Item item = new() { Id = Id, Name = Name };
|
||||
valueStore.Set(item);
|
||||
|
||||
cache.Add(item);
|
||||
publisher.Publish(Create.As(viewModel), nameof(ContainerViewModel));
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
|
||||
namespace Bitvault;
|
||||
|
||||
public class ConfirmItemHandler(IMediator mediator,
|
||||
public class ConfirmItemHandler(IValueStore<Item> valueStore,
|
||||
IMediator mediator,
|
||||
IPublisher publisher) :
|
||||
INotificationHandler<ConfirmEventArgs<Item>>
|
||||
{
|
||||
@@ -11,12 +12,28 @@ public class ConfirmItemHandler(IMediator mediator,
|
||||
ItemHeaderConfiguration? configuration = await mediator.Handle<ConfirmEventArgs<Item>,
|
||||
ItemHeaderConfiguration>(args);
|
||||
|
||||
(bool Success, int Id, string Name) result = await mediator.Handle<CreateEventArgs<ItemConfiguration>,
|
||||
(bool, int, string)>(new CreateEventArgs<ItemConfiguration>(new ItemConfiguration { Name = configuration?.Name }));
|
||||
|
||||
if (result.Success)
|
||||
if (valueStore?.Value is Item item)
|
||||
{
|
||||
publisher.Publish(Activated.As(new Item { Id = result.Id, Name = result.Name }));
|
||||
(bool Success, int Id, string Name) = await mediator.Handle<EditEventArgs<(int, ItemConfiguration)>,
|
||||
(bool, int, string)>(new EditEventArgs<(int, ItemConfiguration)>((item.Id, new ItemConfiguration { Name = configuration?.Name })));
|
||||
|
||||
if (Success)
|
||||
{
|
||||
Item newItem = new Item { Id = Id, Name = Name };
|
||||
publisher.Publish(Modified.As(item, newItem));
|
||||
|
||||
valueStore.Set(newItem);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
(bool Success, int Id, string Name) = await mediator.Handle<CreateEventArgs<ItemConfiguration>,
|
||||
(bool, int, string)>(new CreateEventArgs<ItemConfiguration>(new ItemConfiguration { Name = configuration?.Name }));
|
||||
|
||||
if (Success)
|
||||
{
|
||||
publisher.Publish(Created.As(new Item { Id = Id, Name = Name }));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace Bitvault;
|
||||
namespace Bitvault;
|
||||
|
||||
public record ContainerToken
|
||||
{
|
||||
@@ -21,9 +19,7 @@ public record ContainerToken
|
||||
}
|
||||
|
||||
|
||||
[MaybeNull]
|
||||
public string Name { get; }
|
||||
public string Name { get; } = "";
|
||||
|
||||
[MaybeNull]
|
||||
public string? Password { get; }
|
||||
public string? Password { get; } = "";
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ using Toolkit.Foundation;
|
||||
|
||||
namespace Bitvault;
|
||||
|
||||
public class CreateItemHander(IDbContextFactory<ContainerDbContext> dbContextFactory) :
|
||||
public class CreateItemHandler(IDbContextFactory<ContainerDbContext> dbContextFactory) :
|
||||
IHandler<CreateEventArgs<ItemConfiguration>, (bool, int, string?)>
|
||||
{
|
||||
public async Task<(bool, int, string?)> Handle(CreateEventArgs<ItemConfiguration> args,
|
||||
@@ -4,24 +4,27 @@ using Toolkit.Foundation;
|
||||
|
||||
namespace Bitvault;
|
||||
|
||||
public class ItemActivatedHandler(IServiceProvider serviceProvider,
|
||||
ICache<Item> cache,
|
||||
public class CreatedItemHandler(IServiceProvider serviceProvider,
|
||||
ICache< Item> cache,
|
||||
IPublisher publisher) :
|
||||
INotificationHandler<ActivatedEventArgs<Item>>
|
||||
INotificationHandler<CreatedEventArgs<Item>>
|
||||
{
|
||||
public Task Handle(ActivatedEventArgs<Item> args)
|
||||
public Task Handle(CreatedEventArgs<Item> args)
|
||||
{
|
||||
if (args.Value is Item item)
|
||||
{
|
||||
IServiceScope serviceScope = serviceProvider.CreateScope();
|
||||
IServiceFactory serviceFactory = serviceScope.ServiceProvider.GetRequiredService<IServiceFactory>();
|
||||
IValueStore<Item> valueStore = serviceScope.ServiceProvider.GetRequiredService<IValueStore<Item>>();
|
||||
|
||||
cache.Add(item);
|
||||
int index = cache.IndexOf(item);
|
||||
|
||||
if (serviceFactory.Create<ItemNavigationViewModel>(item.Id, item.Name, "Description " + 1, true)
|
||||
if (serviceFactory.Create<ItemNavigationViewModel>(item.Id, item.Name, "Description", true)
|
||||
is ItemNavigationViewModel viewModel)
|
||||
{
|
||||
cache.Add(item);
|
||||
|
||||
int index = cache.IndexOf(item);
|
||||
valueStore.Set(item);
|
||||
|
||||
publisher.Publish(Insert.As(index, viewModel), nameof(ContainerViewModel));
|
||||
}
|
||||
}
|
||||
@@ -11,5 +11,5 @@ public partial class EditItemActionViewModel(IServiceProvider provider,
|
||||
IDisposer disposer) : Observable(provider, factory, mediator, publisher, subscriber, disposer)
|
||||
{
|
||||
[RelayCommand]
|
||||
public void Invoke() => Publisher.Publish(Edit.As<Item>());
|
||||
public void Invoke() => Publisher.Publish(Edit.As<Item>(), nameof(ItemViewModel));
|
||||
}
|
||||
+28
-23
@@ -5,36 +5,41 @@ using Toolkit.Foundation;
|
||||
namespace Bitvault;
|
||||
|
||||
public class EditItemHander(IDbContextFactory<ContainerDbContext> dbContextFactory) :
|
||||
IHandler<EditEventArgs<(int, ItemConfiguration)>, bool>
|
||||
IHandler<EditEventArgs<(int, ItemConfiguration)>, (bool, int, string?)>
|
||||
{
|
||||
public async Task<bool> Handle(EditEventArgs<(int, ItemConfiguration)> args,
|
||||
public async Task<(bool, int, string?)> Handle(EditEventArgs<(int, ItemConfiguration)> args,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
//if (args.Value is ItemConfiguration configuration)
|
||||
//{
|
||||
// try
|
||||
// {
|
||||
// using ContainerDbContext context = dbContextFactory.CreateDbContext();
|
||||
// EntityEntry<ItemEntry>? result = null;
|
||||
if (args.Value is (int id, ItemConfiguration configuration))
|
||||
{
|
||||
try
|
||||
{
|
||||
using ContainerDbContext context = dbContextFactory.CreateDbContext();
|
||||
ItemEntry? result = null;
|
||||
|
||||
// await Task.Run(async () =>
|
||||
// {
|
||||
// result = await context.AddAsync(new ItemEntry { Name = configuration.Name }, cancellationToken);
|
||||
// await context.SaveChangesAsync(cancellationToken);
|
||||
await Task.Run(async () =>
|
||||
{
|
||||
result = await context.Set<ItemEntry>().FindAsync(id);
|
||||
|
||||
// }, cancellationToken);
|
||||
if (result is not null)
|
||||
{
|
||||
result.Name = configuration.Name;
|
||||
await context.SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
|
||||
// if (result is not null)
|
||||
// {
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
// catch
|
||||
// {
|
||||
}, cancellationToken);
|
||||
|
||||
// }
|
||||
//}
|
||||
if (result is not null)
|
||||
{
|
||||
return (true, result.Id, result.Name);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return (false, -1, "");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,6 @@
|
||||
|
||||
namespace Bitvault;
|
||||
|
||||
public interface IContainerNavigationViewModel : ISelectable;
|
||||
public interface IContainerNavigationViewModel :
|
||||
ISelectable,
|
||||
IDisposable;
|
||||
@@ -1,3 +1,3 @@
|
||||
namespace Bitvault;
|
||||
|
||||
public interface IMainNavigationViewModel;
|
||||
public interface IMainNavigationViewModel : IDisposable;
|
||||
|
||||
+4
-2
@@ -1,9 +1,11 @@
|
||||
namespace Bitvault;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace Bitvault;
|
||||
|
||||
public record Item
|
||||
{
|
||||
public int Id { get; init; }
|
||||
|
||||
public string? Name { get; init; }
|
||||
public string Name { get; init; } = "";
|
||||
}
|
||||
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
|
||||
public record ItemConfiguration
|
||||
{
|
||||
public string? Name { get; set; }
|
||||
public string Name { get; set; } = "";
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ public partial class ItemHeaderViewModel(IServiceProvider provider,
|
||||
string? value = null) : Observable<string, string>(provider, factory, mediator, publisher, subscriber, disposer, value),
|
||||
IHandler<ValidationEventArgs<Item>, bool>,
|
||||
IHandler<ConfirmEventArgs<Item>, ItemHeaderConfiguration>,
|
||||
IItemEntryViewModel
|
||||
IItemEntryViewModel, IRemovable
|
||||
{
|
||||
[ObservableProperty]
|
||||
private bool immutable = immutable;
|
||||
@@ -24,6 +24,11 @@ public partial class ItemHeaderViewModel(IServiceProvider provider,
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
public Task<ItemHeaderConfiguration> Handle(ConfirmEventArgs<Item> args,
|
||||
CancellationToken cancellationToken) => Task.FromResult(new ItemHeaderConfiguration { Name = Value });
|
||||
}
|
||||
|
||||
@@ -12,9 +12,9 @@ public partial class ItemNavigationViewModel(IServiceProvider provider,
|
||||
IContentTemplate template,
|
||||
NamedComponent named,
|
||||
int id,
|
||||
string name,
|
||||
string description,
|
||||
bool selected,
|
||||
string? name = "",
|
||||
string? description = "",
|
||||
bool selected = false,
|
||||
bool favourite = false,
|
||||
bool archived = false) :
|
||||
Observable(provider, factory, mediator, publisher, subscriber, disposer),
|
||||
|
||||
@@ -18,21 +18,31 @@ public partial class ItemViewModel :
|
||||
[ObservableProperty]
|
||||
private bool immutable;
|
||||
|
||||
public ItemViewModel(IServiceProvider provider,
|
||||
[ObservableProperty]
|
||||
private string named;
|
||||
|
||||
[ObservableProperty]
|
||||
private string name;
|
||||
|
||||
public ItemViewModel(IServiceProvider provider,
|
||||
IServiceFactory factory,
|
||||
IMediator mediator,
|
||||
IPublisher publisher,
|
||||
ISubscription subscriber,
|
||||
IDisposer disposer,
|
||||
IContentTemplate template,
|
||||
NamedComponent named,
|
||||
string name = "",
|
||||
bool immutable = true,
|
||||
bool favourite = false,
|
||||
bool archived = false) : base(provider, factory, mediator, publisher, subscriber, disposer)
|
||||
{
|
||||
Named = $"{named}";
|
||||
Template = template;
|
||||
Immutable = immutable;
|
||||
Favourite = favourite;
|
||||
Archived = archived;
|
||||
Name = name;
|
||||
}
|
||||
|
||||
public IContentTemplate Template { get; set; }
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Toolkit.Foundation;
|
||||
|
||||
namespace Bitvault;
|
||||
|
||||
public class ModifiedItemHandler(IServiceProvider serviceProvider,
|
||||
ICache<Item> cache,
|
||||
IPublisher publisher) :
|
||||
INotificationHandler<ModifiedEventArgs<Item>>
|
||||
{
|
||||
public Task Handle(ModifiedEventArgs<Item> args)
|
||||
{
|
||||
Item oldItem = args.OldView;
|
||||
Item newItem = args.NewValue;
|
||||
|
||||
if (cache.TryGetValue(oldItem, out Item? cachedItem))
|
||||
{
|
||||
if (cachedItem is not null)
|
||||
{
|
||||
IServiceScope serviceScope = serviceProvider.CreateScope();
|
||||
IServiceFactory serviceFactory = serviceScope.ServiceProvider.GetRequiredService<IServiceFactory>();
|
||||
IValueStore<Item> valueStore = serviceScope.ServiceProvider.GetRequiredService<IValueStore<Item>>();
|
||||
|
||||
if (serviceFactory.Create<ItemNavigationViewModel>(newItem.Id, newItem.Name, "Description", true)
|
||||
is ItemNavigationViewModel viewModel)
|
||||
{
|
||||
int oldIndex = cache.IndexOf(cachedItem);
|
||||
cache.Remove(cachedItem);
|
||||
|
||||
cache.Add(newItem);
|
||||
|
||||
int newIndex = cache.IndexOf(newItem);
|
||||
valueStore.Set(newItem);
|
||||
|
||||
publisher.Publish(RemoveAndInsertAt.As(oldIndex, newIndex, viewModel), nameof(ContainerViewModel));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
@@ -15,18 +15,13 @@ public class QueryItemHandler(IDbContextFactory<ContainerDbContext> dbContextFac
|
||||
}
|
||||
}
|
||||
|
||||
public record QueryItemConfiguration
|
||||
{
|
||||
public int Id { get; set; }
|
||||
}
|
||||
|
||||
public class QueryContainerHandler(IDbContextFactory<ContainerDbContext> dbContextFactory) :
|
||||
IHandler<RequestEventArgs<QueryContainerConfiguration>, IReadOnlyCollection<(int Id, string? Name, bool Favourite, bool Archived)>>
|
||||
{
|
||||
public async Task<IReadOnlyCollection<(int Id, string? Name, bool Favourite, bool Archived)>> Handle(RequestEventArgs<QueryContainerConfiguration> args,
|
||||
public async Task<IReadOnlyCollection<(int Id, string Name, bool Favourite, bool Archived)>> Handle(RequestEventArgs<QueryContainerConfiguration> args,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
List<(int Id, string? Name, bool Favourite, bool Archived)> items = [];
|
||||
List<(int Id, string Name, bool Favourite, bool Archived)> items = [];
|
||||
|
||||
if (args.Value is QueryContainerConfiguration queryConfiguration)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace Bitvault;
|
||||
|
||||
public record QueryItemConfiguration
|
||||
{
|
||||
public int Id { get; set; }
|
||||
}
|
||||
+1
-1
Submodule Toolkit updated: 72a37c7275...1190303044
Reference in New Issue
Block a user