Files
Moonlight/Moonlight/Shared/Views/Admin/Nodes/View.razor
2023-03-20 15:55:44 +01:00

357 lines
12 KiB
Plaintext

@page "/admin/nodes/view/{id:int}"
@using Moonlight.App.Repositories
@using Moonlight.App.Database.Entities
@using Moonlight.App.Helpers
@using Moonlight.App.Models.Daemon.Resources
@using Moonlight.App.Models.Wings.Resources
@using Moonlight.App.Services
@inject NodeRepository NodeRepository
@inject NodeService NodeService
<OnlyAdmin>
<LazyLoader Load="Load">
@if (Node == null)
{
<div class="alert alert-warning">
<TL>No node with this id found</TL>
</div>
}
else
{
<div class="d-flex flex-center">
<div class="row">
<div class="card">
<div class="card-header">
<h3 class="card-title">
<span class="fw-bold fs-3">
@(Node.Name) <TL>details</TL>
</span>
</h3>
</div>
<div class="card-body">
<div class="row g-3 g-lg-6">
<div class="col">
<div class="bg-gray-100 bg-opacity-70 rounded-2 px-6 py-5">
<div class="symbol symbol-30px me-5 mb-8">
<span class="symbol-label">
<i class="text-primary bx bx-lg bx-chip"></i>
</span>
</div>
<div class="m-0">
<span class="fw-bolder d-block fs-2qx lh-1 ls-n1 mb-1">
@if (CpuStats == null)
{
<span class="text-muted">
<TL>Loading</TL>
</span>
}
else
{
<span>
@(CpuStats.Usage)% <TL>of</TL> @(CpuStats.Cores) <TL>Cores used</TL>
</span>
}
</span>
<span class="fw-semibold fs-6">
@if (CpuStats == null)
{
<span class="text-muted">
<TL>Loading</TL>
</span>
}
else
{
<span>@(CpuStats.Model)</span>
}
</span>
</div>
</div>
</div>
<div class="col">
<div class="bg-gray-100 bg-opacity-70 rounded-2 px-6 py-5">
<div class="symbol symbol-30px me-5 mb-8">
<span class="symbol-label">
<i class="text-primary bx bx-lg bx-microchip"></i>
</span>
</div>
<div class="m-0">
<span class="fw-bolder d-block fs-2qx lh-1 ls-n1 mb-1">
@if (MemoryStats == null)
{
<span class="text-muted">
<TL>Loading</TL>
</span>
}
else
{
<span>
@(Formatter.FormatSize(MemoryStats.Used * 1024D * 1024D)) <TL>of</TL> @(Formatter.FormatSize(MemoryStats.Total * 1024D * 1024D)) <TL>used</TL>
</span>
}
</span>
<span class="fw-semibold fs-6">
@if (MemoryStats == null)
{
<span class="text-muted">
<TL>Loading</TL>
</span>
}
else
{
if (MemoryStats.Sticks.Any())
{
foreach (var stick in SortMemorySticks(MemoryStats.Sticks))
{
<span>@(stick)</span>
<br/>
}
}
else
{
<span>No memory sticks detected</span>
}
}
</span>
</div>
</div>
</div>
<div class="col">
<div class="bg-gray-100 bg-opacity-70 rounded-2 px-6 py-5">
<div class="symbol symbol-30px me-5 mb-8">
<span class="symbol-label">
<i class="text-primary bx bx-lg bx-microchip"></i>
</span>
</div>
<div class="m-0">
<span class="fw-bolder d-block fs-2qx lh-1 ls-n1 mb-1">
@if (DiskStats == null)
{
<span class="text-muted">
<TL>Loading</TL>
</span>
}
else
{
<span>
@(Formatter.FormatSize(DiskStats.TotalSize - DiskStats.FreeBytes)) <TL>of</TL> @(Formatter.FormatSize(DiskStats.TotalSize)) <TL>used</TL>
</span>
}
</span>
<span class="fw-semibold fs-6">
@if (DiskStats == null)
{
<span class="text-muted">
<TL>Loading</TL>
</span>
}
else
{
<span>@(DiskStats.Name) - @(DiskStats.DriveFormat)</span>
}
</span>
</div>
</div>
</div>
</div>
<div class="mt-3 row g-3 g-lg-6">
<div class="col">
<div class="bg-gray-100 bg-opacity-70 rounded-2 px-6 py-5">
<div class="symbol symbol-30px me-5 mb-8">
<span class="symbol-label">
<i class="text-primary bx bx-lg bx-purchase-tag"></i>
</span>
</div>
<div class="m-0">
<span class="fw-bolder d-block fs-2qx lh-1 ls-n1 mb-1">
@if (SystemStatus == null)
{
<span class="text-muted">
<TL>Loading</TL>
</span>
}
else
{
<span class="text-success">
<TL>Online</TL>
</span>
}
</span>
<span class="fw-semibold fs-6">
@if (SystemStatus == null)
{
<span class="text-muted">
<TL>Loading</TL>
</span>
}
else
{
<span>@(SystemStatus.Version)</span>
}
</span>
</div>
</div>
</div>
<div class="col">
<div class="bg-gray-100 bg-opacity-70 rounded-2 px-6 py-5">
<div class="symbol symbol-30px me-5 mb-8">
<span class="symbol-label">
<i class="text-primary bx bx-lg bx-fingerprint"></i>
</span>
</div>
<div class="m-0">
<span class="fw-bolder d-block fs-2qx lh-1 ls-n1 mb-1">
@if (SystemStatus == null)
{
<span class="text-muted">
<TL>Loading</TL>
</span>
}
else
{
<span>
@(SystemStatus.KernelVersion) - @(SystemStatus.Architecture)
</span>
}
</span>
<span class="fw-semibold fs-6">
@if (SystemStatus == null)
{
<span class="text-muted">
<TL>Loading</TL>
</span>
}
else
{
<TL>Host system information</TL>
}
</span>
</div>
</div>
</div>
<div class="col">
<div class="bg-gray-100 bg-opacity-70 rounded-2 px-6 py-5">
<div class="symbol symbol-30px me-5 mb-8">
<span class="symbol-label">
<i class="text-primary bx bx-lg bxl-docker"></i>
</span>
</div>
<div class="m-0">
<span class="fw-bolder d-block fs-2qx lh-1 ls-n1 mb-1">
@if (ContainerStats == null)
{
<span class="text-muted">
<TL>Loading</TL>
</span>
}
else
{
<span>
<TL>@(ContainerStats.Containers.Count)</TL>
</span>
}
</span>
<span class="fw-semibold fs-6">
@if (ContainerStats == null)
{
<span class="text-muted">
<TL>Loading</TL>
</span>
}
else
{
<TL>Docker containers running</TL>
}
</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="mt-5 card card-body">
<div class="d-flex justify-content-end">
<a href="/admin/nodes" class="btn btn-primary">
<TL>Cancel</TL>
</a>
</div>
</div>
</div>
</div>
}
</LazyLoader>
</OnlyAdmin>
@code
{
[Parameter]
public int Id { get; set; }
private Node? Node;
private CpuStats CpuStats;
private MemoryStats MemoryStats;
private DiskStats DiskStats;
private SystemStatus SystemStatus;
private ContainerStats ContainerStats;
private async Task Load(LazyLoader arg)
{
Node = NodeRepository
.Get()
.FirstOrDefault(x => x.Id == Id);
if (Node != null)
{
Task.Run(async () =>
{
try
{
SystemStatus = await NodeService.GetStatus(Node);
await InvokeAsync(StateHasChanged);
CpuStats = await NodeService.GetCpuStats(Node);
await InvokeAsync(StateHasChanged);
MemoryStats = await NodeService.GetMemoryStats(Node);
await InvokeAsync(StateHasChanged);
DiskStats = await NodeService.GetDiskStats(Node);
await InvokeAsync(StateHasChanged);
ContainerStats = await NodeService.GetContainerStats(Node);
await InvokeAsync(StateHasChanged);
}
catch (Exception e)
{
// ignored
}
});
}
}
private List<string> SortMemorySticks(List<MemoryStats.MemoryStick> sticks)
{
// Thank you ChatGPT <3
var groupedMemory = sticks.GroupBy(memory => new { memory.Type, memory.Size })
.Select(group => new
{
Type = group.Key.Type,
Size = group.Key.Size,
Count = group.Count()
});
var sortedMemory = groupedMemory.OrderBy(memory => memory.Type)
.ThenBy(memory => memory.Size);
List<string> sortedList = sortedMemory.Select(memory =>
{
string sizeString = $"{memory.Size}GB";
return $"{memory.Count}x {memory.Type} {sizeString}";
}).ToList();
return sortedList;
}
}