LANCommander/LANCommander.Server/UI/Pages/Games/Index.razor

254 lines
8.3 KiB
Text
Raw Permalink Normal View History

@page "/Games"
2025-01-16 00:35:01 -06:00
@using SortDirection = AntDesign.SortDirection
@using AntDesign.TableModels
@attribute [Authorize]
@inject GameService GameService
@inject MetadataService MetadataService
@inject NavigationManager NavigationManager
@inject ModalService ModalService
@inject IMessageService MessageService
2024-07-07 16:33:46 -05:00
@inject ILogger<Index> Logger
<PageHeader Title="Games" Subtitle="@Total.ToString()" />
2024-12-12 17:35:52 -06:00
<DataTable
2024-11-07 02:06:54 -06:00
@ref="Table"
TItem="Game"
@bind-SelectedRows="Selected"
@bind-Total="Total"
2024-11-07 02:06:54 -06:00
Size="@TableSize.Small"
2025-01-16 00:35:01 -06:00
Responsive
ColumnPicker
2025-01-21 18:48:01 -06:00
Searchable
SearchProperty="g => g.Title"
Children="(g, dg) => dg.BaseGameId == g.Id && (dg.Type == GameType.Expansion || dg.Type == GameType.Mod)"
Query="g => g.BaseGameId == null || g.BaseGameId == Guid.Empty || (g.Type != GameType.Expansion && g.Type != GameType.Mod)">
2024-12-12 17:35:52 -06:00
<RightToolbar>
@if (Selected != null && Selected.Count() > 0)
{
2025-08-01 02:35:23 -05:00
<Button OnClick="() => AddToCollection()" Type="@ButtonType.Default">Add to Collection</Button>
2024-12-12 17:35:52 -06:00
}
<Button Type="@ButtonType.Default" OnClick="OpenImportDialog">Import</Button>
2024-12-12 17:35:52 -06:00
<Button OnClick="() => Add()" Type="@ButtonType.Primary">Add Game</Button>
</RightToolbar>
<Columns>
<Selection Key="@(context.Id.ToString())" CheckStrictly="true" />
2025-01-16 00:35:01 -06:00
<DataColumn TData="string" Title="Icon" Include="Media">
2024-12-12 17:35:52 -06:00
<Image Src="@GetIcon(context)" Height="32" Width="32" Preview="false"></Image>
</DataColumn>
2025-01-16 00:35:01 -06:00
<BoundDataColumn Property="g => g.Title" Sortable DefaultSortOrder="SortDirection.Ascending" />
<BoundDataColumn Property="g => g.MultiplayerModes" Include="MultiplayerModes" Sortable Title="Multiplayer">
2024-12-12 17:35:52 -06:00
<Checkbox Disabled="true" Checked="context.MultiplayerModes?.Count > 0" />
2025-01-20 01:22:56 -06:00
</BoundDataColumn>
2024-12-12 17:35:52 -06:00
<BoundDataColumn Property="g => g.Keys" Title="Total Keys" Include="Keys" Sortable>
@context.Keys?.Count
</BoundDataColumn>
<BoundDataColumn Property="g => g.Keys" Title="Keys Allocated" Include="Keys" Sortable>
@context.Keys?.Count(k => k.ClaimedOn.HasValue)
</BoundDataColumn>
2025-01-16 00:35:01 -06:00
<DataColumn TData="string[]" Title="Collections" Include="Collections">
2024-12-12 17:35:52 -06:00
@if (context.Collections != null)
foreach (var collection in context.Collections)
{
<Tag>@collection.Name</Tag>
}
</DataColumn>
2025-01-28 00:46:37 -06:00
<DataColumn TData="string[]" Title="Developers" Include="Developers" Hide>
2024-12-12 17:35:52 -06:00
@if (context.Developers != null)
foreach (var dev in context.Developers)
{
<Tag>@dev.Name</Tag>
}
</DataColumn>
2025-01-28 00:46:37 -06:00
<DataColumn TData="string[]" Title="Publishers" Include="Publishers" Hide>
2024-12-12 17:35:52 -06:00
@if (context.Publishers != null)
foreach (var pub in context.Publishers)
{
<Tag>@pub.Name</Tag>
}
</DataColumn>
2025-01-28 00:46:37 -06:00
<DataColumn TData="string[]" Title="Genres" Include="Genres" Hide>
2024-12-12 17:35:52 -06:00
@if (context.Genres != null)
foreach (var genre in context.Genres)
{
<Tag>@genre.Name</Tag>
}
</DataColumn>
2025-01-28 00:46:37 -06:00
<DataColumn TData="string[]" Title="Platforms" Include="Platforms" Hide>
2024-12-12 17:35:52 -06:00
@if (context.Platforms != null)
foreach (var platform in context.Platforms)
{
<Tag>@platform.Name</Tag>
}
</DataColumn>
2025-01-28 00:46:37 -06:00
<DataColumn TData="SDK.Enums.MultiplayerType[]" Title="Multiplayer Modes" Include="MultiplayerModes" Hide>
2024-12-12 17:35:52 -06:00
@if (context.MultiplayerModes != null)
foreach (var mode in context.MultiplayerModes.Select(mm => mm.Type).Distinct())
{
<Tag>@mode.GetDisplayName()</Tag>
}
</DataColumn>
2025-03-17 02:02:17 -05:00
<BoundDataColumn Property="g => g.CreatedOn" Title="Created On" Sortable>
<LocalTime Value="context.CreatedOn" />
</BoundDataColumn>
<BoundDataColumn Property="g => g.UpdatedOn" Title="Updated On" Sortable>
<LocalTime Value="context.UpdatedOn" />
</BoundDataColumn>
2025-01-28 00:46:37 -06:00
<BoundDataColumn Property="g => g.CreatedBy" Sortable Title="Created By" Include="CreatedBy">
@context.CreatedBy?.UserName
</BoundDataColumn>
<BoundDataColumn Property="g => g.UpdatedBy" Title="Updated By" Sortable Include="UpdatedBy">
@context.UpdatedBy?.UserName
</BoundDataColumn>
<DataActions TData="string">
<Flex Gap="FlexGap.Small" Align="FlexAlign.Center" Justify="FlexJustify.End">
<a href="@($"/Games/{context.Id}")" class="ant-btn ant-btn-primary">Edit</a>
<Popconfirm OnConfirm="() => Delete(context)" Title="Are you sure you want to delete this game?">
<Button Icon="@IconType.Outline.Close" Type="@ButtonType.Text" Danger/>
</Popconfirm>
</Flex>
2024-12-12 17:35:52 -06:00
</DataActions>
</Columns>
<PaginationTemplate>
<Pagination
Total="context.Total"
PageSize="context.PageSize"
Current="context.PageIndex"
DefaultPageSize="25"
PageSizeOptions="new [] { 25, 50, 100, 200 }"
ShowSizeChanger
OnChange="context.HandlePageChange" />
</PaginationTemplate>
2024-12-12 17:35:52 -06:00
</DataTable>
2024-07-07 16:33:46 -05:00
@code {
bool Visibility = false;
IEnumerable<Game> Selected;
int Total;
2024-12-12 17:35:52 -06:00
DataTable<Game> Table;
2024-11-27 21:08:58 -06:00
string GetIcon(Game game)
{
2024-06-19 19:36:04 -05:00
var media = game?.Media?.FirstOrDefault(m => m.Type == SDK.Enums.MediaType.Icon);
if (media != null)
return $"/api/Media/{media.Id}/Download?fileId={media.FileId}";
else
return "/favicon.ico";
}
bool _hasMetadataProviders;
protected override void OnInitialized()
{
_hasMetadataProviders = MetadataService.GetProviderNames().Any();
}
async Task Add()
2023-03-03 17:40:24 -06:00
{
if (_hasMetadataProviders)
{
var modalOptions = new ModalOptions
{
Title = "Add Game",
Maximizable = false,
DefaultMaximized = false,
Closable = true,
Footer = null,
};
var modalRef = ModalService.CreateModal<AddGameDialog, AddGameDialogOptions>(modalOptions, new AddGameDialogOptions());
modalRef.OnClose = Reload;
}
else
{
NavigationManager.NavigateTo("/Games/Add");
}
2023-03-03 17:40:24 -06:00
}
2024-11-27 21:08:58 -06:00
async Task Delete(Game game)
2023-03-15 18:09:48 -05:00
{
try
{
await GameService.DeleteAsync(game);
2024-02-23 17:25:40 -06:00
MessageService.Success($"{game.Title} was successfully deleted!");
}
catch (Exception ex)
{
MessageService.Error("Could not delete the game!");
Logger.LogError(ex, "Could not delete the game!");
}
2023-03-15 18:09:48 -05:00
2025-01-16 00:35:01 -06:00
await Reload();
2023-03-15 18:09:48 -05:00
}
2024-11-27 21:08:58 -06:00
async void AddToCollection()
{
var modalOptions = new ModalOptions()
{
Title = "Add to Collection",
Maximizable = false,
DefaultMaximized = false,
Closable = true,
OkText = "Add"
};
var options = new AddToCollectionOptions()
{
GameIds = Selected.Select(g => g.Id)
};
var modalRef = await ModalService.CreateModalAsync<AddToCollectionDialog, AddToCollectionOptions, IEnumerable<Collection>>(modalOptions, options);
modalRef.OnOk = async (collections) =>
{
Table.UnselectAll();
2025-01-16 00:35:01 -06:00
await Reload();
};
}
async Task OpenImportDialog()
{
var options = new ImportDialogOptions
{
2026-05-24 18:51:58 -05:00
Hint = "Only LCX files are supported for importing games",
ManifestType = ManifestType.Game,
};
var modalOptions = new ModalOptions
{
Title = "Import Game",
DestroyOnClose = true,
2025-01-21 20:43:28 -06:00
MaskClosable = false,
Footer = null,
};
var modalRef = ModalService.CreateModal<ImportUploadDialog, ImportDialogOptions>(modalOptions, options);
2025-12-05 16:28:39 -06:00
modalRef.OnOk = modalRef.OnCancel = modalRef.OnClose = Reload;
}
2025-01-16 00:35:01 -06:00
async Task Reload()
{
2025-12-05 16:28:39 -06:00
await Table.ReloadAsync();
2025-01-16 00:35:01 -06:00
}
}