LANCommander/LANCommander.Server/UI/Pages/Games/Components/KeysEditor.razor
Pat Hartl 20731f355a Fix certain taxonomies (tag, genre, platform) being removed from game on save
Fixes the action, custom field, multiplayer mode, and save path editors from clearing out taxonomies when saving. Also passes the Game/Server/Redistributable ID as a cascading parameter.
2025-12-08 00:51:32 -06:00

142 lines
4.7 KiB
Text

@inject KeyService KeyService
@inject IMessageService MessageService
@inject ILogger<KeysEditor> Logger
@if (_keys != null)
{
<Flex Direction="FlexDirection.Vertical" Gap="FlexGap.Small">
<GridRow>
<GridCol Span="8">
<Statistic Title="Available" Value="_keys.Count - _allocatedKeys" Style="text-align: center;" />
</GridCol>
<GridCol Span="8">
<Statistic Title="Allocated" Value="_allocatedKeys" Style="text-align: center;" />
</GridCol>
<GridCol Span="8">
<Statistic Title="Total" Value="_keys.Count" Style="text-align: center;" />
</GridCol>
</GridRow>
<DataTable
TItem="Key"
Responsive
Query="k => k.GameId == GameId">
<RightToolbar>
<Button Type="@ButtonType.Default" OnClick="() => Edit()">Edit</Button>
<Button Type="@ButtonType.Primary" OnClick="() => Save()">Save</Button>
</RightToolbar>
<Columns>
<BoundDataColumn Property="k => k.Value">
<InputPassword @bind-Value="@context.Value"/>
</BoundDataColumn>
<BoundDataColumn Property="k => k.AllocationMethod" Title="Allocation Method"/>
<DataColumn TData="string" Title="Claimed By" Include="ClaimedByUser">
@switch (context.AllocationMethod)
{
case KeyAllocationMethod.MacAddress:
<text>@context.ClaimedByMacAddress</text>
break;
case KeyAllocationMethod.UserAccount:
<text>@context.ClaimedByUser?.UserName</text>
break;
}
</DataColumn>
<BoundDataColumn Property="s => s.ClaimedOn" Title="Claimed" Sortable>
<LocalTime Value="context.CreatedOn" Relative />
</BoundDataColumn>
<DataActions TData="string">
@if (context.IsAllocated())
{
<Button OnClick="() => Release(context)">Release</Button>
}
</DataActions>
</Columns>
</DataTable>
</Flex>
<Modal Title="Edit Keys" Visible="_editModalVisible" Maximizable="false" DefaultMaximized="true" OnCancel="() => _editModalVisible = false" OnOk="Save">
<StandaloneCodeEditor @ref="_editor" Id="editor" ConstructionOptions="EditorConstructionOptions" />
</Modal>
}
<style>
.monaco-editor-container {
height: 600px;
}
</style>
@code {
[CascadingParameter(Name = "GameId")] public Guid GameId { get; set; }
ICollection<Key> _keys = new List<Key>();
int _allocatedKeys;
bool _editModalVisible = false;
StandaloneCodeEditor? _editor;
StandaloneEditorConstructionOptions EditorConstructionOptions(StandaloneCodeEditor editor)
{
return new StandaloneEditorConstructionOptions
{
AutomaticLayout = true,
Language = "text",
Value = String.Join('\n', _keys.Select(k => k.Value)),
Theme = "vs-dark",
};
}
protected override async Task OnInitializedAsync()
{
if (_keys == null)
_keys = new List<Key>();
_keys = await KeyService.GetAsync(k => k.GameId == GameId);
_allocatedKeys = _keys.Count(k => k.IsAllocated());
}
void Edit()
{
_editModalVisible = true;
}
async Task Release(Key key)
{
await KeyService.ReleaseAsync(key);
await MessageService.SuccessAsync("Key was unallocated!");
}
async Task Save()
{
try
{
var value = await _editor.GetValue();
var keys = value.Split("\n").Select(k => k.Trim()).Where(k => !String.IsNullOrWhiteSpace(k)).ToList();
var keysDeleted = _keys.Where(k => !keys.Contains(k.Value)).ToList();
var keysAdded = keys.Where(k => !_keys.Any(gk => gk.Value == k)).ToList();
foreach (var key in keysDeleted)
await KeyService.DeleteAsync(key);
foreach (var key in keysAdded)
await KeyService.AddAsync(new Key()
{
GameId = GameId,
Value = key
});
_editModalVisible = false;
MessageService.Success("Keys updated!");
}
catch (Exception ex)
{
MessageService.ErrorAsync("Could not update keys!");
Logger.LogError(ex, "Could not update keys!");
}
}
}