Refactored ui. Improved console experience. Added command endpoint
This commit is contained in:
@@ -0,0 +1,217 @@
|
||||
@using Microsoft.Extensions.Logging
|
||||
@using MoonCore.Blazor.FlyonUi.Components
|
||||
@using MoonCore.Blazor.FlyonUi.Toasts
|
||||
@using MoonCore.Helpers
|
||||
@using MoonlightServers.Frontend.Services
|
||||
@using MoonlightServers.Shared.Http.Responses.Admin.Nodes
|
||||
@using MoonlightServers.Shared.Http.Responses.Admin.Nodes.Statistics
|
||||
|
||||
@inject NodeService NodeService
|
||||
@inject ToastService ToastService
|
||||
@inject ILogger<Overview> Logger
|
||||
|
||||
@implements IDisposable
|
||||
|
||||
<LazyLoader Load="Load">
|
||||
|
||||
<div class="mb-3 mt-5 text-xl font-semibold">
|
||||
Overview
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 lg:grid-cols-3 gap-5">
|
||||
<div class="col-span-1 card card-body">
|
||||
<div class="flex justify-between">
|
||||
<p class="text-xl font-semibold text-base-content">
|
||||
@(Math.Round(Statistics.Cpu.Usage, 2))%
|
||||
</p>
|
||||
<i class="icon-cpu text-4xl text-primary"></i>
|
||||
</div>
|
||||
<div class="text-base text-base-content/90">
|
||||
<span class="truncate">
|
||||
CPU: @Statistics.Cpu.Model
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-span-1 card card-body">
|
||||
<div class="flex justify-between">
|
||||
<p class="text-xl font-semibold text-base-content">
|
||||
@(Formatter.FormatSize(Statistics.Memory.Total - Statistics.Memory.Available))
|
||||
/
|
||||
@(Formatter.FormatSize(Statistics.Memory.Total))
|
||||
</p>
|
||||
<i class="icon-memory-stick text-4xl text-primary"></i>
|
||||
</div>
|
||||
<div class="text-base text-base-content/90">
|
||||
Memory
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-span-1 card card-body">
|
||||
<div class="flex justify-between">
|
||||
<div class="text-xl font-semibold text-base-content">
|
||||
@(Formatter.FormatSize(Statistics.Memory.SwapTotal - Statistics.Memory.SwapFree))
|
||||
/
|
||||
@(Formatter.FormatSize(Statistics.Memory.SwapTotal))
|
||||
</div>
|
||||
<i class="icon-shapes text-4xl text-primary"></i>
|
||||
</div>
|
||||
<div class="text-base text-base-content/90">
|
||||
Swap
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3 mt-5 text-xl font-semibold">
|
||||
CPU
|
||||
</div>
|
||||
|
||||
<div class="card card-body grid grid-cols-1 lg:grid-cols-2 gap-y-2 gap-x-5">
|
||||
@{
|
||||
var i = 0;
|
||||
}
|
||||
|
||||
@foreach (var usage in Statistics.Cpu.UsagePerCore)
|
||||
{
|
||||
var percentRounded = Math.Round(usage, 2);
|
||||
|
||||
<div class="flex flex-row items-center col-span-1">
|
||||
<div class="text-sm text-base-content/90 me-1.5 grow-0 flex flex-col">
|
||||
<span>#@(i)</span>
|
||||
</div>
|
||||
<div class="grow">
|
||||
<div class="progress h-2" role="progressbar">
|
||||
<div class="progress-bar transition-all duration-300 ease-in-out @(GetBackgroundColorByPercent(percentRounded))" style="width: @(usage)%"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
i++;
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="mb-3 mt-5 text-xl font-semibold">
|
||||
Disks
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 lg:grid-cols-3 gap-5">
|
||||
@foreach (var disk in Statistics.Disks)
|
||||
{
|
||||
var usedPercent = Math.Round((disk.DiskTotal - disk.DiskFree) / (double)disk.DiskTotal * 100, 2);
|
||||
var iNodesPercent = Math.Round((disk.InodesTotal - disk.InodesFree) / (double)disk.InodesTotal * 100, 2);
|
||||
|
||||
<div class="col-span-1 card card-body">
|
||||
<div class="flex items-center">
|
||||
<div class="grow">
|
||||
<div class="progress h-2" role="progressbar">
|
||||
<div class="progress-bar transition-all duration-300 ease-in-out @(GetBackgroundColorByPercent(usedPercent))" style="width: @(usedPercent)%"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-sm text-base-content/90 mt-2.5 flex flex-col">
|
||||
<div>
|
||||
Device: <span class="font-semibold">@disk.Device</span> - Mounted at: <span class="font-semibold truncate">@disk.MountPath</span>
|
||||
</div>
|
||||
<div>
|
||||
Used: <span class="font-semibold">@Formatter.FormatSize(disk.DiskTotal - disk.DiskFree)</span>
|
||||
Total: <span class="font-semibold">@Formatter.FormatSize(disk.DiskTotal)</span>
|
||||
</div>
|
||||
<div>
|
||||
INodes: <span class="font-semibold">@(iNodesPercent)%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="mb-3 mt-5 text-xl font-semibold">
|
||||
Docker
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 lg:grid-cols-3 gap-5">
|
||||
<div class="col-span-1 card card-body">
|
||||
<div class="flex justify-between">
|
||||
<p class="text-xl font-semibold text-base-content">
|
||||
@Formatter.FormatSize(DockerStatistics.ImagesUsed) (@Formatter.FormatSize(DockerStatistics.ImagesReclaimable) unused)
|
||||
</p>
|
||||
<i class="icon-gallery-horizontal-end text-4xl text-primary"></i>
|
||||
</div>
|
||||
<div class="text-base text-base-content/90">
|
||||
Images
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-span-1 card card-body">
|
||||
<div class="flex justify-between">
|
||||
<p class="text-xl font-semibold text-base-content">
|
||||
@Formatter.FormatSize(DockerStatistics.ContainersUsed) ( @Formatter.FormatSize(DockerStatistics.ContainersReclaimable) unused)
|
||||
</p>
|
||||
<i class="icon-container text-4xl text-primary"></i>
|
||||
</div>
|
||||
<div class="text-base text-base-content/90">
|
||||
Containers
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-span-1 card card-body">
|
||||
<div class="flex justify-between">
|
||||
<p class="text-xl font-semibold text-base-content">
|
||||
@Formatter.FormatSize(DockerStatistics.BuildCacheUsed) (@Formatter.FormatSize(DockerStatistics.BuildCacheReclaimable) unused)
|
||||
</p>
|
||||
<i class="icon-hard-hat text-4xl text-primary"></i>
|
||||
</div>
|
||||
<div class="text-base text-base-content/90">
|
||||
Build Cache
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</LazyLoader>
|
||||
|
||||
@code
|
||||
{
|
||||
[Parameter] public NodeResponse Node { get; set; }
|
||||
|
||||
private StatisticsResponse Statistics;
|
||||
private DockerStatisticsResponse DockerStatistics;
|
||||
|
||||
private Timer? UpdateTimer;
|
||||
|
||||
private async Task Load(LazyLoader _)
|
||||
{
|
||||
Statistics = await NodeService.GetStatistics(Node.Id);
|
||||
DockerStatistics = await NodeService.GetDockerStatistics(Node.Id);
|
||||
|
||||
UpdateTimer = new Timer(HandleUpdate, null, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(3));
|
||||
}
|
||||
|
||||
private async void HandleUpdate(object? _)
|
||||
{
|
||||
try
|
||||
{
|
||||
Statistics = await NodeService.GetStatistics(Node.Id);
|
||||
DockerStatistics = await NodeService.GetDockerStatistics(Node.Id);
|
||||
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.LogWarning("An error occured while fetching status update: {e}", e);
|
||||
await ToastService.Error("Unable to fetch status update", e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private string GetBackgroundColorByPercent(double percent)
|
||||
{
|
||||
if (percent < 70)
|
||||
return "bg-success";
|
||||
else if (percent < 80)
|
||||
return "bg-warning";
|
||||
else
|
||||
return "bg-error";
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
UpdateTimer?.Dispose();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user