Files
dnsmasq-webui/src/DnsmasqWebUI/Components/Dnsmasq/Logs/LogsSection.razor
T

41 lines
2.1 KiB
Plaintext

@namespace DnsmasqWebUI.Components.Dnsmasq.Logs
@* Recent logs — live view via SignalR from LogsCommand; client polls at interval, server pushes deltas *@
@using DnsmasqWebUI.Models.Logs
@using Microsoft.AspNetCore.SignalR.Client
@inject NavigationManager Navigation
@inject IJSRuntime JSRuntime
@inject ILogger<LogsSection> Logger
@implements IAsyncDisposable
@if (_status != null && (_status.LogsConfigured || _status.LogsPath != null))
{
<p class="mb-1 mt-3 d-flex align-items-center justify-content-between flex-wrap gap-1">
<span class="d-flex align-items-center gap-1">
<strong>Recent logs</strong>
<span class="status-dot d-inline-block rounded-circle flex-shrink-0 bg-success @(_justUpdated ? "status-dot-updating" : null)" style="width: 0.5rem; height: 0.5rem;" title="@(_justUpdated ? "Updating…" : "Live")" aria-hidden="true"></span>
</span>
<button type="button" class="btn btn-link btn-sm p-0 text-body" aria-label="Recent logs polling settings" @onclick="() => OnOpenSettings.InvokeAsync()" title="Configure recent logs polling interval">
<i class="bi bi-gear-fill bi-gear-sm" aria-hidden="true"></i>
</button>
</p>
@if (_status.LogsConfigured)
{
<p class="text-muted small mb-1"><code>@_status.LogsCommand</code></p>
}
@if (_status.LogsConfigured)
{
<LogsPreView Id="dnsmasq-logs-pre" Placeholder="@_initialPlaceholder" Freeze="_logsContentReceived" />
}
<div class="mt-2 d-flex flex-wrap gap-2 align-items-center">
<button class="btn btn-primary btn-sm" @onclick="RequestRefreshAsync" disabled="@_refreshing">Refresh</button>
@if (_status.LogsPath != null)
{
<a href="api/status/logs/download" download="dnsmasq.log" class="btn btn-primary btn-sm">Download logs</a>
}
else
{
<button type="button" class="btn btn-primary btn-sm" disabled title="No log file path detected. Set log-facility=/path/to/file in your dnsmasq config to enable download.">Download logs</button>
}
</div>
}