mirror of
https://github.com/chylex/Minecraft-Phantom-Panel.git
synced 2024-10-30 05:42:47 +01:00
118 lines
4.1 KiB
Plaintext
118 lines
4.1 KiB
Plaintext
@page "/agents"
|
|
@using System.Collections.Immutable
|
|
@using Phantom.Common.Data.Agent
|
|
@using Phantom.Common.Messages.ToAgent
|
|
@using Phantom.Server.Services.Agents
|
|
@using Phantom.Utils.Collections
|
|
@implements IDisposable
|
|
@inject AgentAuthToken AgentAuthToken
|
|
@inject AgentManager AgentManager
|
|
@inject AgentStatsManager AgentStatsManager
|
|
|
|
<h1>Agents</h1>
|
|
|
|
<table class="table align-middle">
|
|
<thead>
|
|
<tr>
|
|
<th style="min-width: 200px;">Name</th>
|
|
<th style="width: 275px;" class="text-end">Instances</th>
|
|
<th style="width: 275px;" class="text-end">Memory</th>
|
|
<th style="width: 150px;" class="text-end">Version</th>
|
|
<th style="width: 350px;">Identifier</th>
|
|
<th style="width: 150px;" class="text-center">Status</th>
|
|
<th style="width: 250px;" class="text-right">Last Ping</th>
|
|
<th style="width: 200px;">Actions</th>
|
|
</tr>
|
|
</thead>
|
|
@if (!agentTable.IsEmpty) {
|
|
<tbody>
|
|
@foreach (var row in agentTable) {
|
|
var agent = row.Agent;
|
|
var stats = agentStats.TryGetValue(agent.Guid, out var s) ? s : null;
|
|
var usedInstances = stats?.UsedInstances;
|
|
var usedMemory = stats?.UsedMemory.InMegabytes;
|
|
|
|
<tr>
|
|
<td>@agent.Name</td>
|
|
<td class="text-end">
|
|
<ProgressBar Value="@(usedInstances ?? 0)" Maximum="@agent.MaxInstances">
|
|
@(usedInstances?.ToString() ?? "?") / @agent.MaxInstances
|
|
</ProgressBar>
|
|
</td>
|
|
<td class="text-end">
|
|
<ProgressBar Value="@(usedMemory ?? 0)" Maximum="@agent.MaxMemory.InMegabytes">
|
|
@(usedMemory?.ToString() ?? "?") / @agent.MaxMemory.InMegabytes MB
|
|
</ProgressBar>
|
|
</td>
|
|
<td class="text-end">@agent.Version</td>
|
|
<td>
|
|
<code class="text-uppercase">@agent.Guid.ToString()</code>
|
|
</td>
|
|
@if (agent.IsOnline) {
|
|
<td class="text-center text-success">Online</td>
|
|
<td class="text-right"></td>
|
|
<td>
|
|
<button type="button" class="btn btn-danger btn-sm" @onclick="() => ShutdownAgent(agent.Guid)" disabled="@row.IsShutdownButtonDisabled">Shutdown</button>
|
|
</td>
|
|
}
|
|
else {
|
|
<td class="text-center text-danger">Offline</td>
|
|
@if (agent.LastPing is {} lastPing) {
|
|
<td class="text-right">
|
|
<time datetime="@lastPing.ToString("o")" data-time-type="relative">@lastPing.ToString()</time>
|
|
</td>
|
|
}
|
|
else {
|
|
<td class="text-right">-</td>
|
|
}
|
|
<td>-</td>
|
|
}
|
|
</tr>
|
|
}
|
|
</tbody>
|
|
}
|
|
<tfoot>
|
|
<tr>
|
|
<td colspan="8">
|
|
@if (agentTable.IsEmpty) {
|
|
<text>No agents registered.</text>
|
|
}
|
|
Register agents using the token: <code>@AgentAuthToken</code>
|
|
</td>
|
|
</tr>
|
|
</tfoot>
|
|
</table>
|
|
|
|
@code {
|
|
|
|
private readonly Table<AgentRow, Guid> agentTable = new();
|
|
private ImmutableDictionary<Guid, AgentStats> agentStats = ImmutableDictionary<Guid, AgentStats>.Empty;
|
|
|
|
private readonly record struct AgentRow(Agent Agent, bool IsShutdownButtonDisabled = false);
|
|
|
|
protected override void OnInitialized() {
|
|
AgentManager.AgentsChanged.Subscribe(this, agents => {
|
|
var sortedAgents = agents.Sort(static (a1, a2) => a1.Name.CompareTo(a2.Name));
|
|
agentTable.UpdateFrom(sortedAgents, static agent => agent.Guid, static agent => new AgentRow(agent), static (agent, row) => row with { Agent = agent });
|
|
InvokeAsync(StateHasChanged);
|
|
});
|
|
|
|
AgentStatsManager.AgentStatsChanged.Subscribe(this, agentStats => {
|
|
this.agentStats = agentStats.ToImmutableDictionary(static stats => stats.Agent.Guid);
|
|
InvokeAsync(StateHasChanged);
|
|
});
|
|
}
|
|
|
|
private async Task ShutdownAgent(Guid guid) {
|
|
if (agentTable.TryUpdateRow(guid, static row => row with { IsShutdownButtonDisabled = true })) {
|
|
await AgentManager.SendMessage(guid, new ShutdownAgentMessage());
|
|
}
|
|
}
|
|
|
|
void IDisposable.Dispose() {
|
|
AgentManager.AgentsChanged.Unsubscribe(this);
|
|
AgentStatsManager.AgentStatsChanged.Unsubscribe(this);
|
|
}
|
|
|
|
}
|