Fixed more edge cases

This commit is contained in:
TheXamlGuy
2024-05-21 20:32:41 +01:00
parent 15de406460
commit 5c1a579984
24 changed files with 173 additions and 87 deletions
+10 -9
View File
@@ -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);
});
})!);
+1 -5
View File
@@ -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>
+1 -1
View File
@@ -12,7 +12,7 @@
<TextBox
MaxWidth="360"
IsVisible="{Binding !Immutable}"
Text="{Binding Value}"
Text="{Binding Value, UpdateSourceTrigger=PropertyChanged}"
TextAlignment="Center"
Watermark="Enter name" />
<SelectableTextBlock
+1 -4
View File
@@ -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}" />
+8
View File
@@ -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>
+1 -1
View File
@@ -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));
}
+23 -6
View File
@@ -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 }));
}
}
}
}
+3 -7
View File
@@ -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));
}
}
+1 -1
View File
@@ -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
View File
@@ -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, "");
}
}
+3 -1
View File
@@ -2,4 +2,6 @@
namespace Bitvault;
public interface IContainerNavigationViewModel : ISelectable;
public interface IContainerNavigationViewModel :
ISelectable,
IDisposable;
+1 -1
View File
@@ -1,3 +1,3 @@
namespace Bitvault;
public interface IMainNavigationViewModel;
public interface IMainNavigationViewModel : IDisposable;
+4 -2
View File
@@ -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; } = "";
}
+1 -1
View File
@@ -2,5 +2,5 @@
public record ItemConfiguration
{
public string? Name { get; set; }
public string Name { get; set; } = "";
}
+6 -1
View File
@@ -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 });
}
+3 -3
View File
@@ -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),
+11 -1
View File
@@ -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; }
+42
View File
@@ -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;
}
}
+2 -7
View File
@@ -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)
{
+6
View File
@@ -0,0 +1,6 @@
namespace Bitvault;
public record QueryItemConfiguration
{
public int Id { get; set; }
}
+1 -1
Submodule Toolkit updated: 72a37c7275...1190303044