2023-02-04 12:18:10 -06:00
|
|
|
@page "/Games"
|
2025-01-16 00:35:01 -06:00
|
|
|
@using SortDirection = AntDesign.SortDirection
|
2025-05-23 02:17:06 -05:00
|
|
|
@using AntDesign.TableModels
|
2023-03-02 18:50:24 -06:00
|
|
|
@attribute [Authorize]
|
2025-02-01 02:21:34 -06:00
|
|
|
@inject GameService GameService
|
2023-03-02 18:50:24 -06:00
|
|
|
@inject NavigationManager NavigationManager
|
2023-12-04 01:39:59 -06:00
|
|
|
@inject ModalService ModalService
|
2023-11-27 20:28:51 -06:00
|
|
|
@inject IMessageService MessageService
|
2024-07-07 16:33:46 -05:00
|
|
|
@inject ILogger<Index> Logger
|
2023-02-04 12:18:10 -06:00
|
|
|
|
2025-01-28 18:23:49 -06:00
|
|
|
<PageHeader Title="Games" Subtitle="@Total.ToString()" />
|
2023-08-10 12:59:03 -05:00
|
|
|
|
2024-12-12 17:35:52 -06:00
|
|
|
<DataTable
|
2024-11-07 02:06:54 -06:00
|
|
|
@ref="Table"
|
|
|
|
|
TItem="Game"
|
|
|
|
|
@bind-SelectedRows="Selected"
|
2025-01-28 18:23:49 -06:00
|
|
|
@bind-Total="Total"
|
2024-11-07 02:06:54 -06:00
|
|
|
Size="@TableSize.Small"
|
2025-01-16 00:35:01 -06:00
|
|
|
Responsive
|
2025-01-28 18:23:49 -06:00
|
|
|
ColumnPicker
|
2025-01-21 18:48:01 -06:00
|
|
|
Searchable
|
2025-05-23 02:17:06 -05:00
|
|
|
SearchProperty="g => g.Title"
|
|
|
|
|
Children="(g, dg) => dg.BaseGameId == g.Id"
|
2025-05-25 21:13:10 -05:00
|
|
|
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
|
|
|
}
|
2025-01-08 17:10:03 -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" />
|
2023-08-10 12:59:03 -05:00
|
|
|
|
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>
|
2023-02-04 12:18:10 -06:00
|
|
|
|
2025-01-16 00:35:01 -06:00
|
|
|
<BoundDataColumn Property="g => g.Title" Sortable DefaultSortOrder="SortDirection.Ascending" />
|
2025-06-22 21:23:03 +02:00
|
|
|
|
2025-05-23 02:17:06 -05:00
|
|
|
<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
|
|
|
|
2025-05-23 02:17:06 -05: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-06-22 21:23:03 +02:00
|
|
|
|
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-06-22 21:23:03 +02:00
|
|
|
|
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>
|
|
|
|
|
|
2025-05-23 02:17:06 -05:00
|
|
|
<DataActions TData="string">
|
2024-12-12 17:35:52 -06:00
|
|
|
<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>
|
|
|
|
|
</DataActions>
|
|
|
|
|
</Columns>
|
2025-01-28 18:23:49 -06:00
|
|
|
|
|
|
|
|
<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 {
|
2023-09-04 02:02:53 -05:00
|
|
|
bool Visibility = false;
|
2023-08-23 23:57:56 -05:00
|
|
|
|
2023-12-04 01:39:59 -06:00
|
|
|
IEnumerable<Game> Selected;
|
2025-01-28 18:23:49 -06:00
|
|
|
int Total;
|
2023-12-04 01:39:59 -06:00
|
|
|
|
2024-12-12 17:35:52 -06:00
|
|
|
DataTable<Game> Table;
|
2023-02-05 16:13:05 -06:00
|
|
|
|
2024-11-27 21:08:58 -06:00
|
|
|
string GetIcon(Game game)
|
2023-02-05 16:13:05 -06:00
|
|
|
{
|
2024-06-19 19:36:04 -05:00
|
|
|
var media = game?.Media?.FirstOrDefault(m => m.Type == SDK.Enums.MediaType.Icon);
|
2023-11-03 01:24:27 -05:00
|
|
|
|
|
|
|
|
if (media != null)
|
|
|
|
|
return $"/api/Media/{media.Id}/Download?fileId={media.FileId}";
|
|
|
|
|
else
|
|
|
|
|
return "/favicon.ico";
|
2023-02-04 12:18:10 -06:00
|
|
|
}
|
2023-03-02 18:50:24 -06:00
|
|
|
|
2024-11-27 21:08:58 -06:00
|
|
|
void Add()
|
2023-03-03 17:40:24 -06:00
|
|
|
{
|
|
|
|
|
NavigationManager.NavigateTo("/Games/Add");
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-27 21:08:58 -06:00
|
|
|
async Task Delete(Game game)
|
2023-03-15 18:09:48 -05:00
|
|
|
{
|
2025-02-01 02:21:34 -06:00
|
|
|
try
|
2023-11-27 20:28:51 -06:00
|
|
|
{
|
2025-02-01 02:21:34 -06:00
|
|
|
await GameService.DeleteAsync(game);
|
2024-02-23 17:25:40 -06:00
|
|
|
|
2025-02-01 02:21:34 -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-11-27 20:28:51 -06:00
|
|
|
}
|
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
|
|
|
}
|
2023-08-17 17:23:32 -05:00
|
|
|
|
2024-11-27 21:08:58 -06:00
|
|
|
async void AddToCollection()
|
2023-12-04 01:39:59 -06:00
|
|
|
{
|
|
|
|
|
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)
|
|
|
|
|
};
|
|
|
|
|
|
2024-01-12 21:25:56 -06:00
|
|
|
var modalRef = await ModalService.CreateModalAsync<AddToCollectionDialog, AddToCollectionOptions, IEnumerable<Collection>>(modalOptions, options);
|
2023-12-04 01:39:59 -06:00
|
|
|
|
2024-01-12 21:25:56 -06:00
|
|
|
modalRef.OnOk = async (collections) =>
|
2023-12-04 01:39:59 -06:00
|
|
|
{
|
2024-01-12 20:55:56 -06:00
|
|
|
Table.UnselectAll();
|
2025-01-16 00:35:01 -06:00
|
|
|
await Reload();
|
2023-12-04 01:39:59 -06:00
|
|
|
};
|
|
|
|
|
}
|
2025-01-08 17:10:03 -06:00
|
|
|
|
|
|
|
|
async Task OpenImportDialog()
|
|
|
|
|
{
|
|
|
|
|
var options = new ImportDialogOptions
|
|
|
|
|
{
|
|
|
|
|
Hint = "Only LCX files are supported for importing games"
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var modalOptions = new ModalOptions
|
|
|
|
|
{
|
|
|
|
|
Title = "Import Game",
|
|
|
|
|
DestroyOnClose = true,
|
2025-01-21 20:43:28 -06:00
|
|
|
MaskClosable = false,
|
2025-01-08 20:01:00 -06:00
|
|
|
Footer = null,
|
2025-01-08 17:10:03 -06:00
|
|
|
};
|
|
|
|
|
|
2025-06-22 21:23:03 +02:00
|
|
|
var modalRef = ModalService.CreateModal<ImportUploadDialog, ImportDialogOptions>(modalOptions, options);
|
|
|
|
|
modalRef.OnOk = modalRef.OnCancel = Reload;
|
2025-01-08 17:10:03 -06:00
|
|
|
}
|
2025-01-16 00:35:01 -06:00
|
|
|
|
|
|
|
|
async Task Reload()
|
|
|
|
|
{
|
|
|
|
|
Table.ReloadData();
|
|
|
|
|
}
|
2023-02-04 12:18:10 -06:00
|
|
|
}
|