@page "/admin/servers/nodes" @using MoonCore.Blazor.FlyonUi.Alerts @using MoonCore.Blazor.FlyonUi.DataTables @using MoonCore.Blazor.FlyonUi.Toasts @using MoonCore.Blazor.Tailwind.Alerts @using MoonCore.Helpers @using MoonCore.Models @using MoonlightServers.Shared.Http.Responses.Admin.Nodes @using MoonCore.Blazor.Tailwind.Components @using MoonCore.Blazor.Tailwind.Dt @using MoonCore.Blazor.Tailwind.Toasts @using MoonlightServers.Frontend.Services @using MoonlightServers.Shared.Http.Responses.Admin.Nodes.Statistics @using MoonlightServers.Shared.Http.Responses.Admin.Nodes.Sys @inject HttpApiClient ApiClient @inject NodeService NodeService @inject AlertService AlertService @inject ToastService ToastService @inject ILogger Logger @attribute [Authorize(Policy = "permissions:admin.servers.nodes.get")]
Create
@context.Name @{ var isFetched = StatusResponses.TryGetValue(context.Id, out var data); } @if (isFetched) { if (data == null) {
API Error
} else { if (data.RoundtripSuccess) {
Online (@(data.Version))
} else {
Error Details
} } } else {
Loading
}
@{ var isFetched = Statistics.TryGetValue(context.Id, out var data); } @if (isFetched) { if (data == null) {
API Error
} else {
@(Math.Round(data.Cpu.Usage))%
@(Math.Round((data.Memory.Total - data.Memory.Free - data.Memory.Cached) / (double)data.Memory.Total * 100))%
} } else {
Loading
}
@code { private DataTable Table; private Dictionary StatusResponses = new(); private Dictionary Statistics = new(); private async Task> LoadData(PaginationOptions options) { Statistics.Clear(); StatusResponses.Clear(); var result = await ApiClient.GetJson>( $"api/admin/servers/nodes?page={options.Page}&pageSize={options.PerPage}" ); Task.Run(async () => { foreach (var item in result.Items) { try { Statistics[item.Id] = await NodeService.GetStatistics(item.Id); } catch (Exception e) { Logger.LogWarning( "An error occured while fetching statistics for node {nodeId}: {e}", item.Id, e ); Statistics[item.Id] = null; } await InvokeAsync(StateHasChanged); try { StatusResponses[item.Id] = await NodeService.GetSystemStatus(item.Id); } catch (Exception e) { Logger.LogWarning( "An error occured while fetching status for node {nodeId}: {e}", item.Id, e ); StatusResponses[item.Id] = null; } await InvokeAsync(StateHasChanged); } }); return result; } private async Task Delete(NodeResponse response) { await AlertService.ConfirmDanger( "Node deletion", $"Do you really want to delete the node '{response.Name}'", async () => { await ApiClient.Delete($"api/admin/servers/nodes/{response.Id}"); await ToastService.Success("Successfully deleted node"); await Table.Refresh(); } ); } private async Task ShowErrorDetails(int id) { var data = StatusResponses.GetValueOrDefault(id); if (data == null) return; var message = $"Failed after {Math.Round(data.RoundtripTime.TotalSeconds, 2)} seconds: " + (data.RoundtripRemoteFailure ? "(Failed at node)" : "(Failed at api server)") + $" {data.RoundtripError}"; await AlertService.Danger("Node error details", message); } }