Initial version

This commit is contained in:
Sithis 2026-10-15 05:46:35 +02:00
commit e5b6226a85
68 changed files with 7338 additions and 0 deletions

View file

@ -0,0 +1,93 @@
@* Small stroke icon set (24×24 grid) drawn with currentColor, so icons follow the surrounding text color. *@
<svg class="icon @Class" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
@switch (Name)
{
case "transfer":
<path d="M4 9h15l-4-4"/>
<path d="M20 15H5l4 4"/>
break;
case "lock":
<rect x="5" y="11" width="14" height="10" rx="2"/>
<path d="M8 11V7a4 4 0 0 1 8 0v4"/>
break;
case "shield":
<path d="M12 3l7 3v6c0 4.5-3 7.7-7 9-4-1.3-7-4.5-7-9V6z"/>
<path d="M9 12l2 2 4-4"/>
break;
case "plus":
<path d="M12 5v14M5 12h14"/>
break;
case "join":
<path d="M14 4h4a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2h-4"/>
<path d="M10 16l4-4-4-4M14 12H4"/>
break;
case "arrow-up":
<path d="M12 19V5M6 11l6-6 6 6"/>
break;
case "arrow-down":
<path d="M12 5v14M6 13l6 6 6-6"/>
break;
case "arrow-right":
<path d="M5 12h14M13 6l6 6-6 6"/>
break;
case "file":
<path d="M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8z"/>
<path d="M14 3v5h5"/>
break;
case "upload":
<path d="M12 15V4M7 9l5-5 5 5"/>
<path d="M4 15v3a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-3"/>
break;
case "download":
<path d="M12 4v11M7 10l5 5 5-5"/>
<path d="M4 15v3a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-3"/>
break;
case "copy":
<rect x="9" y="9" width="11" height="11" rx="2"/>
<path d="M15 5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2"/>
break;
case "check":
<path d="M5 12.5l4.5 4.5L19 7.5"/>
break;
case "close":
<path d="M6 6l12 12M18 6L6 18"/>
break;
case "info":
<circle cx="12" cy="12" r="9"/>
<path d="M12 11v5M12 8h.01"/>
break;
case "alert":
<path d="M12 3.5L2.5 20h19z"/>
<path d="M12 10v4M12 17h.01"/>
break;
case "power":
<path d="M12 3v9"/>
<path d="M6.3 6.3a8 8 0 1 0 11.4 0"/>
break;
case "inbox":
<path d="M3 13l3-8h12l3 8v5a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/>
<path d="M3 13h5l1.5 2.5h5L16 13h5"/>
break;
case "clock":
<circle cx="12" cy="12" r="9"/>
<path d="M12 7v5l3 2"/>
break;
case "file-text":
<path d="M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8z"/>
<path d="M14 3v5h5M9 13h6M9 17h6"/>
break;
case "flag":
<path d="M5 21V4"/>
<path d="M5 4h12l-2.5 4.5L17 13H5"/>
break;
case "code":
<path d="M8 7l-5 5 5 5M16 7l5 5-5 5M14 4l-4 16"/>
break;
}
</svg>
@code {
[Parameter][EditorRequired] public string Name { get; set; } = string.Empty;
[Parameter] public string? Class { get; set; }
}

View file

@ -0,0 +1,38 @@
@implements IDisposable
@inject ServerStatusMonitor Monitor
@if (Monitor.Current is { } status)
{
<span class="server-load @LoadClass(status)" title="@Describe(status)" data-testid="server-load">
<span class="server-load-dot" aria-hidden="true"></span>
<span class="server-load-count">@status.ActiveConnections/@status.MaxConnections</span>
<span class="server-load-label">connections</span>
@if (status.QueuedClients > 0)
{
<span class="server-load-queue">· @status.QueuedClients queued</span>
}
</span>
}
@code {
protected override void OnInitialized()
{
Monitor.Changed += OnMonitorChanged;
Monitor.EnsureStarted();
}
public void Dispose() => Monitor.Changed -= OnMonitorChanged;
private void OnMonitorChanged() => _ = InvokeAsync(StateHasChanged);
private static string LoadClass(ServerStatus status) =>
status.ActiveConnections >= status.MaxConnections ? "is-full"
: status.ActiveConnections * 5 >= status.MaxConnections * 4 ? "is-high"
: "is-ok";
private static string Describe(ServerStatus status) =>
$"{status.ActiveConnections} of {status.MaxConnections} connections in use"
+ (status.QueuedClients > 0 ? $", {status.QueuedClients} waiting in the queue" : null);
}

View file

@ -0,0 +1,36 @@
/* Lives in the always-dark header, so the colors are fixed instead of following the theme tokens. */
.server-load {
display: inline-flex;
align-items: center;
gap: 0.375rem;
color: var(--header-muted);
font-size: 0.8125rem;
white-space: nowrap;
}
.server-load-dot {
width: 0.5rem;
height: 0.5rem;
border-radius: 50%;
background-color: #4cb167;
}
.is-high .server-load-dot {
background-color: #e0a63c;
}
.is-full .server-load-dot {
background-color: #ef6b65;
}
.server-load-count {
color: var(--header-text);
font-family: var(--mono);
font-variant-numeric: tabular-nums;
}
@media (max-width: 560px) {
.server-load-label {
display: none;
}
}