@inherits LocalizableComponentBase @* Asks before an act that takes words or a password: what it does, then the fields it needs, then a confirm button. The staff's acts (Staff) take a note only the staff read (data-moderate-note), a warning the persona is told (data-moderate-warning) and, to delete, the administrator's own password (data-admin-password); the dialog is data-moderate-confirm="{act}". A login's own deletions take its password (data-own-password) in data-own-confirm="{act}". OnConfirm does the act: a failure stays in the dialog (a wrong password is typed again), a success closes it. *@ @Question
@if (Text is { Length: > 0 }) {

@Text

} @if (AskNote) { } @if (AskWarning) { } @if (AskPassword) { }
@Localizer["Cancel"] @if (isActing) { } @ConfirmText
@code { /// The question the dialog asks, its heading. [Parameter, EditorRequired] public string Question { get; set; } /// What the act does, in words. [Parameter] public string Text { get; set; } [Parameter, EditorRequired] public string ConfirmText { get; set; } /// The confirm button shows as a danger (it deletes or cuts something off). [Parameter] public bool Danger { get; set; } /// The act's name in the dialog's data attribute (silence, persona-delete, ...). [Parameter, EditorRequired] public string Act { get; set; } /// A staff act (data-moderate-confirm, the administrator's password) or the login's own (data-own-confirm). [Parameter] public bool Staff { get; set; } [Parameter] public bool AskNote { get; set; } [Parameter] public bool AskWarning { get; set; } /// Who reads the warning, when it isn't simply the persona (an account elsewhere is told nothing). [Parameter] public string WarningHint { get; set; } [Parameter] public bool AskPassword { get; set; } /// Does the act with what was typed; an invalid result stays in the dialog, a valid one closes it. [Parameter, EditorRequired] public Func> OnConfirm { get; set; } [Parameter] public EventCallback OnClosed { get; set; } /// What was typed: the note and the warning trimmed, null when empty; the password as typed. public sealed record Answer(string Note, string Warning, string Password); string note; string warning; string password; string error; bool isActing; protected override void OnInitialized() => IsLoading = false; async Task Confirm() { error = default; isActing = true; var result = await OnConfirm(new Answer(Trimmed(note), Trimmed(warning), password)); isActing = false; if (result.IsInvalid) { // a cancelled request says nothing; anything else is said here, where it can be fixed if (result.StatusCode is not 410) error = result.ErrorMessage; password = default; return; } await OnClosed.InvokeAsync(); } static string Trimmed(string text) => string.IsNullOrWhiteSpace(text) ? null : text.Trim(); Task Cancel() => OnClosed.InvokeAsync(); Task Closed(bool open) => open ? Task.CompletedTask : OnClosed.InvokeAsync(); }