feat(ui): constrain decimal input and add stacked timed toasts with uniform actions
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
@inject ToastService Toasts
|
||||
@inject ReportingPeriod Period
|
||||
@page "/accounts/{AccountId:int}"
|
||||
@inject IAccountService AccountService
|
||||
@@ -9,21 +10,7 @@
|
||||
|
||||
<div class="container-fluid">
|
||||
<OperationNotice Result="fileResult" />
|
||||
@if (fileBusy) { <p role="status" aria-live="polite">Dateiaktion läuft … Bitte warten.</p> }
|
||||
|
||||
@if (lastSaved != null)
|
||||
{
|
||||
<div class="alert alert-success" role="status" aria-live="polite">
|
||||
@lastSaved.Kind über @FormatAmount(lastSaved.Amount) @(lastSaved.Edited ? "aktualisiert" : "gespeichert").
|
||||
</div>
|
||||
}
|
||||
@if (savedOutsideYear.HasValue)
|
||||
{
|
||||
<div class="alert alert-info" role="status">
|
||||
Die Buchung wurde im Jahr @savedOutsideYear gespeichert und liegt außerhalb der aktuellen Ansicht.
|
||||
<button class="btn btn-outline-primary" @onclick="ShowSavedYear">Buchung im Jahr @savedOutsideYear anzeigen</button>
|
||||
</div>
|
||||
}
|
||||
@if (account == null)
|
||||
{
|
||||
<div class="text-center py-5">
|
||||
@@ -41,21 +28,21 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex align-items-center gap-2 py-3 flex-wrap">
|
||||
<div class="action-toolbar">
|
||||
<button class="btn btn-secondary btn-nav" @onclick="NavigateBack">
|
||||
<i class="bi bi-arrow-left"></i> Zurück
|
||||
<i class="bi bi-arrow-left"></i><span>Zurück</span>
|
||||
</button>
|
||||
<button class="btn btn-success btn-nav" @onclick="() => showAddEntry = true">
|
||||
<i class="bi bi-plus-lg"></i> Einnahme oder Ausgabe erfassen
|
||||
<i class="bi bi-plus-lg"></i> <span>Einnahme oder<br /> Ausgabe erfassen</span>
|
||||
</button>
|
||||
<button class="btn btn-info btn-nav" @onclick="() => showAddTransfer = true">
|
||||
<i class="bi bi-arrow-left-right"></i> Geld zwischen Konten verschieben
|
||||
<i class="bi bi-arrow-left-right"></i> <span>Geld zwischen<br /> Konten verschieben</span>
|
||||
</button>
|
||||
<button class="btn btn-dark btn-nav" @onclick="HandleExport" disabled="@fileBusy">
|
||||
<i class="bi bi-file-earmark-pdf"></i> Als PDF speichern
|
||||
<i class="bi bi-file-earmark-pdf"></i> <span>Als PDF<br /> speichern</span>
|
||||
</button>
|
||||
<button class="btn btn-nav btn-primary" @onclick="OpenYearFilterDialog">
|
||||
<i class="bi bi-funnel"></i> @GetFilterLabel()
|
||||
<i class="bi bi-funnel"></i><span>@GetFilterLabel()</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using Duempelkas.App.Services;
|
||||
using Duempelkas.App.Services.Models;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
@@ -10,6 +11,10 @@ public partial class AccountDetail
|
||||
[Parameter]
|
||||
public int AccountId { get; set; }
|
||||
|
||||
[SupplyParameterFromQuery(Name = "jahr")]
|
||||
public int? QueryYear { get; set; }
|
||||
private int? previousQueryYear;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Fields
|
||||
@@ -53,6 +58,8 @@ public partial class AccountDetail
|
||||
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
if (QueryYear.HasValue && QueryYear != previousQueryYear) selectedYear = QueryYear;
|
||||
previousQueryYear = QueryYear;
|
||||
await LoadAll();
|
||||
}
|
||||
|
||||
@@ -115,6 +122,12 @@ public partial class AccountDetail
|
||||
await LoadAll();
|
||||
lastSaved = saved;
|
||||
savedOutsideYear = selectedYear.HasValue && selectedYear.Value != saved.Date.Year ? saved.Date.Year : null;
|
||||
var nav = Navigation;
|
||||
var period = Period;
|
||||
var accountId = AccountId;
|
||||
Toasts.Show($"{saved.Kind} über {FormatAmount(saved.Amount)} {(saved.Edited ? "aktualisiert" : "gespeichert")}.", ToastKind.Success,
|
||||
actionLabel: savedOutsideYear.HasValue ? $"Buchung im Jahr {saved.Date.Year} anzeigen" : null,
|
||||
action: savedOutsideYear.HasValue ? () => { period.Year = saved.Date.Year; nav.NavigateTo($"/accounts/{accountId}?jahr={saved.Date.Year}"); return Task.CompletedTask; } : null);
|
||||
showAddEntry = false;
|
||||
showAddTransfer = false;
|
||||
editingEntry = null;
|
||||
@@ -187,6 +200,7 @@ public partial class AccountDetail
|
||||
private async Task HandleExport()
|
||||
{
|
||||
if (fileBusy) return;
|
||||
var busyToast = Toasts.Show("Dateiaktion läuft … Bitte warten.", persistent: true);
|
||||
fileBusy = true;
|
||||
fileResult = null;
|
||||
try
|
||||
@@ -199,12 +213,13 @@ public partial class AccountDetail
|
||||
|
||||
}
|
||||
catch (Exception ex) { fileResult = FileOperationResult.Error(ex); }
|
||||
finally { fileBusy = false; }
|
||||
finally { fileBusy = false; Toasts.Dismiss(busyToast); }
|
||||
}
|
||||
|
||||
private async Task HandleOpenSavedPdf()
|
||||
{
|
||||
if (fileBusy) return;
|
||||
var busyToast = Toasts.Show("Dateiaktion läuft … Bitte warten.", persistent: true);
|
||||
fileBusy = true;
|
||||
fileResult = null;
|
||||
try
|
||||
@@ -218,7 +233,7 @@ public partial class AccountDetail
|
||||
|
||||
}
|
||||
catch (Exception ex) { fileResult = FileOperationResult.Error(ex); }
|
||||
finally { fileBusy = false; }
|
||||
finally { fileBusy = false; Toasts.Dismiss(busyToast); }
|
||||
}
|
||||
|
||||
private void CancelOpenSavedPdf()
|
||||
|
||||
Reference in New Issue
Block a user