Compare commits

...

3 Commits

Author SHA1 Message Date
troogs
935f026c75 Fix and harden prospect creation against Blazor runtime crashes
All checks were successful
Build And Push Dev Docker Image / docker (push) Successful in 3m3s
- Handle empty numeric input safely with nullable integer binding.

- Add semaphore locks to prevent double-click invocation errors on mobile.

- Implement global exception handling and user notifications for prospect operations.
2026-05-10 19:47:39 +02:00
troogs
e1c57967e4 Fix EditProspectDialog and Prospects: prevent multiple modal openings during save and create operations 2026-05-10 19:40:06 +02:00
troogs
c702e8dbd5 Fix EditProspectDialog: update NumericEdit to handle nullable Foodsharing-ID 2026-05-10 19:40:00 +02:00
3 changed files with 63 additions and 16 deletions

View File

@@ -11,7 +11,7 @@
<div class="col"> <div class="col">
<Field> <Field>
<FieldLabel>Foodsharing-ID</FieldLabel> <FieldLabel>Foodsharing-ID</FieldLabel>
<NumericEdit TValue="int" @bind-Value="Prospect.FsId"></NumericEdit> <NumericEdit TValue="int?" Value="Prospect.FsId" ValueChanged="@((int? v) => Prospect.FsId = v ?? 0)"></NumericEdit>
</Field> </Field>
</div> </div>
</div> </div>

View File

@@ -82,24 +82,53 @@ namespace FoodsharingSiegen.Server.Dialogs
#region Private Method SaveClick #region Private Method SaveClick
private bool _isSaving;
/// <summary> /// <summary>
/// Saves the click (a. beging, 31.05.2022) /// Saves the click (a. beging, 31.05.2022)
/// </summary> /// </summary>
private async Task SaveClick() private async Task SaveClick()
{
if (_isSaving) return;
_isSaving = true;
try
{ {
if (IsUpdateMode) if (IsUpdateMode)
{ {
var updateR = await ProspectService.UpdateAsync(Prospect); var updateR = await ProspectService.UpdateAsync(Prospect);
if (updateR.Success && OnSuccess != null) await OnSuccess.Invoke(); if (updateR.Success)
{
if (OnSuccess != null) await OnSuccess.Invoke();
await ModalService.Hide();
}
else
{
await Notification.Error(updateR.Exception?.Message ?? "Unbekannter Fehler beim Speichern.", "Fehler");
}
} }
else else
{ {
var addR = await ProspectService.AddProspectAsync(Prospect); var addR = await ProspectService.AddProspectAsync(Prospect);
if (addR.Success && OnSuccess != null) await OnSuccess.Invoke(); if (addR.Success)
} {
if (OnSuccess != null) await OnSuccess.Invoke();
await ModalService.Hide(); await ModalService.Hide();
} }
else
{
await Notification.Error(addR.Exception?.Message ?? "Unbekannter Fehler beim Hinzufügen.", "Fehler");
}
}
}
catch (Exception ex)
{
await Notification.Error(ex.Message, "Systemfehler");
}
finally
{
_isSaving = false;
}
}
#endregion #endregion
} }

View File

@@ -56,14 +56,25 @@ namespace FoodsharingSiegen.Server.Pages
#region Private Method CreateProspectAsync #region Private Method CreateProspectAsync
private bool _isOpeningModal;
/// <summary> /// <summary>
/// Asynchronously creates a new prospect by displaying the AddProspectModal dialog and refreshing the prospect list. /// Asynchronously creates a new prospect by displaying the AddProspectModal dialog and refreshing the prospect list.
/// </summary> /// </summary>
/// <returns>A task that represents the asynchronous operation.</returns> /// <returns>A task that represents the asynchronous operation.</returns>
private async Task CreateProspectAsync() private async Task CreateProspectAsync()
{
if (_isOpeningModal) return;
_isOpeningModal = true;
try
{ {
await EditProspectDialog.ShowAsync(ModalService, LoadProspects); await EditProspectDialog.ShowAsync(ModalService, LoadProspects);
} }
finally
{
_isOpeningModal = false;
}
}
#endregion #endregion
@@ -88,6 +99,8 @@ namespace FoodsharingSiegen.Server.Pages
/// Loads the prospects (a. beging, 11.04.2022) /// Loads the prospects (a. beging, 11.04.2022)
/// </summary> /// </summary>
private async Task LoadProspects() private async Task LoadProspects()
{
try
{ {
var parameter = new GetProspectsParameter var parameter = new GetProspectsParameter
{ {
@@ -99,6 +112,11 @@ namespace FoodsharingSiegen.Server.Pages
await InvokeAsync(StateHasChanged); await InvokeAsync(StateHasChanged);
} }
catch (Exception ex)
{
await Notification.Error(ex.Message, "Fehler beim Laden");
}
}
#endregion #endregion
} }