356 lines
11 KiB
C#
356 lines
11 KiB
C#
using System.Diagnostics.CodeAnalysis;
|
|
using Microsoft.AspNetCore.Components;
|
|
using RpgRoller.Contracts;
|
|
|
|
namespace RpgRoller.Components.Pages.HomeControls;
|
|
|
|
[ExcludeFromCodeCoverage]
|
|
public partial class CharacterPanel
|
|
{
|
|
private void OpenCreateSkillModal(Guid? skillGroupId = null)
|
|
{
|
|
var selectedGroup = skillGroupId.HasValue
|
|
? SelectedCharacterSkillGroups.FirstOrDefault(group => group.Id == skillGroupId.Value)
|
|
: null;
|
|
|
|
CreateSkillInitialModel = new()
|
|
{
|
|
Name = string.Empty,
|
|
DiceRollDefinition = selectedGroup?.DiceRollDefinition ?? string.Empty,
|
|
SkillGroupId = selectedGroup?.Id.ToString() ?? string.Empty,
|
|
WildDice = selectedGroup?.WildDice ?? (IsD6 ? 1 : 0),
|
|
AllowFumble = selectedGroup?.AllowFumble ?? IsD6
|
|
};
|
|
|
|
CreateSkillFormVersion++;
|
|
ShowCreateSkillModal = true;
|
|
}
|
|
|
|
private void OpenEditSkillModal(SkillSummary skill)
|
|
{
|
|
EditingSkillId = skill.Id;
|
|
EditSkillInitialModel = new()
|
|
{
|
|
Name = skill.Name,
|
|
DiceRollDefinition = skill.DiceRollDefinition,
|
|
SkillGroupId = skill.SkillGroupId?.ToString() ?? string.Empty,
|
|
WildDice = skill.WildDice,
|
|
AllowFumble = skill.AllowFumble
|
|
};
|
|
|
|
EditSkillFormVersion++;
|
|
ShowEditSkillModal = true;
|
|
}
|
|
|
|
private void CloseSkillModals()
|
|
{
|
|
ShowCreateSkillModal = false;
|
|
ShowEditSkillModal = false;
|
|
EditingSkillId = null;
|
|
}
|
|
|
|
private async Task OnSkillCreatedAsync(Guid skillId)
|
|
{
|
|
CloseSkillModals();
|
|
await SkillCreated.InvokeAsync(skillId);
|
|
}
|
|
|
|
private async Task OnSkillUpdatedAsync(Guid skillId)
|
|
{
|
|
CloseSkillModals();
|
|
await SkillUpdated.InvokeAsync(skillId);
|
|
}
|
|
|
|
private async Task OnRollVisibilityChangedAsync(ChangeEventArgs args)
|
|
{
|
|
var selectedVisibility = args.Value?.ToString() ?? "public";
|
|
await RollVisibilityChanged.InvokeAsync(selectedVisibility);
|
|
}
|
|
|
|
private async Task RollSkillAsync(Guid skillId)
|
|
{
|
|
await RollRequested.InvokeAsync(skillId);
|
|
}
|
|
|
|
private Task OnAddSkillRequestedAsync(Guid? skillGroupId)
|
|
{
|
|
OpenCreateSkillModal(skillGroupId);
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
private Task OnEditSkillRequestedAsync(SkillSummary skill)
|
|
{
|
|
OpenEditSkillModal(skill);
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
private Task OnEditSkillGroupRequestedAsync(Guid skillGroupId)
|
|
{
|
|
var skillGroup = SelectedCharacterSkillGroups.FirstOrDefault(group => group.Id == skillGroupId);
|
|
if (skillGroup is not null)
|
|
OpenEditSkillGroupModal(skillGroup);
|
|
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
private void OpenCreateSkillGroupModal()
|
|
{
|
|
SkillGroupState.Model.Name = string.Empty;
|
|
SkillGroupState.Model.DiceRollDefinition = string.Empty;
|
|
SkillGroupState.Model.WildDice = IsD6 ? 1 : 0;
|
|
SkillGroupState.Model.AllowFumble = IsD6;
|
|
SkillGroupState.ResetValidation();
|
|
ShowCreateSkillGroupModal = true;
|
|
}
|
|
|
|
private void OpenEditSkillGroupModal(SkillGroupSummary skillGroup)
|
|
{
|
|
EditingSkillGroupId = skillGroup.Id;
|
|
SkillGroupState.Model.Name = skillGroup.Name;
|
|
SkillGroupState.Model.DiceRollDefinition = skillGroup.DiceRollDefinition;
|
|
SkillGroupState.Model.WildDice = skillGroup.WildDice;
|
|
SkillGroupState.Model.AllowFumble = skillGroup.AllowFumble;
|
|
SkillGroupState.ResetValidation();
|
|
ShowEditSkillGroupModal = true;
|
|
}
|
|
|
|
private void CloseSkillGroupModals()
|
|
{
|
|
ShowCreateSkillGroupModal = false;
|
|
ShowEditSkillGroupModal = false;
|
|
EditingSkillGroupId = null;
|
|
SkillGroupState.ResetValidation();
|
|
}
|
|
|
|
private async Task SubmitCreateSkillGroupAsync()
|
|
{
|
|
SkillGroupState.ResetValidation();
|
|
|
|
if (string.IsNullOrWhiteSpace(SkillGroupState.Model.Name))
|
|
SkillGroupState.Errors["name"] = "Skill group name is required.";
|
|
|
|
if (string.IsNullOrWhiteSpace(SkillGroupState.Model.DiceRollDefinition))
|
|
SkillGroupState.Errors["diceRollDefinition"] = "Expression is required.";
|
|
|
|
if (IsD6 && SkillGroupState.Model.WildDice < 1)
|
|
SkillGroupState.Errors["wildDice"] = "D6 groups require at least one wild die.";
|
|
|
|
if (!SelectedCharacterId.HasValue)
|
|
SkillGroupState.Errors["character"] = "Select a character first.";
|
|
|
|
if (SkillGroupState.Errors.Count > 0)
|
|
{
|
|
SkillGroupState.ErrorMessage = "Resolve validation issues before submitting.";
|
|
return;
|
|
}
|
|
|
|
IsSubmittingSkillGroup = true;
|
|
try
|
|
{
|
|
var selectedCharacterId = SelectedCharacterId!.Value;
|
|
var createdGroup = await ApiClient.RequestAsync<SkillGroupSummary>(
|
|
"POST",
|
|
$"/api/characters/{selectedCharacterId}/skill-groups",
|
|
new CreateSkillGroupRequest(
|
|
SkillGroupState.Model.Name.Trim(),
|
|
SkillGroupState.Model.DiceRollDefinition.Trim(),
|
|
SkillGroupState.Model.WildDice,
|
|
SkillGroupState.Model.AllowFumble));
|
|
CloseSkillGroupModals();
|
|
await SkillGroupCreated.InvokeAsync(createdGroup.Id);
|
|
}
|
|
catch (ApiRequestException ex)
|
|
{
|
|
SkillGroupState.ErrorMessage = ex.Message;
|
|
}
|
|
finally
|
|
{
|
|
IsSubmittingSkillGroup = false;
|
|
}
|
|
}
|
|
|
|
private async Task SubmitUpdateSkillGroupAsync()
|
|
{
|
|
SkillGroupState.ResetValidation();
|
|
|
|
if (string.IsNullOrWhiteSpace(SkillGroupState.Model.Name))
|
|
SkillGroupState.Errors["name"] = "Skill group name is required.";
|
|
|
|
if (string.IsNullOrWhiteSpace(SkillGroupState.Model.DiceRollDefinition))
|
|
SkillGroupState.Errors["diceRollDefinition"] = "Expression is required.";
|
|
|
|
if (IsD6 && SkillGroupState.Model.WildDice < 1)
|
|
SkillGroupState.Errors["wildDice"] = "D6 groups require at least one wild die.";
|
|
|
|
if (!EditingSkillGroupId.HasValue)
|
|
SkillGroupState.Errors["group"] = "Select a skill group first.";
|
|
|
|
if (SkillGroupState.Errors.Count > 0)
|
|
{
|
|
SkillGroupState.ErrorMessage = "Resolve validation issues before submitting.";
|
|
return;
|
|
}
|
|
|
|
IsSubmittingSkillGroup = true;
|
|
try
|
|
{
|
|
var editingSkillGroupId = EditingSkillGroupId!.Value;
|
|
var updatedGroup = await ApiClient.RequestAsync<SkillGroupSummary>(
|
|
"PUT",
|
|
$"/api/skill-groups/{editingSkillGroupId}",
|
|
new UpdateSkillGroupRequest(
|
|
SkillGroupState.Model.Name.Trim(),
|
|
SkillGroupState.Model.DiceRollDefinition.Trim(),
|
|
SkillGroupState.Model.WildDice,
|
|
SkillGroupState.Model.AllowFumble));
|
|
CloseSkillGroupModals();
|
|
await SkillGroupUpdated.InvokeAsync(updatedGroup.Id);
|
|
}
|
|
catch (ApiRequestException ex)
|
|
{
|
|
SkillGroupState.ErrorMessage = ex.Message;
|
|
}
|
|
finally
|
|
{
|
|
IsSubmittingSkillGroup = false;
|
|
}
|
|
}
|
|
|
|
private async Task DeleteSkillAsync(Guid skillId)
|
|
{
|
|
try
|
|
{
|
|
await ApiClient.RequestAsync<bool>("DELETE", $"/api/skills/{skillId}");
|
|
await SkillDeleted.InvokeAsync(skillId);
|
|
}
|
|
catch (ApiRequestException ex)
|
|
{
|
|
await ErrorOccurred.InvokeAsync(ex.Message);
|
|
}
|
|
}
|
|
|
|
private async Task DeleteSkillGroupAsync(Guid skillGroupId)
|
|
{
|
|
try
|
|
{
|
|
await ApiClient.RequestAsync<bool>("DELETE", $"/api/skill-groups/{skillGroupId}");
|
|
await SkillGroupDeleted.InvokeAsync(skillGroupId);
|
|
}
|
|
catch (ApiRequestException ex)
|
|
{
|
|
await ErrorOccurred.InvokeAsync(ex.Message);
|
|
}
|
|
}
|
|
|
|
private bool SkillMatchesFilter(SkillSummary skill)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(SkillFilterText))
|
|
return true;
|
|
|
|
var filter = SkillFilterText.Trim();
|
|
return skill.Name.Contains(filter, StringComparison.OrdinalIgnoreCase) ||
|
|
skill.DiceRollDefinition.Contains(filter, StringComparison.OrdinalIgnoreCase);
|
|
}
|
|
|
|
private static string InitialsFor(string value)
|
|
{
|
|
var words = value.Split(' ', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
|
|
if (words.Length == 0)
|
|
return "?";
|
|
|
|
if (words.Length == 1)
|
|
return words[0].Length >= 2 ? words[0][..2].ToUpperInvariant() : words[0].ToUpperInvariant();
|
|
|
|
return string.Concat(words[0][0], words[1][0]).ToUpperInvariant();
|
|
}
|
|
|
|
private bool ShowCreateSkillModal { get; set; }
|
|
private bool ShowEditSkillModal { get; set; }
|
|
private bool ShowCreateSkillGroupModal { get; set; }
|
|
private bool ShowEditSkillGroupModal { get; set; }
|
|
private Guid? EditingSkillId { get; set; }
|
|
private Guid? EditingSkillGroupId { get; set; }
|
|
private SkillFormModel CreateSkillInitialModel { get; set; } = new();
|
|
private SkillFormModel EditSkillInitialModel { get; set; } = new();
|
|
private FormState<SkillGroupFormModel> SkillGroupState { get; } = new();
|
|
private int CreateSkillFormVersion { get; set; }
|
|
private int EditSkillFormVersion { get; set; }
|
|
private bool IsSubmittingSkillGroup { get; set; }
|
|
private string SkillFilterText { get; set; } = string.Empty;
|
|
|
|
[Inject]
|
|
private RpgRollerApiClient ApiClient { get; set; } = null!;
|
|
|
|
[Parameter]
|
|
public bool IsCampaignDataLoading { get; set; }
|
|
|
|
[Parameter]
|
|
public CampaignRoster? SelectedCampaign { get; set; }
|
|
|
|
[Parameter]
|
|
public Guid? SelectedCharacterId { get; set; }
|
|
|
|
[Parameter]
|
|
public CharacterSummary? SelectedCharacter { get; set; }
|
|
|
|
[Parameter]
|
|
public bool IsMutating { get; set; }
|
|
|
|
[Parameter]
|
|
public IReadOnlyList<SkillSummary> SelectedCharacterSkills { get; set; } = [];
|
|
|
|
[Parameter]
|
|
public IReadOnlyList<SkillGroupSummary> SelectedCharacterSkillGroups { get; set; } = [];
|
|
|
|
[Parameter]
|
|
public bool IsD6 { get; set; }
|
|
|
|
[Parameter]
|
|
public string RollVisibility { get; set; } = "public";
|
|
|
|
[Parameter]
|
|
public EventCallback<string> RollVisibilityChanged { get; set; }
|
|
|
|
[Parameter]
|
|
public Func<Guid, string> OwnerLabel { get; set; } = _ => string.Empty;
|
|
|
|
[Parameter]
|
|
public Func<SkillSummary, string> SkillDefinitionLabel { get; set; } = _ => string.Empty;
|
|
|
|
[Parameter]
|
|
public Func<CharacterSummary, bool> CanEditCharacter { get; set; } = _ => false;
|
|
|
|
[Parameter]
|
|
public Func<SkillSummary, bool> CanEditSkill { get; set; } = _ => false;
|
|
|
|
[Parameter]
|
|
public EventCallback<Guid> CharacterSelected { get; set; }
|
|
|
|
[Parameter]
|
|
public EventCallback<CharacterSummary> EditCharacterRequested { get; set; }
|
|
|
|
[Parameter]
|
|
public EventCallback<Guid> SkillCreated { get; set; }
|
|
|
|
[Parameter]
|
|
public EventCallback<Guid> SkillUpdated { get; set; }
|
|
|
|
[Parameter]
|
|
public EventCallback<Guid> SkillGroupCreated { get; set; }
|
|
|
|
[Parameter]
|
|
public EventCallback<Guid> SkillGroupUpdated { get; set; }
|
|
|
|
[Parameter]
|
|
public EventCallback<Guid> SkillDeleted { get; set; }
|
|
|
|
[Parameter]
|
|
public EventCallback<Guid> SkillGroupDeleted { get; set; }
|
|
|
|
[Parameter]
|
|
public EventCallback<string> ErrorOccurred { get; set; }
|
|
|
|
[Parameter]
|
|
public EventCallback<Guid> RollRequested { get; set; }
|
|
}
|