AddressSelector & Blazorise

This commit is contained in:
Andre Beging
2024-11-07 13:16:00 +01:00
parent 07bd63c450
commit 6091b54b2a
8 changed files with 181 additions and 8 deletions

View File

@@ -9,6 +9,11 @@
<link rel="stylesheet" href="app.css"/>
<link rel="stylesheet" href="Server.styles.css"/>
<link rel="icon" type="image/png" href="favicon.png"/>
<link href="_content/Blazorise.Icons.FontAwesome/v6/css/all.min.css" rel="stylesheet">
<link href="_content/Blazorise/blazorise.css" rel="stylesheet" />
<link href="_content/Blazorise.Bootstrap5/blazorise.bootstrap5.css" rel="stylesheet" />
<HeadOutlet/>
</head>

View File

@@ -0,0 +1,22 @@
@using Server.Data
@using Server.Model
@using Address = Server.Model.Address
<ModalBody>
<DataGrid TItem="Address"
Data="@CustomerData.Instance.Customers.Where(x => !string.IsNullOrWhiteSpace(x.Name) && x.State != RecordState.Deleted)"
Responsive
@bind-SelectedRow="SelectedCustomer"
RowDoubleClicked="SelectedAsync">
<DataGridColumn Field="@nameof(Address.Name)" Caption="Name" Sortable="true" />
<DataGridColumn Field="@nameof(Address.Street)" Caption="Straße" />
<DataGridColumn Field="@nameof(Address.City)" Caption="City" />
</DataGrid>
</ModalBody>
<ModalFooter>
<Button Color="Color.Primary" Clicked="SelectedAsync">Auswählen</Button>
<Button Color="Color.Secondary" Clicked="ModalService.Hide">Abbrechen</Button>
</ModalFooter>

View File

@@ -0,0 +1,85 @@
using Blazorise;
using Microsoft.AspNetCore.Components;
using Server.Data;
using Address = Server.Model.Address;
namespace Server.Components.Dialogs
{
public partial class AddressSelector : ComponentBase
{
#region Dependencies
[Inject]
private IModalService ModalService { get; set; } = null!;
#endregion
#region Parameters
/// <summary>
/// Gets or sets the delegate that will be invoked when an address is selected.
/// </summary>
/// <remarks>
/// This property expects a <see cref="Func{T, TResult}" /> delegate where the input parameter is an <see cref="Address" />
/// and the return type is a <see cref="Task" />. It allows customization of what should happen when a user selects an address
/// from the AddressSelector component.
/// </remarks>
[Parameter]
public Func<Address, Task>? OnSelected { get; set; }
#endregion
#region Private Properties
private Address? SelectedCustomer { get; set; }
#endregion
#region Override SetParametersAsync
//// <inheritdoc />
public override async Task SetParametersAsync(ParameterView parameters)
{
parameters.SetParameterProperties(this);
await CustomerData.LoadAsync();
await base.SetParametersAsync(ParameterView.Empty);
}
#endregion
#region Public Method ShowAsync
/// <summary>
/// Displays the AddressSelector component as a modal dialog asynchronously.
/// </summary>
/// <param name="modalService">The service used to show the modal dialog.</param>
/// <param name="onSelected">The callback to invoke when an address is selected.</param>
/// <returns>
/// A Task that represents the asynchronous operation of showing the modal dialog.
/// </returns>
public static Task ShowAsync(IModalService modalService, Func<Address, Task> onSelected)
{
return modalService.Show<AddressSelector>(builder => { builder.Add(x => x.OnSelected, onSelected); });
}
#endregion
#region Private Method SelectedAsync
/// <summary>
/// Handles the selection of an address asynchronously.
/// Invokes the OnSelected callback with the selected address
/// and hides the modal service upon completion.
/// </summary>
/// <returns>
/// A Task that represents the asynchronous operation.
/// </returns>
private async Task SelectedAsync()
{
if (SelectedCustomer != null && OnSelected != null) await OnSelected.Invoke(SelectedCustomer);
await ModalService.Hide();
}
#endregion
}
}

