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

162 lines
5.4 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)">
<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">
<Button Icon="@IconType.Outline.Sync" Type="@ButtonType.Text" OnClick="() => RecalculateFileSize(context)" />
<a href="/Download/Archive/@context.Id" target="_blank" class="ant-btn ant-btn-text ant-btn-icon-only">
<Icon Type="@IconType.Outline.Download"/>
</a>
<Button Icon="@IconType.Outline.FolderOpen" Type="@ButtonType.Text" OnClick="() => BrowseArchive(context)" />
<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; }
DataTable<Archive> _table;
ArchiveUploader _uploader;
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)
{
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);
}
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.");
}
}
}