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

250 lines
8.6 KiB
Text

@page "/Servers"
@using LANCommander.Server.UI.Pages.Servers.Components
@using Microsoft.EntityFrameworkCore;
@using System.Web
@attribute [Authorize(Roles = RoleService.AdministratorRoleName)]
@inject DatabaseServiceFactory DatabaseServiceFactory
@inject ServerProcessService ServerProcessService
@inject NavigationManager NavigationManager
@inject IMessageService MessageService
<PageHeader Title="Servers">
<PageHeaderExtra>
<Space Direction="DirectionVHType.Horizontal">
@if (SelectedServers != null && SelectedServers.Count() > 0)
{
<SpaceItem>
<Button Type="@ButtonType.Primary" OnClick="() => StartServers()">Start</Button>
<Popconfirm OnConfirm="() => StopServers()" Title="Are you sure you want to kill these server processes?">
<Button Danger Type="@ButtonType.Primary">Stop</Button>
</Popconfirm>
</SpaceItem>
}
<SpaceItem>
<Search Placeholder="Search" @bind-Value="Search" BindOnInput DebounceMilliseconds="150" OnChange="() => LoadData()" />
</SpaceItem>
<SpaceItem>
<Button Type="@ButtonType.Default" OnClick="ImportUploadDialog.Open">Import</Button>
</SpaceItem>
<SpaceItem>
<Button OnClick="() => Add()" Type="@ButtonType.Primary">Add Server</Button>
</SpaceItem>
</Space>
</PageHeaderExtra>
</PageHeader>
<TableColumnPicker @ref="Picker" Key="Servers" @bind-Visible="ColumnPickerVisible" />
<Table
TItem="Server"
DataSource="@Servers"
Loading="@Loading"
PageSize="@PageSize"
PageIndex="@PageIndex"
Total="@TotalCount"
OnPageIndexChange="PageIndexChanged"
OnPageSizeChange="PageSizeChanged"
Size="@TableSize.Small"
@bind-SelectedRows="SelectedServers"
Responsive>
<Selection Key="@(context.Id.ToString())" />
<PropertyColumn
Property="s => s.Game"
Hidden="@(Picker.IsColumnHidden("Game"))"
DefaultSortOrder="@SortDirection.Ascending"
Sortable
SorterCompare="@((a, b) => a == null ? -1 : b == null ? 1 : String.CompareOrdinal(!String.IsNullOrWhiteSpace(a.SortTitle) ? a.SortTitle : a.Title, !String.IsNullOrWhiteSpace(b.SortTitle) ? b.SortTitle : b.Title))">
<Image Src="@GetIcon(context.Game)" Height="32" Width="32" Preview="false"></Image>
@context.Game?.Title
</PropertyColumn>
<PropertyColumn Property="s => s.Name" Sortable Hidden="@(Picker.IsColumnHidden("Name"))" />
<PropertyColumn Property="s => s.Port" Sortable Hidden="@(Picker.IsColumnHidden("Port"))" />
<PropertyColumn Property="s => s.CreatedOn" Format="MM/dd/yyyy hh:mm tt" Sortable Hidden="@(Picker.IsColumnHidden("Created On"))" />
<PropertyColumn Property="s => s.CreatedBy != null ? s.CreatedBy.UserName : String.Empty" Title="Created By" Sortable Hidden="@(Picker.IsColumnHidden("Created By"))" />
<PropertyColumn Property="s => s.UpdatedOn" Format="MM/dd/yyyy hh:mm tt" Sortable Hidden="@(Picker.IsColumnHidden("Updated On", false))" />
<PropertyColumn Property="s => s.UpdatedBy != null ? s.UpdatedBy.UserName : String.Empty" Title="Updated By" Sortable Hidden="@(Picker.IsColumnHidden("Updated By"))" />
<ActionColumn Title="" Style="text-align: right; white-space: nowrap">
<TitleTemplate>
<div style="text-align: right">
<Button Icon="@IconType.Outline.Edit" Type="@ButtonType.Text" OnClick="() => OpenColumnPicker()" />
</div>
</TitleTemplate>
<ChildContent>
<ServerControl ServerId="context.Id" />
<Space Direction="DirectionVHType.Horizontal">
<SpaceItem>
<a href="/Servers/@(context.Id)" class="ant-btn ant-btn-default">Edit</a>
</SpaceItem>
<SpaceItem>
<Popconfirm OnConfirm="() => Delete(context)" Title="Are you sure you want to delete this server?">
<Button Icon="@IconType.Outline.Close" Type="@ButtonType.Text" Danger />
</Popconfirm>
</SpaceItem>
</Space>
</ChildContent>
</ActionColumn>
</Table>
<ImportUploadDialog @ref="ImportUploadDialog" OnServerImported="LoadData">
<Hint>Only LCX files are supported for importing servers</Hint>
</ImportUploadDialog>
@code {
IEnumerable<Server> Servers { get; set; } = new List<Server>();
bool Loading = true;
int PageIndex = 1;
int PageSize = 50;
int TotalCount = 0;
string Search = "";
string Url;
ImportUploadDialog ImportUploadDialog;
IEnumerable<Server> SelectedServers;
TableColumnPicker Picker;
bool ColumnPickerVisible = false;
protected override async Task OnInitializedAsync()
{
Url = NavigationManager.Uri;
NavigationManager.LocationChanged += LocationChanged;
LoadTableParameter();
await LoadData();
Loading = false;
}
async Task LoadData()
{
var fuzzySearch = Search.ToLower().Trim();
using (var serverService = DatabaseServiceFactory.Create<ServerService>())
{
var results = await serverService
.Query((q) =>
{
return q.Include(s => s.Game).ThenInclude(g => g.Media.Where(m => m.Type == SDK.Enums.MediaType.Icon));
})
.Include(s => s.CreatedBy)
.Include(s => s.UpdatedBy)
.SortBy(s => s.Name)
.PaginateAsync(
s => s.Name.ToLower().Contains(fuzzySearch) || (s.Game != null && (s.Game.Title.ToLower().Contains(fuzzySearch) || s.Game.SortTitle.ToLower().Contains(fuzzySearch))),
PageIndex,
PageSize
);
TotalCount = results.Count;
Servers = results.Results;
}
}
async void LocationChanged(object sender, LocationChangedEventArgs e)
{
Url = e.Location;
LoadTableParameter();
await LoadData();
}
void LoadTableParameter()
{
var uri = NavigationManager.ToAbsoluteUri(Url);
var query = HttpUtility.ParseQueryString(uri.Query);
PageIndex = int.TryParse(query["Page"], out var index) ? index > 0 ? index : 1 : 1;
PageSize = int.TryParse(query["Size"], out var size) ? size > 0 ? size : 50 : 50;
if (query["Search"] != null)
Search = query["Search"];
else
Search = "";
}
void PageIndexChanged(PaginationEventArgs args)
{
NavigationManager.NavigateTo($"/Servers?Page={args.Page}&Size={args.PageSize}{(Search != "" ? "&Search=" + Search : "")}");
}
void PageSizeChanged(PaginationEventArgs args)
{
NavigationManager.NavigateTo($"/Servers?Page={args.Page}&Size={args.PageSize}{(Search != "" ? "&Search=" + Search : "")}");
}
void SearchChanged()
{
NavigationManager.NavigateTo($"/Servers?Search={Search}&Size={PageSize}");
}
void Add()
{
NavigationManager.NavigateTo("/Servers/Add");
}
void Edit(Server server)
{
NavigationManager.NavigateTo($"/Servers/{server.Id}/General");
}
async Task Delete(Server server)
{
Servers = new List<Server>();
Loading = true;
using (var serverService = DatabaseServiceFactory.Create<ServerService>())
{
await serverService.DeleteAsync(server);
}
await LoadData();
Loading = false;
}
string GetIcon(Game game)
{
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";
}
async Task StartServers()
{
foreach (var server in SelectedServers)
{
try
{
var status = ServerProcessService.GetStatus(server);
if (status == ServerProcessStatus.Stopped || status == ServerProcessStatus.Error)
{
ServerProcessService.StartServerAsync(server.Id);
}
}
catch { }
}
}
void StopServers()
{
foreach (var server in SelectedServers)
{
if (ServerProcessService.GetStatus(server) == ServerProcessStatus.Running)
ServerProcessService.StopServerAsync(server.Id);
}
}
async Task OpenColumnPicker()
{
ColumnPickerVisible = true;
}
async Task CloseColumnPicker()
{
ColumnPickerVisible = false;
}
}