AccountingNext/Schaad.Accounting.UI/Components/Pages/Controls/AccountSelector.razor.cs
Claudio Schaad 60f01d437c PR U-1: AccountSelector reacts to Accounts arriving late
Move the SelectedAccount = Accounts.FirstOrDefault(...) lookup from
OnInitialized to OnParametersSet so the preselection tracks the
Accounts list arriving asynchronously (every caller now passes []
first and hydrates after an await). Idempotent — the OnSelectedChanged
callback path returns the same AccountId back and the parent re-render
lookup finds the same account.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-03 19:17:41 +02:00

39 lines
No EOL
1.4 KiB
C#

using Microsoft.AspNetCore.Components;
using Microsoft.FluentUI.AspNetCore.Components;
using Schaad.Accounting.Models;
namespace Schaad.Accounting.UI.Components.Pages.Controls;
public partial class AccountSelector : ComponentBase
{
[Parameter] public required string? AccountId { get; set; }
[Parameter] public required IReadOnlyList<Account> Accounts { get; set; }
[Parameter] public EventCallback<string> AccountIdChanged { get; set; }
private Account? SelectedAccount { get; set; }
// OnParametersSet, not OnInitialized: OnInitialized fires once, but callers now
// pass an empty Accounts list on first render and hydrate it after an await.
// OnParametersSet re-runs the lookup whenever Accounts or AccountId change, so the
// preselection tracks late-arriving data.
protected override void OnParametersSet()
{
SelectedAccount = Accounts.FirstOrDefault(account => account.Id == AccountId);
}
private async Task OnSearchAsync(OptionsSearchEventArgs<Account> e)
{
e.Items = Accounts.Where(i => i.Name.Contains(e.Text, StringComparison.OrdinalIgnoreCase))
.OrderBy(i => i.Name);
await Task.CompletedTask;
}
public async Task OnSelectedChanged(IEnumerable<Account>? s)
{
SelectedAccount = s?.FirstOrDefault();
AccountId = SelectedAccount?.Id;
await AccountIdChanged.InvokeAsync(AccountId);
}
}