Files
RpgRoller/RpgRoller/Components/Pages/HomeControls/CharacterFormModal.razor

111 lines
3.5 KiB
Plaintext

@using System.Diagnostics.CodeAnalysis
@using RpgRoller.Components.Pages
@using RpgRoller.Contracts
@attribute [ExcludeFromCodeCoverage]
@if (Visible)
{
<div class="modal-overlay" role="presentation">
<section class="modal-card" role="dialog" aria-modal="true" aria-label="@Title">
<h2>@Title</h2>
@if (!string.IsNullOrWhiteSpace(FormState.ErrorMessage))
{
<p class="form-error">@FormState.ErrorMessage</p>
}
<form class="form-grid" @onsubmit="SubmitAsync" @onsubmit:preventDefault>
<label for="@NameInputId">Character name</label>
<input id="@NameInputId" @bind="FormState.Model.Name" @bind:event="oninput" />
@if (FormState.Errors.TryGetValue("name", out var nameError))
{
<p class="field-error">@nameError</p>
}
<label for="@CampaignInputId">Campaign</label>
<select id="@CampaignInputId" @bind="FormState.Model.CampaignId">
<option value="">Select campaign</option>
@foreach (var campaign in Campaigns)
{
<option value="@campaign.Id">@campaign.Name</option>
}
</select>
@if (FormState.Errors.TryGetValue("campaignId", out var campaignError))
{
<p class="field-error">@campaignError</p>
}
<div class="inline-actions">
<button type="submit" disabled="@IsMutating">@SubmitLabel</button>
<button type="button" class="ghost" @onclick="CancelRequested">Cancel</button>
</div>
</form>
</section>
</div>
}
@code {
private FormState<CharacterFormModel> FormState { get; } = new();
private int AppliedFormVersion { get; set; } = -1;
[Parameter]
public bool Visible { get; set; }
[Parameter]
public string Title { get; set; } = "Character";
[Parameter]
public string SubmitLabel { get; set; } = "Save";
[Parameter]
public string NameInputId { get; set; } = "character-name";
[Parameter]
public string CampaignInputId { get; set; } = "character-campaign";
[Parameter]
public CharacterFormModel InitialModel { get; set; } = new();
[Parameter]
public int FormVersion { get; set; }
[Parameter]
public IReadOnlyList<CampaignSummary> Campaigns { get; set; } = [];
[Parameter]
public bool IsMutating { get; set; }
[Parameter]
public Func<CharacterFormModel, Task<FormSubmissionResult>> SubmitRequested { get; set; } = _ => Task.FromResult(new FormSubmissionResult());
[Parameter]
public EventCallback CancelRequested { get; set; }
protected override void OnParametersSet()
{
if (!Visible || FormVersion == AppliedFormVersion)
{
return;
}
FormState.Model.Name = InitialModel.Name;
FormState.Model.CampaignId = InitialModel.CampaignId;
FormState.ResetValidation();
AppliedFormVersion = FormVersion;
}
private async Task SubmitAsync()
{
FormState.ResetValidation();
var result = await SubmitRequested.Invoke(new CharacterFormModel
{
Name = FormState.Model.Name,
CampaignId = FormState.Model.CampaignId
});
foreach (var (key, value) in result.Errors)
{
FormState.Errors[key] = value;
}
FormState.ErrorMessage = result.ErrorMessage;
}
}