View File

@@ -1,4 +1,5 @@
@page "/edit/{InvoiceId}"
@using Server.Data
@using Server.Model
@rendermode InteractiveServer
@@ -33,6 +34,27 @@
<InputDate class="form-control" @bind-Value="@Invoice.IssueDate"></InputDate>
</div>
<hr />
@if (Invoice.Customer != null)
{
<div class="card mb-2" style="width: 18rem;">
<div class="card-body">
<h5 class="card-title">@Invoice.Customer.Name</h5>
<p class="card-text">
@Invoice.Customer.Name2<br>
@Invoice.Customer.Street<br>
@Invoice.Customer.Zip - @Invoice.Customer.City<br>
@Invoice.Customer.Phone
</p>
</div>
</div>
}
<button class="btn btn-secondary" @onclick="SelectCustomerAsync">@(Invoice.Customer != null ? "Kunden ändern" : "Kunden auswählen")</button>
<hr />
<div class="mb-3">
<label class="form-label" >Rechnungsnummer</label>
<InputText class="form-control" @bind-Value="@Invoice.InvoiceId" disabled></InputText>
@@ -84,3 +106,5 @@
</div>
</div>
}
<ModalProvider />

View File

@@ -1,7 +1,9 @@
using Microsoft.AspNetCore.Components;
using Blazorise;
using Microsoft.AspNetCore.Components;
using QuestPDF;
using QuestPDF.Fluent;
using QuestPDF.Infrastructure;
using Server.Components.Dialogs;
using Server.Data;
using Server.Model;
@@ -11,6 +13,9 @@ namespace Server.Components.Pages
{
#region Dependencies
[Inject]
private IModalService ModalService { get; set; } = null!;
[Inject]
private NavigationManager NavigationManager { get; set; } = null!;
@@ -18,6 +23,13 @@ namespace Server.Components.Pages
#region Parameters
/// <summary>
/// Gets or sets the identifier for the invoice.
/// </summary>
/// <remarks>
/// This property is used to uniquely identify an invoice.
/// It is a nullable string which allows handling cases where no invoice ID is provided.
/// </remarks>
[Parameter]
public string? InvoiceId { get; set; }
@@ -25,10 +37,10 @@ namespace Server.Components.Pages
#region Private Properties
private InvoiceModel Invoice { get; set; } = new();
private string? AlertMessage { get; set; }
private InvoiceModel Invoice { get; set; } = new();
#endregion
#region Override SetParametersAsync
@@ -149,5 +161,18 @@ namespace Server.Components.Pages
}
#endregion
#region Private Method SelectCustomerAsync
private async Task SelectCustomerAsync()
{
await AddressSelector.ShowAsync(ModalService, async address =>
{
Invoice.Customer = address;
await InvokeAsync(StateHasChanged);
});
}
#endregion
}
}

View File

@@ -8,3 +8,5 @@
@using Microsoft.JSInterop
@using Server
@using Server.Components
@using Blazorise
@using Blazorise.DataGrid

View File

@@ -1,3 +1,6 @@
using Blazorise;
using Blazorise.Bootstrap5;
using Blazorise.Icons.FontAwesome;
using Server.Components;
var builder = WebApplication.CreateBuilder(args);
@@ -6,12 +9,16 @@ var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
builder.Services.AddBlazorise(options => { options.Immediate = true; })
.AddBootstrap5Providers()
.AddFontAwesomeIcons();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error", createScopeForErrors: true);
app.UseExceptionHandler("/Error", true);
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}

View File

@@ -7,6 +7,9 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Blazorise.Bootstrap5" Version="1.6.2" />
<PackageReference Include="Blazorise.DataGrid" Version="1.6.2" />
<PackageReference Include="Blazorise.Icons.FontAwesome" Version="1.6.2" />
<PackageReference Include="QuestPDF" Version="2024.10.2" />
</ItemGroup>