Skip to content

Commit

Permalink
#343 - List of month incomes.
Browse files Browse the repository at this point in the history
  • Loading branch information
maraf committed May 16, 2021
1 parent dd5c505 commit 998c1ff
Show file tree
Hide file tree
Showing 7 changed files with 265 additions and 1 deletion.
20 changes: 19 additions & 1 deletion src/Money.Blazor.Host/Pages/Overview.razor
Original file line number Diff line number Diff line change
@@ -1,13 +1,31 @@
@typeparam T

<Money.Components.Title Icon="calendar" Main="@Title" Sub="@SubTitle" ButtonText="New Expense" ButtonClick="@(() => { CreateModal.Show(); StateHasChanged(); })" />
<Title Icon="calendar" Main="@Title" Sub="@SubTitle">
<ButtonContent>
<ExpenseCreateButton OnClick="CreateModal.Show" />
</ButtonContent>
</Title>
<ExceptionPanel />

<OutcomeCreate @ref="CreateModal" CategoryKey="@CategoryKey" />
<Confirm @ref="DeleteConfirm" Message="@DeleteMessage" OnConfirmed="@OnDeleteConfirmed" />

<div class="overview">
<Loading Context="@Loading" IsOverlay="true">
@{
var incomeUrl = ListIncomeUrl();
}
@if (incomeUrl != null)
{
<ul class="nav nav-pills float-left">
<li>
<a class="nav-link" href="@incomeUrl">Incomes</a>
</li>
<li>
<a class="nav-link active" href="@Navigator.UrlCurrent()">Expenses</a>
</li>
</ul>
}
@if (Items != null)
{
if (Items.Count > 0)
Expand Down
6 changes: 6 additions & 0 deletions src/Money.Blazor.Host/Pages/Overview.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ public partial class Overview<T> :
[Inject]
public Interop Interop { get; set; }

[Inject]
public Navigator Navigator { get; set; }

protected string Title { get; set; }
protected string SubTitle { get; set; }

Expand Down Expand Up @@ -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);
Expand Down
3 changes: 3 additions & 0 deletions src/Money.Blazor.Host/Pages/OverviewMonth.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,8 @@ protected override IQuery<List<OutcomeOverviewModel>> CreateItemsQuery(int pageI

protected override bool IsContained(DateTime when)
=> SelectedPeriod == when;

protected override string ListIncomeUrl()
=> Navigator.UrlOverviewIncomes(SelectedPeriod);
}
}
58 changes: 58 additions & 0 deletions src/Money.Blazor.Host/Pages/OverviewMonthIncome.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
@page "/{Year:int}/{Month:int}/overview/incomes"

<Title Icon="calendar" Main="@($"Incomes in {MonthModel}")" Sub="List of each single income in selected month">
<ButtonContent>
<IncomeCreateButton OnClick="CreateModal.Show" />
</ButtonContent>
</Title>
<ExceptionPanel />

<IncomeCreate @ref="CreateModal" />
<Confirm @ref="DeleteConfirm" Message="@DeleteMessage" OnConfirmed="@OnDeleteConfirmed" />

<div class="overview">
<Loading Context="@Loading" IsOverlay="true">
<ul class="nav nav-pills float-left">
<li>
<a class="nav-link active" href="@Navigator.UrlOverviewIncomes(MonthModel)">Incomes</a>
</li>
<li>
<a class="nav-link" href="@Navigator.UrlOverview(MonthModel)">Expenses</a>
</li>
</ul>

@if (Items != null)
{
if (Items.Count > 0)
{
<SortButton TType="@IncomeOverviewSortType" @bind-Current="@SortDescriptor" Changed="@OnSortChanged" />
<div class="clear"></div>

<div class="cards">
<CascadingValue Value="@this">
@foreach (var item in Items)
{
<div class="outcome-card">
<div class="data">
<h2 class="amount">@CurrencyFormatter.Format(item.Amount)</h2>
<p class="when">@item.When.ToShortDateString()</p>
<p class="description">@item.Description</p>
</div>
<div class="controls">
<IconButton Icon="trash-alt" ToolTip="Delete" Click="@(() => OnDeleteClick(item))" />
</div>
<div class="clear"></div>
</div>
}
</CascadingValue>
</div>

<Paging Context="@PagingContext" />
}
else
{
<Alert Title="No data." Message="Let's add some incomes." Mode="@AlertMode.Warning" />
}
}
</Loading>
</div>
170 changes: 170 additions & 0 deletions src/Money.Blazor.Host/Pages/OverviewMonthIncome.razor.cs
Original file line number Diff line number Diff line change
@@ -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<IncomeCreated>,
IEventHandler<IncomeDeleted>,
IEventHandler<PulledToRefresh>
{
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<IncomeOverviewModel> Items { get; set; }
protected IncomeOverviewModel SelectedItem { get; set; }

protected IncomeCreate CreateModal { get; set; }

protected LoadingContext Loading { get; } = new LoadingContext();
protected SortDescriptor<IncomeOverviewSortType> SortDescriptor { get; set; } = new SortDescriptor<IncomeOverviewSortType>(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<PagingLoadStatus> LoadDataAsync()
{
await Interop.ScrollToTopAsync();

List<IncomeOverviewModel> 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<IncomeCreated>(this)
.Add<IncomeDeleted>(this)
.Add<PulledToRefresh>(this);
}

private void UnBindEvents()
{
EventHandlers
.Remove<IncomeCreated>(this)
.Remove<IncomeDeleted>(this)
.Remove<PulledToRefresh>(this);
}

Task IEventHandler<IncomeCreated>.HandleAsync(IncomeCreated payload)
{
if (MonthModel == payload.When)
Reload();

return Task.CompletedTask;
}

Task IEventHandler<IncomeDeleted>.HandleAsync(IncomeDeleted payload)
{
Reload();
return Task.CompletedTask;
}

Task IEventHandler<PulledToRefresh>.HandleAsync(PulledToRefresh payload)
{
payload.IsHandled = true;
_ = LoadDataAsync();
return Task.CompletedTask;
}

#endregion
}
}
6 changes: 6 additions & 0 deletions src/Money.Blazor.Host/Services/Navigator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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));

Expand Down
3 changes: 3 additions & 0 deletions src/Money.Blazor.Host/Services/NavigatorUrl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand Down

0 comments on commit 998c1ff

Please sign in to comment.