LANCommander/LANCommander.Server/UI/Components/ArchiveEditor.razor
Pat Hartl 120e14d40c Add Tools section to server app
Allows users to upload additional tools and tie them to games. This can be useful for software like map editors, trainers, etc.
2026-02-08 02:24:53 -06:00

181 lines
6 KiB
Text

@inject ArchiveService ArchiveService
@inject HttpClient HttpClient
@inject NavigationManager Navigator
@inject ModalService ModalService
@inject IMessageService MessageService
@inject IJSRuntime JS
@inject ILogger<ArchiveEditor> Logger
<DataTable
@ref="_table"
TItem="Archive"
HidePagination
Responsive
Query="a => (GameId != Guid.Empty && a.GameId == GameId) || (RedistributableId != Guid.Empty && a.RedistributableId == RedistributableId) || (ToolId != Guid.Empty && a.ToolId == ToolId)">
<RightToolbar>
<Button OnClick="RecalculateFileSizes" Type="@ButtonType.Default">Recalculate File Sizes</Button>
<Button OnClick="UploadArchive" Type="@ButtonType.Primary">Upload Archive</Button>
</RightToolbar>
<Columns>
<BoundDataColumn Property="a => a.Version">
<Input Type="InputType.Text" Bordered="false" @bind-Value="context.Version" OnBlur="() => Update(context)"/>
</BoundDataColumn>
<BoundDataColumn Property="a => a.CompressedSize">
<ByteSize Value="context.CompressedSize" />
</BoundDataColumn>
<BoundDataColumn Property="a => a.UncompressedSize">
<ByteSize Value="context.UncompressedSize" />
</BoundDataColumn>
<BoundDataColumn Property="a => a.CreatedBy != null ? a.CreatedBy.UserName : String.Empty" Include="CreatedBy"/>
<BoundDataColumn Property="s => s.CreatedOn" DefaultSortOrder="SortDirection.Descending">
<LocalTime Value="context.CreatedOn" />
</BoundDataColumn>
<DataActions TData="string">
<Tooltip Title="Recalculate File Size">
<Button Icon="@IconType.Outline.Sync" Type="@ButtonType.Text" OnClick="() => RecalculateFileSize(context)"/>
</Tooltip>
<Tooltip Title="Download">
<a href="/Download/Archive/@context.Id" target="_blank" class="ant-btn ant-btn-text ant-btn-icon-only">
<Icon Type="@IconType.Outline.Download"/>
</a>
</Tooltip>
<Tooltip Title="Browse">
<Button Icon="@IconType.Outline.FolderOpen" Type="@ButtonType.Text" OnClick="() => BrowseArchive(context)" Loading="_browsing"/>
</Tooltip>
<Popconfirm Title="Are you sure you want to delete this archive?" OnConfirm="() => Delete(context)">
<Button Icon="@IconType.Outline.Close" Type="@ButtonType.Text" Danger/>
</Popconfirm>
</DataActions>
</Columns>
</DataTable>
<ArchiveUploader @ref="_uploader" GameId="GameId" RedistributableId="RedistributableId" OnArchiveUploaded="ArchiveUploaded" />
@code {
[CascadingParameter(Name = "GameId")] public Guid GameId { get; set; }
[CascadingParameter(Name = "RedistributableId")] public Guid RedistributableId { get; set; }
[CascadingParameter(Name = "ToolId")] public Guid ToolId { get; set; }
DataTable<Archive> _table;
ArchiveUploader _uploader;
bool _browsing;
protected override void OnInitialized()
{
HttpClient.BaseAddress = new Uri(Navigator.BaseUri);
}
private async Task RecalculateFileSizes()
{
MessageService.Info("Recalculating File Sizes...");
await Task.Yield();
await InvokeAsync(StateHasChanged);
var archives = _table.DataSource;
var results = new List<bool>();
foreach (var archive in archives)
{
var result = await ArchiveService.RecalculateFileSizeArchiveAsync(archive);
results.Add(result);
}
if (results.All(x => x))
MessageService.Success("File sizes recalculated!");
else
MessageService.Warning("File sizes recalculated but some failed!");
await Task.Yield();
await InvokeAsync(StateHasChanged);
await _table.ReloadAsync();
}
private async Task RecalculateFileSize(Archive archive)
{
MessageService.Info("Recalculating File Sizes...");
archive = await ArchiveService.AsNoTracking().GetAsync(archive.Id);
var result = await ArchiveService.RecalculateFileSizeArchiveAsync(archive);
await ArchiveUploaded(archive.Id);
if (result)
MessageService.Success("File sizes recalculated!");
else
MessageService.Error("Recalculating file sizes failed!");
}
private async Task ArchiveUploaded(Guid archiveId)
{
await _table.ReloadAsync();
}
private async Task UploadArchive()
{
await _uploader.Open();
}
private async Task BrowseArchive(Archive archive)
{
_browsing = true;
await InvokeAsync(StateHasChanged);
await Task.Yield();
var modalOptions = new ModalOptions()
{
Title = "Browse Archive",
Maximizable = false,
DefaultMaximized = true,
Closable = true,
WrapClassName = "file-picker-dialog",
};
var modalRef = await ModalService.CreateModalAsync<ArchiveBrowserDialog, Guid, Guid>(modalOptions, archive.Id);
_browsing = false;
await InvokeAsync(StateHasChanged);
await Task.Yield();
}
private async Task Update(Archive archive)
{
try
{
await ArchiveService.UpdateAsync(archive);
await _table.ReloadAsync();
MessageService.Success("Archive updated!");
}
catch (Exception ex)
{
MessageService.Error("Archive could not be updated.");
Logger.LogError(ex, "Archive could not be updated.");
}
}
private async Task Delete(Archive archive)
{
try
{
await ArchiveService.DeleteAsync(archive);
await _table.ReloadAsync();
MessageService.Success("Archive deleted!");
}
catch (Exception ex)
{
MessageService.Error("Archive could not be deleted.");
Logger.LogError(ex, "Archive could not be deleted.");
}
}
}