LANCommander/LANCommander.Server/UI/Components/ScriptEditor.razor

197 lines
6.2 KiB
Text

@using System.Linq.Expressions
@using LANCommander.SDK.Extensions
@using LANCommander.SDK.Enums
@inject ScriptService ScriptService
@inject GameVersionService GameVersionService
@inject ModalService ModalService
@inject IMessageService MessageService
@inject ILogger<ScriptEditor> Logger
<Flex Direction="FlexDirection.Vertical" Gap="FlexGap.Large">
<DataTable
@ref="Table"
TItem="Script"
HidePagination
Responsive
Size="TableSize.Small"
Query="GetQueryExpression()">
<BoundDataColumn Property="s => s.Name" />
<BoundDataColumn Property="s => s.Type">
@context.Type.GetDisplayName()
</BoundDataColumn>
<BoundDataColumn Title="Created By" Property="s => s.CreatedBy != null ? s.CreatedBy.UserName : String.Empty" Include="CreatedBy">
@context.CreatedBy?.UserName
</BoundDataColumn>
<BoundDataColumn Property="s => s.CreatedOn">
<LocalTime Value="context.CreatedOn" />
</BoundDataColumn>
<DataActions TData="string">
<Button OnClick="() => Edit(context.Id)" Icon="@IconType.Outline.Edit" Type="ButtonType.Text"/>
<Popconfirm OnConfirm="() => Delete(context)" Title="Are you sure you want to delete this script?">
<Button Icon="@IconType.Outline.Close" Type="ButtonType.Text" Danger/>
</Popconfirm>
</DataActions>
</DataTable>
<Flex Gap="FlexGap.Small" Justify="FlexJustify.End">
<Dropdown>
<Overlay>
<Menu>
@foreach (var type in GetAllowedTypes())
{
<MenuItem OnClick="() => Add(type)">
@type.GetDisplayName()
</MenuItem>
}
</Menu>
</Overlay>
<ChildContent>
<Button Type="ButtonType.Primary">Add Script</Button>
</ChildContent>
</Dropdown>
</Flex>
</Flex>
<style>
.monaco-editor-container {
height: 600px;
}
</style>
@code {
[CascadingParameter(Name = "GameId")] public Guid? GameId { get; set; }
[CascadingParameter(Name = "RedistributableId")] public Guid? RedistributableId { get; set; }
[CascadingParameter(Name = "ServerId")] public Guid? ServerId { get; set; }
[CascadingParameter(Name = "ToolId")] public Guid? ToolId { get; set; }
[Parameter] public IEnumerable<ScriptType> AllowedTypes { get; set; }
Expression<Func<Script, bool>> Query = s => s.GameId == Guid.Empty && s.RedistributableId == Guid.Empty && s.ServerId == Guid.Empty && s.ToolId == Guid.Empty;
DataTable<Script> Table;
Archive _archive;
// For games, scripts are version-scoped: they belong to the game's latest GameVersion rather
// than the game directly. Resolved (creating an initial version if needed) so the table can
// filter to the current version; the service assigns it on save.
Guid? _gameVersionId;
protected override async Task OnInitializedAsync()
{
if (GameId.HasValue && GameId != Guid.Empty)
_gameVersionId = await GameVersionService.GetOrCreateLatestIdAsync(GameId.Value);
}
IEnumerable<ScriptType> GetAllowedTypes()
{
if (AllowedTypes != null)
return AllowedTypes;
return Enum.GetValues<ScriptType>();
}
Expression<Func<Script, bool>> GetQueryExpression()
{
if (GameId.HasValue)
return s => s.GameVersionId == _gameVersionId;
if (RedistributableId.HasValue)
return s => s.RedistributableId == RedistributableId;
if (ServerId.HasValue)
return s => s.ServerId == ServerId;
if (ToolId.HasValue)
return s => s.ToolId == ToolId;
return s =>
(s.GameId == null || s.GameId == Guid.Empty)
&&
(s.RedistributableId == null || s.RedistributableId == Guid.Empty)
&&
(s.ServerId == null || s.ServerId == Guid.Empty)
&&
(s.ToolId == null || s.ToolId == Guid.Empty);
}
async void Add(ScriptType scriptType)
{
var modalOptions = new ModalOptions()
{
Title = $"Add {scriptType.GetDisplayName()} Script",
Maximizable = false,
DefaultMaximized = true,
Closable = true,
MaskClosable = false,
OkText = "Save"
};
var options = new ScriptEditorOptions()
{
ScriptType = scriptType,
AllowedTypes = AllowedTypes,
GameId = GameId,
RedistributableId = RedistributableId,
ServerId = ServerId,
ToolId = ToolId,
};
var modalRef = await ModalService.CreateModalAsync<ScriptEditorDialog, ScriptEditorOptions, Script>(modalOptions, options);
modalRef.OnOk = async (script) =>
{
await Table.ReloadAsync();
};
}
async void Edit(Guid scriptId)
{
var modalOptions = new ModalOptions()
{
Title = "Edit Script",
Maximizable = false,
DefaultMaximized = true,
Closable = true,
MaskClosable = false,
OkText = "Save"
};
var options = new ScriptEditorOptions()
{
ScriptId = scriptId,
AllowedTypes = AllowedTypes,
GameId = GameId,
RedistributableId = RedistributableId,
ServerId = ServerId,
ToolId = ToolId,
};
var modalRef = await ModalService.CreateModalAsync<ScriptEditorDialog, ScriptEditorOptions, Script>(modalOptions, options);
modalRef.OnOk = async (script) =>
{
await Table.ReloadAsync();
};
}
async Task Delete(Script script = null)
{
try
{
if (script != null)
await ScriptService.DeleteAsync(script);
await Table.ReloadAsync();
MessageService.Success("Script deleted!");
}
catch (Exception ex)
{
Logger?.LogError(ex, "Could not delete script");
MessageService.Error("Could not delete script!");
}
}
}