From 998c1ff756f253709022a5d6205ed5f5ce6dd831 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Fi=C5=A1era?= Date: Sun, 16 May 2021 09:41:08 +0200 Subject: [PATCH] #343 - List of month incomes. --- src/Money.Blazor.Host/Pages/Overview.razor | 20 ++- src/Money.Blazor.Host/Pages/Overview.razor.cs | 6 + src/Money.Blazor.Host/Pages/OverviewMonth.cs | 3 + .../Pages/OverviewMonthIncome.razor | 58 ++++++ .../Pages/OverviewMonthIncome.razor.cs | 170 ++++++++++++++++++ src/Money.Blazor.Host/Services/Navigator.cs | 6 + .../Services/NavigatorUrl.cs | 3 + 7 files changed, 265 insertions(+), 1 deletion(-) create mode 100644 src/Money.Blazor.Host/Pages/OverviewMonthIncome.razor create mode 100644 src/Money.Blazor.Host/Pages/OverviewMonthIncome.razor.cs diff --git a/src/Money.Blazor.Host/Pages/Overview.razor b/src/Money.Blazor.Host/Pages/Overview.razor index e05ad112..1a73dbff 100644 --- a/src/Money.Blazor.Host/Pages/Overview.razor +++ b/src/Money.Blazor.Host/Pages/Overview.razor @@ -1,6 +1,10 @@ @typeparam T - + + <ButtonContent> + <ExpenseCreateButton OnClick="CreateModal.Show" /> + </ButtonContent> + @@ -8,6 +12,20 @@
+ @{ + var incomeUrl = ListIncomeUrl(); + } + @if (incomeUrl != null) + { + + } @if (Items != null) { if (Items.Count > 0) diff --git a/src/Money.Blazor.Host/Pages/Overview.razor.cs b/src/Money.Blazor.Host/Pages/Overview.razor.cs index a270e084..e2a39f04 100644 --- a/src/Money.Blazor.Host/Pages/Overview.razor.cs +++ b/src/Money.Blazor.Host/Pages/Overview.razor.cs @@ -45,6 +45,9 @@ public partial class Overview : [Inject] public Interop Interop { get; set; } + [Inject] + public Navigator Navigator { get; set; } + protected string Title { get; set; } protected string SubTitle { get; set; } @@ -96,6 +99,9 @@ protected virtual IKey CreateSelectedCategoryFromParameters() protected virtual T CreateSelectedItemFromParameters() => throw Ensure.Exception.NotImplemented($"Missing override for method '{nameof(CreateSelectedItemFromParameters)}'."); + protected virtual string ListIncomeUrl() + => null; + protected async void Reload() { await PagingContext.LoadAsync(0); diff --git a/src/Money.Blazor.Host/Pages/OverviewMonth.cs b/src/Money.Blazor.Host/Pages/OverviewMonth.cs index 14a11cb0..867c7a96 100644 --- a/src/Money.Blazor.Host/Pages/OverviewMonth.cs +++ b/src/Money.Blazor.Host/Pages/OverviewMonth.cs @@ -45,5 +45,8 @@ protected override IQuery> CreateItemsQuery(int pageI protected override bool IsContained(DateTime when) => SelectedPeriod == when; + + protected override string ListIncomeUrl() + => Navigator.UrlOverviewIncomes(SelectedPeriod); } } diff --git a/src/Money.Blazor.Host/Pages/OverviewMonthIncome.razor b/src/Money.Blazor.Host/Pages/OverviewMonthIncome.razor new file mode 100644 index 00000000..26a75bb5 --- /dev/null +++ b/src/Money.Blazor.Host/Pages/OverviewMonthIncome.razor @@ -0,0 +1,58 @@ +@page "/{Year:int}/{Month:int}/overview/incomes" + + + <ButtonContent> + <IncomeCreateButton OnClick="CreateModal.Show" /> + </ButtonContent> + + + + + + +
+ + + + @if (Items != null) + { + if (Items.Count > 0) + { + +
+ +
+ + @foreach (var item in Items) + { +
+
+

@CurrencyFormatter.Format(item.Amount)

+

@item.When.ToShortDateString()

+

@item.Description

+
+
+ +
+
+
+ } +
+
+ + + } + else + { + + } + } +
+
diff --git a/src/Money.Blazor.Host/Pages/OverviewMonthIncome.razor.cs b/src/Money.Blazor.Host/Pages/OverviewMonthIncome.razor.cs new file mode 100644 index 00000000..9f1ffa63 --- /dev/null +++ b/src/Money.Blazor.Host/Pages/OverviewMonthIncome.razor.cs @@ -0,0 +1,170 @@ +using Microsoft.AspNetCore.Components; +using Money.Commands; +using Money.Components; +using Money.Events; +using Money.Models; +using Money.Models.Loading; +using Money.Models.Queries; +using Money.Models.Sorting; +using Money.Services; +using Neptuo.Commands; +using Neptuo.Events; +using Neptuo.Events.Handlers; +using Neptuo.Queries; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Money.Pages +{ + public partial class OverviewMonthIncome : IDisposable, + IEventHandler, + IEventHandler, + IEventHandler + { + public CurrencyFormatter CurrencyFormatter { get; private set; } + + [Inject] + public ICommandDispatcher Commands { get; set; } + + [Inject] + public IEventHandlerCollection EventHandlers { get; set; } + + [Inject] + public IQueryDispatcher Queries { get; set; } + + [Inject] + public Interop Interop { get; set; } + + [Inject] + public Navigator Navigator { get; set; } + + [Parameter] + public int Year { get; set; } + + [Parameter] + public int Month { get; set; } + + protected MonthModel MonthModel { get; set; } + + protected List Items { get; set; } + protected IncomeOverviewModel SelectedItem { get; set; } + + protected IncomeCreate CreateModal { get; set; } + + protected LoadingContext Loading { get; } = new LoadingContext(); + protected SortDescriptor SortDescriptor { get; set; } = new SortDescriptor(IncomeOverviewSortType.ByWhen, SortDirection.Descending); + protected PagingContext PagingContext { get; set; } + + protected IncomeOverviewModel Selected { get; set; } + protected string DeleteMessage { get; set; } + protected Confirm DeleteConfirm { get; set; } + + protected override async Task OnInitializedAsync() + { + PagingContext = new PagingContext(LoadDataAsync, Loading); + + BindEvents(); + + MonthModel = new MonthModel(Year, Month); + + CurrencyFormatter = new CurrencyFormatter(await Queries.QueryAsync(new ListAllCurrency())); + Reload(); + } + + protected async void Reload() + { + await PagingContext.LoadAsync(0); + StateHasChanged(); + } + + protected async Task LoadDataAsync() + { + await Interop.ScrollToTopAsync(); + + List models = await Queries.QueryAsync(new ListMonthIncome(MonthModel, SortDescriptor, PagingContext.CurrentPageIndex)); + if (models.Count == 0) + return PagingLoadStatus.EmptyPage; + + Items = models; + return Items.Count == 10 ? PagingLoadStatus.HasNextPage : PagingLoadStatus.LastPage; + } + + protected async void OnSortChanged() + { + await PagingContext.LoadAsync(0); + StateHasChanged(); + } + + protected void OnActionClick(IncomeOverviewModel model, ModalDialog modal) + { + SelectedItem = model; + modal.Show(); + StateHasChanged(); + } + + protected void OnDeleteClick(IncomeOverviewModel model) + { + Selected = model; + DeleteMessage = $"Do you really want to delete income '{model.Description}'?"; + DeleteConfirm.Show(); + StateHasChanged(); + } + + protected async void OnDeleteConfirmed() + { + await Commands.HandleAsync(new DeleteIncome(Selected.Key)); + StateHasChanged(); + } + + protected IncomeOverviewModel FindModel(IEvent payload) + => Items.FirstOrDefault(o => o.Key.Equals(payload.AggregateKey)); + + public void Dispose() + => UnBindEvents(); + + #region Events + + private void BindEvents() + { + EventHandlers + .Add(this) + .Add(this) + .Add(this); + } + + private void UnBindEvents() + { + EventHandlers + .Remove(this) + .Remove(this) + .Remove(this); + } + + Task IEventHandler.HandleAsync(IncomeCreated payload) + { + if (MonthModel == payload.When) + Reload(); + + return Task.CompletedTask; + } + + Task IEventHandler.HandleAsync(IncomeDeleted payload) + { + Reload(); + return Task.CompletedTask; + } + + Task IEventHandler.HandleAsync(PulledToRefresh payload) + { + payload.IsHandled = true; + _ = LoadDataAsync(); + return Task.CompletedTask; + } + + #endregion + } +} diff --git a/src/Money.Blazor.Host/Services/Navigator.cs b/src/Money.Blazor.Host/Services/Navigator.cs index dd4a9163..853bd67e 100644 --- a/src/Money.Blazor.Host/Services/Navigator.cs +++ b/src/Money.Blazor.Host/Services/Navigator.cs @@ -37,6 +37,9 @@ public void Dispose() manager.LocationChanged -= OnLocationChanged; } + public string UrlCurrent() + => manager.Uri; + private void OnLocationChanged(object sender, LocationChangedEventArgs e) => LocationChanged?.Invoke(e.Location); @@ -61,6 +64,9 @@ public void OpenSummary(MonthModel month) public void OpenOverview(MonthModel month) => manager.NavigateTo(UrlOverview(month)); + public void OpenOverviewIncomes(MonthModel month) + => manager.NavigateTo(UrlOverviewIncomes(month)); + public void OpenOverview(MonthModel month, IKey categoryKey) => manager.NavigateTo(UrlOverview(month, categoryKey)); diff --git a/src/Money.Blazor.Host/Services/NavigatorUrl.cs b/src/Money.Blazor.Host/Services/NavigatorUrl.cs index 6ec538ee..4ba259aa 100644 --- a/src/Money.Blazor.Host/Services/NavigatorUrl.cs +++ b/src/Money.Blazor.Host/Services/NavigatorUrl.cs @@ -22,6 +22,9 @@ public string UrlSummary(MonthModel month) public string UrlOverview(MonthModel month) => $"/{month.Year}/{month.Month}/overview"; + public string UrlOverviewIncomes(MonthModel month) + => $"/{month.Year}/{month.Month}/overview/incomes"; + public string UrlOverview(YearModel year) => $"/{year.Year}/overview";