diff --git a/Wallet.Avalonia/AllNavigationView.axaml b/Wallet.Avalonia/AllNavigationView.axaml
index 6ead957..5ec18e3 100644
--- a/Wallet.Avalonia/AllNavigationView.axaml
+++ b/Wallet.Avalonia/AllNavigationView.axaml
@@ -15,7 +15,7 @@
-
+
@@ -25,7 +25,7 @@
-
+
@@ -33,4 +33,7 @@
+
+
+
diff --git a/Wallet.Avalonia/App.axaml.cs b/Wallet.Avalonia/App.axaml.cs
index 4484820..4c6ce6f 100644
--- a/Wallet.Avalonia/App.axaml.cs
+++ b/Wallet.Avalonia/App.axaml.cs
@@ -108,6 +108,7 @@ public partial class App : Application
services.AddHandler();
services.AddHandler();
services.AddHandler();
+ services.AddHandler();
services.AddHandler();
@@ -184,6 +185,8 @@ public partial class App : Application
services.AddHandler();
+ services.AddHandler(ServiceLifetime.Singleton);
+
services.AddHandler();
services.AddHandler();
services.AddHandler();
diff --git a/Wallet.Avalonia/ArchiveNavigationView.axaml b/Wallet.Avalonia/ArchiveNavigationView.axaml
index 549b3a1..6a0a757 100644
--- a/Wallet.Avalonia/ArchiveNavigationView.axaml
+++ b/Wallet.Avalonia/ArchiveNavigationView.axaml
@@ -15,7 +15,7 @@
-
+
@@ -25,7 +25,7 @@
-
+
@@ -33,4 +33,7 @@
+
+
+
diff --git a/Wallet.Avalonia/CategoryNavigationView.axaml b/Wallet.Avalonia/CategoryNavigationView.axaml
index 4865dfd..565f3e6 100644
--- a/Wallet.Avalonia/CategoryNavigationView.axaml
+++ b/Wallet.Avalonia/CategoryNavigationView.axaml
@@ -4,7 +4,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:Wallet"
x:DataType="vm:CategoryNavigationViewModel"
- Content="{Binding Filter}"
+ Content="{Binding Value}"
IsSelected="{Binding Selected}">
@@ -15,7 +15,7 @@
-
+
@@ -25,7 +25,7 @@
-
+
diff --git a/Wallet.Avalonia/StarredNavigationView.axaml b/Wallet.Avalonia/StarredNavigationView.axaml
index 7365659..ce76d48 100644
--- a/Wallet.Avalonia/StarredNavigationView.axaml
+++ b/Wallet.Avalonia/StarredNavigationView.axaml
@@ -15,7 +15,7 @@
-
+
@@ -25,7 +25,7 @@
-
+
@@ -33,5 +33,8 @@
+
+
+
diff --git a/Wallet/AllNavigationViewModel.cs b/Wallet/AllNavigationViewModel.cs
index bdf6485..7427f5c 100644
--- a/Wallet/AllNavigationViewModel.cs
+++ b/Wallet/AllNavigationViewModel.cs
@@ -2,10 +2,20 @@
namespace Wallet;
+[Notification(typeof(NotifyEventArgs- >), "All")]
public partial class AllNavigationViewModel(IServiceProvider provider,
- IServiceFactory factory,
- IMediator mediator,
- IPublisher publisher,
- ISubscription subscriber,
- IDisposer disposer,
- string filter) : FilterNavigationViewModel(provider, factory, mediator, publisher, subscriber, disposer, filter);
\ No newline at end of file
+ IServiceFactory factory, IMediator mediator,
+ IPublisher publisher, ISubscription subscriber, IDisposer disposer, int key, string value) :
+ FilterNavigationViewModel(provider, factory, mediator, publisher, subscriber, disposer, key, value),
+ INotificationHandler>>
+{
+ public Task Handle(NotifyEventArgs
- > args)
+ {
+ if (args.Sender is Item item)
+ {
+ Key = item.Value;
+ }
+
+ return Task.CompletedTask;
+ }
+}
\ No newline at end of file
diff --git a/Wallet/ArchiveEventArgs.cs b/Wallet/ArchiveEventArgs.cs
index a996d3c..10f93b5 100644
--- a/Wallet/ArchiveEventArgs.cs
+++ b/Wallet/ArchiveEventArgs.cs
@@ -1,3 +1,3 @@
namespace Wallet;
-public record ArchiveEventArgs(TValue Value);
\ No newline at end of file
+public record ArchiveEventArgs(TSender Sender);
\ No newline at end of file
diff --git a/Wallet/ArchiveItemHandler.cs b/Wallet/ArchiveItemHandler.cs
index 23fea10..7e6a4ca 100644
--- a/Wallet/ArchiveItemHandler.cs
+++ b/Wallet/ArchiveItemHandler.cs
@@ -4,7 +4,8 @@ namespace Wallet;
public class ArchiveItemHandler(IDecoratorService
- > decoratorService,
ICache
- > cache,
- IMediator mediator) :
+ IMediator mediator,
+ IPublisher publisher) :
INotificationHandler>
{
public async Task Handle(ArchiveEventArgs
- args)
@@ -21,6 +22,7 @@ public class ArchiveItemHandler(IDecoratorService
- > decorato
bool>(new UpdateEventArgs<(Guid, int)>((id, 2)));
cache.Remove(item);
+ publisher.Publish(Changed.As(item));
}
}
}
diff --git a/Wallet/ArchiveNavigationViewModel.cs b/Wallet/ArchiveNavigationViewModel.cs
index c97f641..aaf5545 100644
--- a/Wallet/ArchiveNavigationViewModel.cs
+++ b/Wallet/ArchiveNavigationViewModel.cs
@@ -2,10 +2,24 @@
namespace Wallet;
+[Notification(typeof(NotifyEventArgs
- >), "Archive")]
public partial class ArchiveNavigationViewModel(IServiceProvider provider,
IServiceFactory factory,
IMediator mediator,
IPublisher publisher,
ISubscription subscriber,
IDisposer disposer,
- string name) : FilterNavigationViewModel(provider, factory, mediator, publisher, subscriber, disposer, name);
\ No newline at end of file
+ int key,
+ string value) : FilterNavigationViewModel(provider, factory, mediator, publisher, subscriber, disposer, key, value),
+ INotificationHandler>>
+{
+ public Task Handle(NotifyEventArgs
- > args)
+ {
+ if (args.Sender is Item item)
+ {
+ Key = item.Value;
+ }
+
+ return Task.CompletedTask;
+ }
+}
\ No newline at end of file
diff --git a/Wallet/CategoriesNavigationViewModel.cs b/Wallet/CategoriesNavigationViewModel.cs
index 7b772d3..310964d 100644
--- a/Wallet/CategoriesNavigationViewModel.cs
+++ b/Wallet/CategoriesNavigationViewModel.cs
@@ -9,7 +9,5 @@ public partial class CategoriesNavigationViewModel(IServiceProvider provider,
IPublisher publisher,
ISubscription subscriber,
IDisposer disposer,
- string name) : FilterNavigationViewModel(provider, factory, mediator, publisher, subscriber, disposer, name)
-{
-
-}
\ No newline at end of file
+ int key,
+ string value) : FilterNavigationViewModel(provider, factory, mediator, publisher, subscriber, disposer, key, value);
\ No newline at end of file
diff --git a/Wallet/CategoryNavigationViewModel.cs b/Wallet/CategoryNavigationViewModel.cs
index 479aec3..6159ac5 100644
--- a/Wallet/CategoryNavigationViewModel.cs
+++ b/Wallet/CategoryNavigationViewModel.cs
@@ -8,4 +8,4 @@ public partial class CategoryNavigationViewModel(IServiceProvider provider,
IPublisher publisher,
ISubscription subscriber,
IDisposer disposer,
- string filter) : FilterNavigationViewModel(provider, factory, mediator, publisher, subscriber, disposer, filter);
\ No newline at end of file
+ string value) : FilterNavigationViewModel(provider, factory, mediator, publisher, subscriber, disposer, 0, value);
\ No newline at end of file
diff --git a/Wallet/ConfirmCreateItemHandler.cs b/Wallet/ConfirmCreateItemHandler.cs
index a987ed7..bf2e035 100644
--- a/Wallet/ConfirmCreateItemHandler.cs
+++ b/Wallet/ConfirmCreateItemHandler.cs
@@ -13,15 +13,19 @@ public class ConfirmCreateItemHandler(IMediator mediator,
if (itemHeaderConfiguration.Service is ItemHeaderConfiguration headerConfiguration &&
itemConfigurationDecorator.Service is ItemConfiguration itemConfiguration)
{
- string? name = headerConfiguration?.Name;
- if (name is not null)
+ if (headerConfiguration.Name is { Length: > 0 } name &&
+ headerConfiguration.Category is { Length: > 0 } category)
{
Guid id = Guid.NewGuid();
- publisher.Publish(Created.As(new Item<(Guid, string)>((id, name))));
+
+ Item<(Guid, string)> item = new((id, name));
+ publisher.Publish(Created.As(item));
await mediator.Handle, bool>(new CreateEventArgs<(Guid, string, string,
- ItemConfiguration)>((id, name, "", itemConfiguration)));
+ ItemConfiguration)>((id, name, category, itemConfiguration)));
+
+ publisher.Publish(Changed.As(item));
}
}
}
diff --git a/Wallet/ConfirmUpdateItemHandler.cs b/Wallet/ConfirmUpdateItemHandler.cs
index 1791a2b..e834f3a 100644
--- a/Wallet/ConfirmUpdateItemHandler.cs
+++ b/Wallet/ConfirmUpdateItemHandler.cs
@@ -29,6 +29,8 @@ public class ConfirmUpdateItemHandler(IDecoratorService
- > it
await mediator.Handle>, bool>(new UpdateEventArgs
- >(new Item<(Guid, string, ItemConfiguration)>((id, name, itemConfiguration))));
+
+ publisher.Publish(Changed.As(item));
}
}
}
diff --git a/Wallet/CountCategoriesHandler.cs b/Wallet/CountCategoriesHandler.cs
new file mode 100644
index 0000000..46dfa59
--- /dev/null
+++ b/Wallet/CountCategoriesHandler.cs
@@ -0,0 +1,52 @@
+using Microsoft.EntityFrameworkCore;
+using System.Linq;
+using Toolkit.Foundation;
+using Wallet.Data;
+
+namespace Wallet;
+
+public class CountCategoriesHandler(IDbContextFactory dbContextFactory) :
+ IHandler, IReadOnlyCollection<(string, int)>>
+{
+ public async Task> Handle(CountEventArgs args,
+ CancellationToken cancellationToken)
+ {
+ using WalletContext context = await dbContextFactory.CreateDbContextAsync(cancellationToken);
+
+ var stateCounts = await context.Items
+ .GroupBy(i => i.State)
+ .Select(g => new
+ {
+ g.Key,
+ Count = g.Count()
+ })
+ .ToListAsync(cancellationToken: cancellationToken);
+
+ var categoryCounts = await context.Items.Where(x => !string.IsNullOrEmpty(x.Category))
+ .GroupBy(i => i.Category)
+ .Select(g => new
+ {
+ g.Key,
+ Count = g.Count()
+ })
+ .ToListAsync(cancellationToken: cancellationToken);
+
+ int allCount = stateCounts.Where(x => x.Key != 2).Sum(x => x.Count);
+ int favouritesCount = stateCounts.Where(x => x.Key == 1).Sum(x => x.Count);
+ int archiveCount = stateCounts.Where(x => x.Key == 2).Sum(x => x.Count);
+
+ List<(string, int)> combinedCounts =
+ [
+ new("Favourites", favouritesCount),
+ new("Archive", archiveCount),
+ new("All", allCount)
+ ];
+
+ foreach ((string key, int count) in categoryCounts.Select(x => (x.Key, x.Count)))
+ {
+ combinedCounts.Add((key, count));
+ }
+
+ return combinedCounts;
+ }
+}
diff --git a/Wallet/FavouriteEventArgs.cs b/Wallet/FavouriteEventArgs.cs
index c929ddb..0ce6902 100644
--- a/Wallet/FavouriteEventArgs.cs
+++ b/Wallet/FavouriteEventArgs.cs
@@ -1,3 +1,3 @@
namespace Wallet;
-public record FavouriteEventArgs(TValue Value);
\ No newline at end of file
+public record FavouriteEventArgs(TSender Sender);
\ No newline at end of file
diff --git a/Wallet/FavouriteItemHandler.cs b/Wallet/FavouriteItemHandler.cs
index 63f62ac..6723c91 100644
--- a/Wallet/FavouriteItemHandler.cs
+++ b/Wallet/FavouriteItemHandler.cs
@@ -3,7 +3,8 @@
namespace Wallet;
public class FavouriteItemHandler(IDecoratorService
- > decoratorService,
- IMediator mediator) :
+ IMediator mediator,
+ IPublisher publisher) :
INotificationHandler>
{
public async Task Handle(FavouriteEventArgs
- args)
@@ -14,6 +15,8 @@ public class FavouriteItemHandler(IDecoratorService
- > decora
{
(Guid id, string name) = item.Value;
await mediator.Handle, bool>(new UpdateEventArgs<(Guid, int)>((id, 1)));
+
+ publisher.Publish(Changed.As(item));
}
}
catch
diff --git a/Wallet/FilterNavigationViewModel.cs b/Wallet/FilterNavigationViewModel.cs
index 29e00a3..ec08dd8 100644
--- a/Wallet/FilterNavigationViewModel.cs
+++ b/Wallet/FilterNavigationViewModel.cs
@@ -4,7 +4,7 @@ using Toolkit.Foundation;
namespace Wallet;
public partial class FilterNavigationViewModel :
- ObservableCollection,
+ ObservableCollection,
IWalletNavigationViewModel,
INotificationHandler>,
INotificationHandler>
@@ -12,21 +12,19 @@ public partial class FilterNavigationViewModel :
[ObservableProperty]
private bool activated;
- [ObservableProperty]
- private string? filter;
-
[ObservableProperty]
private bool selected;
- public FilterNavigationViewModel(IServiceProvider provider,
- IServiceFactory factory,
- IMediator mediator,
+ public FilterNavigationViewModel(IServiceProvider provider,
+ IServiceFactory factory,
+ IMediator mediator,
IPublisher publisher,
ISubscription subscriber,
IDisposer disposer,
- string? filter = null) : base(provider, factory, mediator, publisher, subscriber, disposer)
+ int key,
+ string value) : base(provider, factory, mediator, publisher, subscriber, disposer, key, value)
{
- Filter = filter;
+
}
public Task Handle(DeactivatedEventArgs args) =>
@@ -37,7 +35,7 @@ public partial class FilterNavigationViewModel :
}
public partial class FilterNavigationViewModel :
- ObservableCollection,
+ ObservableCollection,
IWalletNavigationViewModel,
INotificationHandler>,
INotificationHandler>
@@ -47,21 +45,19 @@ public partial class FilterNavigationViewModel :
[ObservableProperty]
private bool activated;
- [ObservableProperty]
- private string? filter;
-
[ObservableProperty]
private bool selected;
public FilterNavigationViewModel(IServiceProvider provider,
IServiceFactory factory,
- IMediator mediator,
+ IMediator mediator,
IPublisher publisher,
- ISubscription subscriber,
+ ISubscription subscriber,
IDisposer disposer,
- string? filter = null) : base(provider, factory, mediator, publisher, subscriber, disposer)
+ int key,
+ string value) : base(provider, factory, mediator, publisher, subscriber, disposer, key, value)
{
- Filter = filter;
+
}
public Task Handle(DeactivatedEventArgs args) =>
diff --git a/Wallet/ItemChangedHandler.cs b/Wallet/ItemChangedHandler.cs
new file mode 100644
index 0000000..213093c
--- /dev/null
+++ b/Wallet/ItemChangedHandler.cs
@@ -0,0 +1,22 @@
+using Toolkit.Foundation;
+
+namespace Wallet;
+
+public class ItemChangedHandler(IMediator mediator,
+ IPublisher publisher) :
+ INotificationHandler>>
+{
+ public async Task Handle(ChangedEventArgs
- > args)
+ {
+ IReadOnlyCollection<(string, int)>? categoryCounts = await mediator.Handle,
+ IReadOnlyCollection<(string, int)>>(Count.As());
+
+ if (categoryCounts is { Count: > 0 } )
+ {
+ foreach ((string key, int count) in categoryCounts)
+ {
+ publisher.Publish(Notify.As(new Item(count)), key);
+ }
+ }
+ }
+}
diff --git a/Wallet/ItemHeaderConfiguration.cs b/Wallet/ItemHeaderConfiguration.cs
index 917e20b..65e8e00 100644
--- a/Wallet/ItemHeaderConfiguration.cs
+++ b/Wallet/ItemHeaderConfiguration.cs
@@ -3,4 +3,6 @@
public class ItemHeaderConfiguration
{
public string? Name { get; set; }
+
+ public string? Category { get; set; }
}
\ No newline at end of file
diff --git a/Wallet/ItemHeaderViewModel.cs b/Wallet/ItemHeaderViewModel.cs
index d03ff5e..45b1f39 100644
--- a/Wallet/ItemHeaderViewModel.cs
+++ b/Wallet/ItemHeaderViewModel.cs
@@ -70,6 +70,7 @@ public partial class ItemHeaderViewModel :
if (args.Sender is ItemCategory category)
{
Category = category.Value;
+ configuration.Category = category.Value;
}
return Task.CompletedTask;
diff --git a/Wallet/QueryWalletHandler.cs b/Wallet/QueryWalletHandler.cs
index 24fcc65..a196179 100644
--- a/Wallet/QueryWalletHandler.cs
+++ b/Wallet/QueryWalletHandler.cs
@@ -12,7 +12,7 @@ public class QueryWalletHandler(IDbContextFactory dbContextFactor
Handle(QueryEventArgs> args,CancellationToken cancellationToken)
{
List<(Guid Id, string? Name, string Category, bool Favourite, bool Archived)> items = [];
- if (args.Value is Wallet<(string, string)> Wallet)
+ if (args.Sender is Wallet<(string, string)> Wallet)
{
(string filter, string text) = Wallet.Sender;
diff --git a/Wallet/StarredNavigationViewModel.cs b/Wallet/StarredNavigationViewModel.cs
index c342159..4df0c65 100644
--- a/Wallet/StarredNavigationViewModel.cs
+++ b/Wallet/StarredNavigationViewModel.cs
@@ -2,10 +2,24 @@
namespace Wallet;
+[Notification(typeof(NotifyEventArgs
- >), "Favourites")]
public partial class StarredNavigationViewModel(IServiceProvider provider,
IServiceFactory factory,
IMediator mediator,
IPublisher publisher,
ISubscription subscriber,
IDisposer disposer,
- string name) : FilterNavigationViewModel(provider, factory, mediator, publisher, subscriber, disposer, name);
\ No newline at end of file
+ int key,
+ string value) : FilterNavigationViewModel(provider, factory, mediator, publisher, subscriber, disposer, key, value),
+ INotificationHandler>>
+{
+ public Task Handle(NotifyEventArgs
- > args)
+ {
+ if (args.Sender is Item item)
+ {
+ Key = item.Value;
+ }
+
+ return Task.CompletedTask;
+ }
+}
\ No newline at end of file
diff --git a/Wallet/UnarchiveEventArgs.cs b/Wallet/UnarchiveEventArgs.cs
index 428c457..f37c0b6 100644
--- a/Wallet/UnarchiveEventArgs.cs
+++ b/Wallet/UnarchiveEventArgs.cs
@@ -1,3 +1,3 @@
namespace Wallet;
-public record UnarchiveEventArgs(TValue Value);
\ No newline at end of file
+public record UnarchiveEventArgs(TSender Sender);
\ No newline at end of file
diff --git a/Wallet/UnarchiveItemHandler.cs b/Wallet/UnarchiveItemHandler.cs
index 239f585..f0febe2 100644
--- a/Wallet/UnarchiveItemHandler.cs
+++ b/Wallet/UnarchiveItemHandler.cs
@@ -1,12 +1,11 @@
-using Wallet.Data;
-using Microsoft.EntityFrameworkCore;
-using System.Threading;
-using Toolkit.Foundation;
+using Toolkit.Foundation;
namespace Wallet;
public class UnarchiveItemHandler(IDecoratorService
- > decoratorService,
- IDbContextFactory dbContextFactory) :
+ ICache
- > cache,
+ IMediator mediator,
+ IPublisher publisher) :
INotificationHandler>
{
public async Task Handle(UnarchiveEventArgs
- args)
@@ -17,12 +16,11 @@ public class UnarchiveItemHandler(IDecoratorService
- > decora
{
(Guid id, string name) = item.Value;
- using WalletContext context = await dbContextFactory.CreateDbContextAsync();
- if (await context.FindAsync(id) is ItemEntry result)
- {
- result.State = 0;
- await context.SaveChangesAsync();
- }
+ await mediator.Handle,
+ bool>(new UpdateEventArgs<(Guid, int)>((id, 0)));
+
+ cache.Add(item);
+ publisher.Publish(Changed.As(item));
}
}
catch
diff --git a/Wallet/UnfavouriteEventArgs.cs b/Wallet/UnfavouriteEventArgs.cs
index 2726426..8d38c35 100644
--- a/Wallet/UnfavouriteEventArgs.cs
+++ b/Wallet/UnfavouriteEventArgs.cs
@@ -1,3 +1,3 @@
namespace Wallet;
-public record UnfavouriteEventArgs(TValue Value);
\ No newline at end of file
+public record UnfavouriteEventArgs(TSender Sender);
\ No newline at end of file
diff --git a/Wallet/UnfavouriteItemHandler.cs b/Wallet/UnfavouriteItemHandler.cs
index 70e309e..876d417 100644
--- a/Wallet/UnfavouriteItemHandler.cs
+++ b/Wallet/UnfavouriteItemHandler.cs
@@ -1,8 +1,10 @@
using Toolkit.Foundation;
namespace Wallet;
+
public class UnfavouriteItemHandler(IDecoratorService
- > decoratorService,
- IMediator mediator) :
+ IMediator mediator,
+ IPublisher publisher) :
INotificationHandler>
{
public async Task Handle(UnfavouriteEventArgs
- args)
@@ -13,6 +15,8 @@ public class UnfavouriteItemHandler(IDecoratorService
- > deco
{
(Guid id, string name) = item.Value;
await mediator.Handle, bool>(new UpdateEventArgs<(Guid, int)>((id, 0)));
+
+ publisher.Publish(Changed.As(item));
}
}
catch
diff --git a/Wallet/UpdateItemStateHandler.cs b/Wallet/UpdateItemStateHandler.cs
index 5cf35ab..9ef4641 100644
--- a/Wallet/UpdateItemStateHandler.cs
+++ b/Wallet/UpdateItemStateHandler.cs
@@ -12,15 +12,12 @@ public class UpdateItemStateHandler(IDbContextFactory dbContextFa
{
if (args.Value is (Guid id, int state))
{
- await Task.Run(async () =>
+ using WalletContext context = await dbContextFactory.CreateDbContextAsync(cancellationToken);
+ if (await context.FindAsync(id) is ItemEntry result)
{
- using WalletContext context = await dbContextFactory.CreateDbContextAsync(cancellationToken);
- if (await context.FindAsync(id) is ItemEntry result)
- {
- result.State = state;
- await context.SaveChangesAsync();
- }
- }, cancellationToken);
+ result.State = state;
+ await context.SaveChangesAsync(cancellationToken);
+ }
}
return false;
diff --git a/Wallet/WalletNavigationViewModel.cs b/Wallet/WalletNavigationViewModel.cs
index 8b5d2f0..9e5e64e 100644
--- a/Wallet/WalletNavigationViewModel.cs
+++ b/Wallet/WalletNavigationViewModel.cs
@@ -46,10 +46,10 @@ public partial class WalletNavigationViewModel :
public Task Handle(OpenedEventArgs args)
{
- Add("All");
- Add("Starred");
- Add("Archive");
- Add("Categories");
+ Add("All", 0);
+ Add("Starred", 0);
+ Add("Archive", 0);
+ Add("Categories", 0);
Opened = true;
return Task.CompletedTask;