mirror of
https://github.com/alexhopeoconnor/dnsmasq-webui.git
synced 2026-10-03 22:12:00 +10:00
Effective config: empty multi-value UX, clickable changes count
- Multi-value: show editable badge next to (none); clicking activates edit and opens add row - List editor: when empty and add allowed, do not show (none) row; auto-focus new-item input on open and when clicking add item - Toolbar: make 'X change(s)' clickable to open save dialog (keyboard accessible)
This commit is contained in:
+8
@@ -38,6 +38,14 @@
|
|||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
::deep .ec-toolbar-changes-link {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
::deep .ec-toolbar-changes-link:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
.ec-sections {
|
.ec-sections {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|||||||
+15
-1
@@ -22,7 +22,13 @@
|
|||||||
</button>
|
</button>
|
||||||
@if (PendingChangesCount > 0)
|
@if (PendingChangesCount > 0)
|
||||||
{
|
{
|
||||||
<span class="text-muted small">@PendingChangesCount change(s)</span>
|
<span class="text-muted small ec-toolbar-changes-link" role="button" tabindex="0"
|
||||||
|
@onclick="OnOpenSaveModal"
|
||||||
|
@onkeydown="OnChangesLinkKeyDown"
|
||||||
|
title="Open save dialog"
|
||||||
|
aria-label="Open save dialog">
|
||||||
|
@PendingChangesCount change(s)
|
||||||
|
</span>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -59,4 +65,12 @@
|
|||||||
{
|
{
|
||||||
await SearchTermChanged.InvokeAsync(e.Value?.ToString() ?? "");
|
await SearchTermChanged.InvokeAsync(e.Value?.ToString() ?? "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task OnChangesLinkKeyDown(KeyboardEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.Key == "Enter" || e.Key == " ")
|
||||||
|
{
|
||||||
|
await OnOpenSaveModal.InvokeAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+34
-2
@@ -1,6 +1,8 @@
|
|||||||
@namespace DnsmasqWebUI.Components.EffectiveConfig
|
@namespace DnsmasqWebUI.Components.EffectiveConfig
|
||||||
@using DnsmasqWebUI.Models.Dnsmasq
|
@using DnsmasqWebUI.Models.Dnsmasq
|
||||||
@using DnsmasqWebUI.Models.Dnsmasq.EffectiveConfig
|
@using DnsmasqWebUI.Models.Dnsmasq.EffectiveConfig
|
||||||
|
@using Microsoft.AspNetCore.Components.Web
|
||||||
|
@inject IJSRuntime JSRuntime
|
||||||
|
|
||||||
<span class="ec-field-value ec-field-value-multi ec-multi-list-editor" @onclick:stopPropagation="true">
|
<span class="ec-field-value ec-field-value-multi ec-multi-list-editor" @onclick:stopPropagation="true">
|
||||||
<ol class="ec-field-value-list">
|
<ol class="ec-field-value-list">
|
||||||
@@ -53,7 +55,7 @@
|
|||||||
</li>
|
</li>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (!AllowAddManagedValue)
|
||||||
{
|
{
|
||||||
<li class="ec-multi-list-row ec-multi-list-empty-hint">
|
<li class="ec-multi-list-row ec-multi-list-empty-hint">
|
||||||
<span class="text-muted">(none)</span>
|
<span class="text-muted">(none)</span>
|
||||||
@@ -65,7 +67,7 @@
|
|||||||
<li class="ec-multi-list-row ec-multi-list-add-item" @key="AddItemKey">
|
<li class="ec-multi-list-row ec-multi-list-add-item" @key="AddItemKey">
|
||||||
@if (_addingNew)
|
@if (_addingNew)
|
||||||
{
|
{
|
||||||
<input class="form-control form-control-sm ec-multi-list-input"
|
<input @ref="_addNewInputRef" class="form-control form-control-sm ec-multi-list-input"
|
||||||
placeholder="New value"
|
placeholder="New value"
|
||||||
@bind="_draftValue" @bind:event="oninput" />
|
@bind="_draftValue" @bind:event="oninput" />
|
||||||
<span class="status-badge-inline">
|
<span class="status-badge-inline">
|
||||||
@@ -102,6 +104,35 @@
|
|||||||
private int? _editingIndex;
|
private int? _editingIndex;
|
||||||
private bool _addingNew;
|
private bool _addingNew;
|
||||||
private string _draftValue = "";
|
private string _draftValue = "";
|
||||||
|
private bool _didAutoOpenAdd;
|
||||||
|
private bool _shouldFocusAddInput;
|
||||||
|
private ElementReference _addNewInputRef;
|
||||||
|
|
||||||
|
protected override void OnParametersSet()
|
||||||
|
{
|
||||||
|
if (!_didAutoOpenAdd && (SourceItems?.Count ?? 0) == 0 && AllowAddManagedValue)
|
||||||
|
{
|
||||||
|
_didAutoOpenAdd = true;
|
||||||
|
_addingNew = true;
|
||||||
|
_shouldFocusAddInput = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||||
|
{
|
||||||
|
if (_shouldFocusAddInput && _addingNew)
|
||||||
|
{
|
||||||
|
_shouldFocusAddInput = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _addNewInputRef.FocusAsync();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// Focus can fail if the element is not yet in the DOM (e.g. prerender)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void BeginEdit(int index, string current)
|
private void BeginEdit(int index, string current)
|
||||||
{
|
{
|
||||||
@@ -115,6 +146,7 @@
|
|||||||
_editingIndex = null;
|
_editingIndex = null;
|
||||||
_addingNew = true;
|
_addingNew = true;
|
||||||
_draftValue = "";
|
_draftValue = "";
|
||||||
|
_shouldFocusAddInput = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CancelInline()
|
private void CancelInline()
|
||||||
|
|||||||
@@ -34,6 +34,8 @@
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
<span class="text-muted">(none)</span>
|
<span class="text-muted">(none)</span>
|
||||||
|
<OptionStateBadge OptionName="@Label" ShowEditableBadge="true" EditableAsButton="true"
|
||||||
|
FieldKey="@FieldKey" IsActiveEditor="false" IsInteractive="true" />
|
||||||
}
|
}
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user