LANCommander/LANCommander.Server/UI/Components/ActionEditor.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

156 lines
5 KiB
Text

@using System.Collections.ObjectModel
@using Action = LANCommander.Server.Data.Models.Action
@inject ActionService ActionService
@inject ArchiveService ArchiveService
@inject MessageService MessageService
@inject ILogger<ActionEditor> Logger
<Flex Vertical Gap="FlexGap.Large">
<Table TItem="Action" DataSource="@_sortedActions.OrderBy(a => a.SortOrder)" HidePagination Style="border: 1px solid #f0f0f0" Responsive>
<PropertyColumn Property="a => a.Name">
<Input Type="InputType.Text" @bind-Value="context.Name"/>
</PropertyColumn>
<PropertyColumn Property="a => a.Path">
<FilePicker @bind-Value="context.Path" ArchiveId="@(_archive?.Id ?? Guid.Empty)" AllowDirectories Title="Select Action Executable" OnSelected="(path) => OnPathSelected(path, context)"/>
</PropertyColumn>
<PropertyColumn Property="a => a.Arguments">
<Input Type="InputType.Text" @bind-Value="context.Arguments"/>
</PropertyColumn>
<PropertyColumn Property="a => a.WorkingDirectory" Title="Working Dir">
<Input Type="InputType.Text" @bind-Value="context.WorkingDirectory"/>
</PropertyColumn>
<PropertyColumn Property="a => a.PrimaryAction" Title="Primary" Style="text-align: center">
<Checkbox @bind-Checked="context.PrimaryAction"/>
</PropertyColumn>
<ActionColumn>
<Flex Gap="FlexGap.Small" Justify="FlexJustify.End">
<Button OnClick="() => MoveUp(context)" Icon="@IconType.Outline.Up" Type="ButtonType.Text"/>
<Button OnClick="() => MoveDown(context)" Icon="@IconType.Outline.Down" Type="ButtonType.Text"/>
<Popconfirm OnConfirm="() => RemoveAction(context)" Title="Are you sure you want to remove this action?">
<Button Icon="@IconType.Outline.Close" Type="ButtonType.Text" Danger/>
</Popconfirm>
</Flex>
</ActionColumn>
</Table>
<GridRow Justify="RowJustify.End">
<GridCol>
<Button OnClick="AddAction" Type="ButtonType.Primary">Add Action</Button>
</GridCol>
</GridRow>
</Flex>
@code {
[CascadingParameter(Name = "GameId")] public Guid? GameId { get; set; }
[CascadingParameter(Name = "ServerId")] public Guid? ServerId { get; set; }
Archive? _archive;
Game? _game;
Server? _server;
ObservableCollection<Action> _sortedActions = new();
protected override async Task OnInitializedAsync() => await LoadActions();
async Task LoadActions()
{
if (GameId.HasValue)
{
_sortedActions = new ObservableCollection<Action>(await ActionService.SortBy(a => a.SortOrder).GetAsync(a => a.GameId == GameId.Value));
_archive = await ArchiveService.GetLatestArchiveAsync(a => a.GameId == GameId);
}
if (ServerId.HasValue)
_sortedActions = new ObservableCollection<Action>(await ActionService.SortBy(a => a.SortOrder).GetAsync(a => a.ServerId == ServerId.Value));
}
void AddAction()
{
var newAction = new Action
{
PrimaryAction = _sortedActions.Count == 0,
SortOrder = _sortedActions.Count
};
if (GameId.HasValue)
newAction.GameId = GameId;
if (ServerId.HasValue)
newAction.ServerId = ServerId;
_sortedActions.Add(newAction);
UpdateOrder();
}
async Task RemoveAction(Action action)
{
await ActionService.DeleteAsync(action);
_sortedActions.Remove(action);
UpdateOrder();
}
async Task MoveUp(Action action)
{
var index = _sortedActions.IndexOf(action);
if (index > 0)
_sortedActions.Move(index, index - 1);
UpdateOrder();
}
async Task MoveDown(Action action)
{
var index = _sortedActions.IndexOf(action);
if (index < _sortedActions.Count - 1)
_sortedActions.Move(index, index + 1);
UpdateOrder();
}
void UpdateOrder()
{
foreach (var action in _sortedActions)
action.SortOrder = _sortedActions.IndexOf(action);
if (GameId.HasValue && _game != null)
_game.Actions = _sortedActions;
if (ServerId.HasValue && _server != null)
_server.Actions = _sortedActions;
}
public async Task Save()
{
try
{
foreach (var action in _sortedActions)
{
if (action.Id == Guid.Empty)
await ActionService.AddAsync(action);
else
await ActionService.UpdateAsync(action);
}
await LoadActions();
MessageService.Success("Actions updated!");
}
catch (Exception ex)
{
MessageService.Error("Could not update actions!");
Logger.LogError(ex, "Could not update actions!");
}
}
void OnPathSelected(string path, Action action)
{
action.Path = path;
action.WorkingDirectory = "{InstallDir}";
}
}