mirror of
https://github.com/alexhopeoconnor/dnsmasq-webui.git
synced 2026-10-16 23:01:35 +10:00
- NavMenu: show short date in update-check tooltip when last check was not today - Settings modal: expand/collapse all sections with bi-arrows-expand/collapse icons - Effective config: add Expand all button (bi-arrows-expand), same icon style as toolbar - Rename settings-modal.js to dialog.js; add config-option-help.js, JS extension helpers - Config option help modal and client settings/dialog wiring updates
155 lines
11 KiB
Plaintext
155 lines
11 KiB
Plaintext
@namespace DnsmasqWebUI.Components.Modals
|
|
@implements IAsyncDisposable
|
|
@inject IJSRuntime JSRuntime
|
|
@inject IClientSettingsService ClientSettingsService
|
|
@inject ILogger<SettingsModal> Logger
|
|
|
|
@if (IsVisible)
|
|
{
|
|
<dialog @ref="_dialogRef" class="settings-modal-dialog">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">@Title</h5>
|
|
<button type="button" class="btn-close" @onclick="Close" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
@if (_validationErrors.Count > 0)
|
|
{
|
|
<div class="alert alert-danger mb-3" role="alert">
|
|
<strong>Please fix the following:</strong>
|
|
<ul class="mb-0 mt-1">
|
|
@foreach (var err in _validationErrors)
|
|
{
|
|
<li>@err</li>
|
|
}
|
|
</ul>
|
|
</div>
|
|
}
|
|
@if (SettingsContext == SettingsModalContext.All)
|
|
{
|
|
<div class="mb-3">
|
|
<div class="d-flex align-items-center gap-2 mb-1">
|
|
<label class="form-label mb-0">Search settings</label>
|
|
<div class="d-flex gap-1 ms-auto" role="group" aria-label="Expand or collapse all sections">
|
|
<button type="button" class="btn btn-sm btn-outline-secondary settings-expand-collapse-btn" title="Expand all sections" aria-label="Expand all sections" @onclick="ExpandAllGroups">
|
|
<i class="bi bi-arrows-expand" aria-hidden="true"></i>
|
|
</button>
|
|
<button type="button" class="btn btn-sm btn-outline-secondary settings-expand-collapse-btn" title="Collapse all sections" aria-label="Collapse all sections" @onclick="CollapseAllGroups">
|
|
<i class="bi bi-arrows-collapse" aria-hidden="true"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<input type="search" class="form-control" placeholder="Search..." autocomplete="off"
|
|
@bind="_searchTerm" @bind:event="oninput" @bind:after="FilterSettings" />
|
|
</div>
|
|
}
|
|
@foreach (var group in GetVisibleGroups())
|
|
{
|
|
var isAllSections = SettingsContext == SettingsModalContext.All;
|
|
var isExpanded = isAllSections ? IsGroupExpanded(group) : true;
|
|
<div class="settings-group">
|
|
@if (isAllSections)
|
|
{
|
|
<button type="button" class="settings-group-header @(isExpanded ? "expanded" : "")"
|
|
@onclick="() => ToggleGroup(group.Id)"
|
|
aria-expanded="@isExpanded"
|
|
aria-controls="group-@group.Id">
|
|
<span class="settings-group-title">@group.DisplayName</span>
|
|
<span class="settings-group-chevron" aria-hidden="true"></span>
|
|
</button>
|
|
}
|
|
else
|
|
{
|
|
<h6 class="settings-group-title settings-group-title-static mb-2 mt-3">@group.DisplayName</h6>
|
|
}
|
|
<div id="group-@group.Id" class="settings-group-content @(isExpanded ? "expanded" : "")"
|
|
role="region" aria-label="@group.DisplayName">
|
|
@foreach (var key in group.SectionKeys)
|
|
{
|
|
@if (ShouldShowSection(key))
|
|
{
|
|
<div class="settings-section">
|
|
@switch (key)
|
|
{
|
|
case SettingsModalSections.ServiceStatus:
|
|
{
|
|
var meta = SettingsModalSections.All[SettingsModalSections.ServiceStatus];
|
|
var field = ClientSettingsFields.ServiceStatusPollingInterval;
|
|
<label for="status-interval" class="form-label">@meta.FieldLabel</label>
|
|
<input id="status-interval" type="number" class="form-control" min="@field.Min" max="@field.Max" step="1"
|
|
@bind="field.Value" />
|
|
break;
|
|
}
|
|
case SettingsModalSections.Logs:
|
|
{
|
|
var meta = SettingsModalSections.All[SettingsModalSections.Logs];
|
|
var field = ClientSettingsFields.RecentLogsPollingInterval;
|
|
<label for="logs-interval" class="form-label">@meta.FieldLabel</label>
|
|
<input id="logs-interval" type="number" class="form-control" min="@field.Min" max="@field.Max" step="1"
|
|
@bind="field.Value" />
|
|
break;
|
|
}
|
|
case SettingsModalSections.AppLogs:
|
|
{
|
|
var meta = SettingsModalSections.All[SettingsModalSections.AppLogs];
|
|
var field = ClientSettingsFields.AppLogsPollingInterval;
|
|
<label for="app-logs-interval" class="form-label">@meta.FieldLabel</label>
|
|
<input id="app-logs-interval" type="number" class="form-control" min="@field.Min" max="@field.Max" step="1"
|
|
@bind="field.Value" />
|
|
break;
|
|
}
|
|
case SettingsModalSections.Leases:
|
|
{
|
|
var meta = SettingsModalSections.All[SettingsModalSections.Leases];
|
|
var field = ClientSettingsFields.LeasesPollingInterval;
|
|
<label for="leases-interval" class="form-label">@meta.FieldLabel</label>
|
|
<input id="leases-interval" type="number" class="form-control" min="@field.Min" max="@field.Max" step="1"
|
|
@bind="field.Value" />
|
|
break;
|
|
}
|
|
case SettingsModalSections.RecentLogsDisplay:
|
|
{
|
|
var maxLinesField = ClientSettingsFields.RecentLogsMaxLines;
|
|
var autoScrollField = ClientSettingsFields.RecentLogsAutoScroll;
|
|
<div class="mb-2">
|
|
<label for="recent-logs-max-lines" class="form-label">Max lines</label>
|
|
<input id="recent-logs-max-lines" type="number" class="form-control" min="@maxLinesField.Min" max="@maxLinesField.Max" step="1"
|
|
@bind="maxLinesField.Value" />
|
|
</div>
|
|
<div class="form-check">
|
|
<input id="recent-logs-auto-scroll" type="checkbox" class="form-check-input" @bind="autoScrollField.Value" />
|
|
<label for="recent-logs-auto-scroll" class="form-check-label">Auto-scroll when new logs arrive</label>
|
|
</div>
|
|
break;
|
|
}
|
|
case SettingsModalSections.AppLogsDisplay:
|
|
{
|
|
var maxLinesField = ClientSettingsFields.AppLogsMaxLines;
|
|
var autoScrollField = ClientSettingsFields.AppLogsAutoScroll;
|
|
<div class="mb-2">
|
|
<label for="app-logs-max-lines" class="form-label">Max lines</label>
|
|
<input id="app-logs-max-lines" type="number" class="form-control" min="@maxLinesField.Min" max="@maxLinesField.Max" step="1"
|
|
@bind="maxLinesField.Value" />
|
|
</div>
|
|
<div class="form-check">
|
|
<input id="app-logs-auto-scroll" type="checkbox" class="form-check-input" @bind="autoScrollField.Value" />
|
|
<label for="app-logs-auto-scroll" class="form-check-label">Auto-scroll when new logs arrive</label>
|
|
</div>
|
|
break;
|
|
}
|
|
}
|
|
</div>
|
|
}
|
|
}
|
|
</div>
|
|
</div>
|
|
}
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" @onclick="Close">Cancel</button>
|
|
<button type="button" class="btn btn-primary" @onclick="Save">Save</button>
|
|
</div>
|
|
</div>
|
|
</dialog>
|
|
}
|