Add ability to fully delete items from the DB
This commit is contained in:
+1
-1
Submodule Toolkit updated: 4a33a1931f...f993e1d44b
@@ -105,6 +105,7 @@ public partial class App : Application
|
|||||||
services.AddHandler<QueryWalletHandler>();
|
services.AddHandler<QueryWalletHandler>();
|
||||||
services.AddHandler<RequestItemHandler>();
|
services.AddHandler<RequestItemHandler>();
|
||||||
services.AddHandler<CreateItemHandler>();
|
services.AddHandler<CreateItemHandler>();
|
||||||
|
services.AddHandler<DeleteItemHandler>();
|
||||||
services.AddHandler<UpdateItemHander>();
|
services.AddHandler<UpdateItemHander>();
|
||||||
services.AddHandler<UpdateItemStateHandler>();
|
services.AddHandler<UpdateItemStateHandler>();
|
||||||
services.AddHandler<CountCategoriesHandler>();
|
services.AddHandler<CountCategoriesHandler>();
|
||||||
@@ -181,7 +182,8 @@ public partial class App : Application
|
|||||||
|
|
||||||
services.AddHandler<ConfirmUpdateItemHandler>(nameof(ItemState.Write));
|
services.AddHandler<ConfirmUpdateItemHandler>(nameof(ItemState.Write));
|
||||||
services.AddHandler<ConfirmCreateItemHandler>(nameof(ItemState.New));
|
services.AddHandler<ConfirmCreateItemHandler>(nameof(ItemState.New));
|
||||||
|
services.AddHandler<ConfirmDeleteItemHandler>();
|
||||||
|
|
||||||
services.AddHandler<HyperlinkHandler>();
|
services.AddHandler<HyperlinkHandler>();
|
||||||
|
|
||||||
services.AddHandler<ItemChangedHandler>(ServiceLifetime.Singleton);
|
services.AddHandler<ItemChangedHandler>(ServiceLifetime.Singleton);
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
Margin="0,3,0,0"
|
Margin="0,3,0,0"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
FontFamily="{DynamicResource FluentThemeFontFamily}"
|
FontFamily="{DynamicResource FluentThemeFontFamily}"
|
||||||
FontSize="16"
|
FontSize="18"
|
||||||
Foreground="{DynamicResource IconForegroundBrush}"
|
Foreground="{DynamicResource IconForegroundBrush}"
|
||||||
Text="" />
|
Text="" />
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
Margin="0,3,0,0"
|
Margin="0,3,0,0"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
FontFamily="{DynamicResource FluentThemeFontFamily}"
|
FontFamily="{DynamicResource FluentThemeFontFamily}"
|
||||||
FontSize="16"
|
FontSize="18"
|
||||||
Foreground="{DynamicResource IconForegroundBrush}"
|
Foreground="{DynamicResource IconForegroundBrush}"
|
||||||
Text="" />
|
Text="" />
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -14,9 +14,9 @@
|
|||||||
<TextBlock
|
<TextBlock
|
||||||
Margin="0,3,0,0"
|
Margin="0,3,0,0"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
FontFamily="{DynamicResource SymbolThemeFontFamily}"
|
FontFamily="{DynamicResource FluentThemeFontFamily}"
|
||||||
FontSize="16"
|
FontSize="18"
|
||||||
Foreground="{DynamicResource IconForegroundBrush}"
|
Foreground="{DynamicResource IconForegroundBrush}"
|
||||||
Text="" />
|
Text="" />
|
||||||
</Button>
|
</Button>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
Margin="0,3,0,0"
|
Margin="0,3,0,0"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
FontFamily="{DynamicResource FluentThemeFontFamily}"
|
FontFamily="{DynamicResource FluentThemeFontFamily}"
|
||||||
FontSize="16"
|
FontSize="18"
|
||||||
Foreground="{DynamicResource IconForegroundBrush}"
|
Foreground="{DynamicResource IconForegroundBrush}"
|
||||||
Text="" />
|
Text="" />
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
Margin="0,3,0,0"
|
Margin="0,3,0,0"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
FontFamily="{DynamicResource FluentThemeFontFamily}"
|
FontFamily="{DynamicResource FluentThemeFontFamily}"
|
||||||
FontSize="16"
|
FontSize="18"
|
||||||
Foreground="{DynamicResource IconForegroundBrush}"
|
Foreground="{DynamicResource IconForegroundBrush}"
|
||||||
Text="" />
|
Text="" />
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -14,14 +14,14 @@
|
|||||||
<TextBlock
|
<TextBlock
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
FontFamily="{DynamicResource FluentThemeFontFamily}"
|
FontFamily="{DynamicResource FluentThemeFontFamily}"
|
||||||
FontSize="16"
|
FontSize="18"
|
||||||
Foreground="{DynamicResource IconForegroundBrush}"
|
Foreground="{DynamicResource IconForegroundBrush}"
|
||||||
IsVisible="{Binding !Value}"
|
IsVisible="{Binding !Value}"
|
||||||
Text="" />
|
Text="" />
|
||||||
<TextBlock
|
<TextBlock
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
FontFamily="{DynamicResource FluentThemeFontFamily}"
|
FontFamily="{DynamicResource FluentThemeFontFamily}"
|
||||||
FontSize="16"
|
FontSize="18"
|
||||||
Foreground="{DynamicResource IconForegroundBrush}"
|
Foreground="{DynamicResource IconForegroundBrush}"
|
||||||
IsVisible="{Binding Value}"
|
IsVisible="{Binding Value}"
|
||||||
Text="" />
|
Text="" />
|
||||||
|
|||||||
@@ -5,6 +5,11 @@
|
|||||||
xmlns:vm="using:Wallet"
|
xmlns:vm="using:Wallet"
|
||||||
x:DataType="vm:ItemSectionViewModel">
|
x:DataType="vm:ItemSectionViewModel">
|
||||||
<ItemsControl ItemTemplate="{ReflectionBinding Template}" ItemsSource="{Binding}">
|
<ItemsControl ItemTemplate="{ReflectionBinding Template}" ItemsSource="{Binding}">
|
||||||
|
<ItemsControl.Styles>
|
||||||
|
<Style Selector="ContentPresenter">
|
||||||
|
<Setter Property="IsTabStop" Value="False" />
|
||||||
|
</Style>
|
||||||
|
</ItemsControl.Styles>
|
||||||
<ItemsControl.ItemsPanel>
|
<ItemsControl.ItemsPanel>
|
||||||
<ItemsPanelTemplate>
|
<ItemsPanelTemplate>
|
||||||
<StackPanel Orientation="Vertical" Spacing="4" />
|
<StackPanel Orientation="Vertical" Spacing="4" />
|
||||||
|
|||||||
@@ -2,8 +2,15 @@
|
|||||||
x:Class="Wallet.Avalonia.ItemView"
|
x:Class="Wallet.Avalonia.ItemView"
|
||||||
xmlns="https://github.com/avaloniaui"
|
xmlns="https://github.com/avaloniaui"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:ui="using:FluentAvalonia.UI.Controls"
|
||||||
xmlns:vm="using:Wallet"
|
xmlns:vm="using:Wallet"
|
||||||
x:DataType="vm:ItemViewModel">
|
x:DataType="vm:ItemViewModel">
|
||||||
|
<UserControl.Styles>
|
||||||
|
<Style Selector="ui|SettingsExpander">
|
||||||
|
<Setter Property="IsTabStop" Value="False" />
|
||||||
|
<Setter Property="KeyboardNavigation.TabNavigation" Value="Local" />
|
||||||
|
</Style>
|
||||||
|
</UserControl.Styles>
|
||||||
<Interaction.Behaviors>
|
<Interaction.Behaviors>
|
||||||
<AttachedBehaviour>
|
<AttachedBehaviour>
|
||||||
<NavigateAction
|
<NavigateAction
|
||||||
|
|||||||
@@ -10,12 +10,12 @@
|
|||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Command="{Binding InvokeCommand}"
|
Command="{Binding InvokeCommand}"
|
||||||
Foreground="{DynamicResource IconForegroundBrush}"
|
Foreground="{DynamicResource IconForegroundBrush}"
|
||||||
ToolTip.Tip="Unarchive">
|
ToolTip.Tip="Restore">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
FontFamily="{DynamicResource FluentThemeFontFamily}"
|
FontFamily="{DynamicResource FluentThemeFontFamily}"
|
||||||
FontSize="16"
|
FontSize="18"
|
||||||
Foreground="{DynamicResource IconForegroundBrush}"
|
Foreground="{DynamicResource IconForegroundBrush}"
|
||||||
Text="" />
|
Text="" />
|
||||||
</Button>
|
</Button>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
|||||||
@@ -15,10 +15,12 @@ public class WalletContext(DbContextOptions<WalletContext> options) :
|
|||||||
{
|
{
|
||||||
modelBuilder.Entity<ItemEntry>()
|
modelBuilder.Entity<ItemEntry>()
|
||||||
.HasMany(x => x.Tags)
|
.HasMany(x => x.Tags)
|
||||||
.WithOne();
|
.WithOne()
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
modelBuilder.Entity<ItemEntry>()
|
modelBuilder.Entity<ItemEntry>()
|
||||||
.HasMany(x => x.Blobs)
|
.HasMany(x => x.Blobs)
|
||||||
.WithOne();
|
.WithOne()
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
using Toolkit.Foundation;
|
||||||
|
|
||||||
|
namespace Wallet;
|
||||||
|
|
||||||
|
public class ConfirmDeleteItemHandler(IDecoratorService<Item<(Guid, string)>> decoratorService,
|
||||||
|
ICache<Item<(Guid, string)>> cache,
|
||||||
|
IMediator mediator,
|
||||||
|
IPublisher publisher) :
|
||||||
|
INotificationHandler<DeleteEventArgs<Item>>
|
||||||
|
{
|
||||||
|
public async Task Handle(DeleteEventArgs<Item> args)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (decoratorService.Service is Item<(Guid, string)> item)
|
||||||
|
{
|
||||||
|
(Guid id, string name) = item.Value;
|
||||||
|
|
||||||
|
await mediator.Handle<DeleteEventArgs<Item<Guid>>,
|
||||||
|
bool>(new DeleteEventArgs<Item<Guid>>(new Item<Guid>(id)));
|
||||||
|
|
||||||
|
cache.Add(item);
|
||||||
|
publisher.Publish(Changed.As<Item>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Toolkit.Foundation;
|
||||||
|
using Wallet.Data;
|
||||||
|
|
||||||
|
namespace Wallet;
|
||||||
|
|
||||||
|
public class DeleteItemHandler(IDbContextFactory<WalletContext> dbContextFactory) :
|
||||||
|
IHandler<DeleteEventArgs<Item<Guid>>, bool>
|
||||||
|
{
|
||||||
|
public async Task<bool> Handle(DeleteEventArgs<Item<Guid>> args,
|
||||||
|
CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
if (args.Sender is Item<Guid> item)
|
||||||
|
{
|
||||||
|
Guid id = item.Value;
|
||||||
|
|
||||||
|
using WalletContext context = await dbContextFactory.CreateDbContextAsync(cancellationToken);
|
||||||
|
if (await context.FindAsync<ItemEntry>(id) is ItemEntry result)
|
||||||
|
{
|
||||||
|
context.Items.Remove(result);
|
||||||
|
await context.SaveChangesAsync(cancellationToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,6 +23,7 @@ public partial class ItemNavigationViewModel(IServiceProvider provider,
|
|||||||
INotificationHandler<UnarchiveEventArgs<Item>>,
|
INotificationHandler<UnarchiveEventArgs<Item>>,
|
||||||
INotificationHandler<FavouriteEventArgs<Item>>,
|
INotificationHandler<FavouriteEventArgs<Item>>,
|
||||||
INotificationHandler<UnfavouriteEventArgs<Item>>,
|
INotificationHandler<UnfavouriteEventArgs<Item>>,
|
||||||
|
INotificationHandler<DeleteEventArgs<Item>>,
|
||||||
INotificationHandler<NotifyEventArgs<ItemHeader<string>>>,
|
INotificationHandler<NotifyEventArgs<ItemHeader<string>>>,
|
||||||
IKeyed<Guid>,
|
IKeyed<Guid>,
|
||||||
ISelectable,
|
ISelectable,
|
||||||
@@ -43,15 +44,14 @@ public partial class ItemNavigationViewModel(IServiceProvider provider,
|
|||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private Guid id = id;
|
private Guid id = id;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private bool isSelected = isSelected;
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? name = name;
|
private string? name = name;
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string named = $"{named}";
|
private string named = $"{named}";
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private bool isSelected = isSelected;
|
|
||||||
|
|
||||||
public IContentTemplate Template { get; set; } = template;
|
public IContentTemplate Template { get; set; } = template;
|
||||||
|
|
||||||
public Task Handle(ArchiveEventArgs<Item> args) =>
|
public Task Handle(ArchiveEventArgs<Item> args) =>
|
||||||
@@ -75,4 +75,7 @@ public partial class ItemNavigationViewModel(IServiceProvider provider,
|
|||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Task Handle(DeleteEventArgs<Item> args) =>
|
||||||
|
Task.Run(Dispose);
|
||||||
}
|
}
|
||||||
@@ -108,6 +108,7 @@ public partial class ItemViewModel :
|
|||||||
Publisher.Publish(Notify.As(Factory.Create<ItemCommandHeaderCollection>(new List<IDisposable>
|
Publisher.Publish(Notify.As(Factory.Create<ItemCommandHeaderCollection>(new List<IDisposable>
|
||||||
{
|
{
|
||||||
Factory.Create<UnarchiveItemActionViewModel>(),
|
Factory.Create<UnarchiveItemActionViewModel>(),
|
||||||
|
Factory.Create<DeleteItemActionViewModel>(),
|
||||||
})));
|
})));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ public class UpdateItemHander(IDbContextFactory<WalletContext> dbContextFactory)
|
|||||||
public async Task<bool> Handle(UpdateEventArgs<Item<(Guid, string, ItemConfiguration)>> args,
|
public async Task<bool> Handle(UpdateEventArgs<Item<(Guid, string, ItemConfiguration)>> args,
|
||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (args.Value is Item<(Guid, string, ItemConfiguration)> item)
|
if (args.Sender is Item<(Guid, string, ItemConfiguration)> item)
|
||||||
{
|
{
|
||||||
(Guid id, string name, ItemConfiguration configuration) = item.Value;
|
(Guid id, string name, ItemConfiguration configuration) = item.Value;
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ public class UpdateItemStateHandler(IDbContextFactory<WalletContext> dbContextFa
|
|||||||
public async Task<bool> Handle(UpdateEventArgs<(Guid, int)> args,
|
public async Task<bool> Handle(UpdateEventArgs<(Guid, int)> args,
|
||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (args.Value is (Guid id, int state))
|
if (args.Sender is (Guid id, int state))
|
||||||
{
|
{
|
||||||
using WalletContext context = await dbContextFactory.CreateDbContextAsync(cancellationToken);
|
using WalletContext context = await dbContextFactory.CreateDbContextAsync(cancellationToken);
|
||||||
if (await context.FindAsync<ItemEntry>(id) is ItemEntry result)
|
if (await context.FindAsync<ItemEntry>(id) is ItemEntry result)
|
||||||
|
|||||||
Reference in New Issue
Block a user