mirror of
https://github.com/alexhopeoconnor/dnsmasq-webui.git
synced 2026-10-03 22:12:00 +10:00
EffectiveConfig: migrate edit activation/commit to shared UiContext
- OptionStateBadge: add FieldKey param, call Ui.ActivateFieldAsync instead of OnActivateEdit - EffectiveConfigOptionItem: add FieldKey, pass to badge; remove OnActivateEdit - EffectiveConfigFieldDisplay: add FieldKey, commit only via Ui.CommitFieldAsync; remove ActiveFieldKey, OnActivateEdit, OnEditCommitted - EffectiveConfigSectionPanel: pass FieldKey to FieldDisplay; remove OnActivateField, OnFieldEditCommitted - EffectiveConfigPanels: remove OnActivateField, OnFieldEditCommitted params and relay - EffectiveConfigSection: stop passing callback props to Panels (Session + UiContext drive behavior)
This commit is contained in:
+4
-8
@@ -34,7 +34,7 @@
|
|||||||
@fragment(Descriptor)
|
@fragment(Descriptor)
|
||||||
</CascadingValue>
|
</CascadingValue>
|
||||||
}
|
}
|
||||||
<OptionStateBadge AnchorId="@_readonlyBadgeAnchorId" Source="@Descriptor.GetSource()" OptionName="@Descriptor.OptionName" Value="@effectiveValue" IsInteractive="@IsEditMode" ShowEditableBadge="@showEditableBadge" HasPendingChange="@_hasPendingChange" EditableAsButton="true" OnActivateEdit="@OnActivateEdit" />
|
<OptionStateBadge AnchorId="@_readonlyBadgeAnchorId" Source="@Descriptor.GetSource()" OptionName="@Descriptor.OptionName" Value="@effectiveValue" IsInteractive="@IsEditMode" ShowEditableBadge="@showEditableBadge" HasPendingChange="@_hasPendingChange" EditableAsButton="true" FieldKey="@FieldKey" />
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
}
|
}
|
||||||
@@ -54,14 +54,14 @@ else
|
|||||||
{
|
{
|
||||||
<li class="ec-field" title="@(Descriptor.GetSource()?.GetReadOnlyTooltip())">
|
<li class="ec-field" title="@(Descriptor.GetSource()?.GetReadOnlyTooltip())">
|
||||||
<EffectiveConfigOptionItem Label="@Descriptor.OptionName" DisplayValue="@(displayValue ?? "(not set)")" Source="@Descriptor.GetSource()" LabelTooltip="@_labelTooltip" OptionHelpKey="@_optionHelpKey" OptionHelpAnchorId="@_anchorId"
|
<EffectiveConfigOptionItem Label="@Descriptor.OptionName" DisplayValue="@(displayValue ?? "(not set)")" Source="@Descriptor.GetSource()" LabelTooltip="@_labelTooltip" OptionHelpKey="@_optionHelpKey" OptionHelpAnchorId="@_anchorId"
|
||||||
ReadonlyBadgeAnchorId="@_readonlyBadgeAnchorId" RawValue="@value" HasPendingChange="@_hasPendingChange" />
|
FieldKey="@FieldKey" ReadonlyBadgeAnchorId="@_readonlyBadgeAnchorId" RawValue="@value" HasPendingChange="@_hasPendingChange" />
|
||||||
</li>
|
</li>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<li class="ec-field @(isActiveEditor ? "ec-field-editing" : "")" title="@(Descriptor.GetSource()?.GetReadOnlyTooltip())">
|
<li class="ec-field @(isActiveEditor ? "ec-field-editing" : "")" title="@(Descriptor.GetSource()?.GetReadOnlyTooltip())">
|
||||||
<EffectiveConfigOptionItem Label="@Descriptor.OptionName" DisplayValue="@(displayValue ?? "(not set)")" Source="@Descriptor.GetSource()" LabelTooltip="@_labelTooltip" OptionHelpKey="@_optionHelpKey" OptionHelpAnchorId="@_anchorId"
|
<EffectiveConfigOptionItem Label="@Descriptor.OptionName" DisplayValue="@(displayValue ?? "(not set)")" Source="@Descriptor.GetSource()" LabelTooltip="@_labelTooltip" OptionHelpKey="@_optionHelpKey" OptionHelpAnchorId="@_anchorId"
|
||||||
ShowEditableBadge="true" OnActivateEdit="@OnActivateEdit" IsActive="@IsActive"
|
ShowEditableBadge="true" FieldKey="@FieldKey" IsActive="@IsActive"
|
||||||
ReadonlyBadgeAnchorId="@_readonlyBadgeAnchorId" RawValue="@value" HasPendingChange="@_hasPendingChange"
|
ReadonlyBadgeAnchorId="@_readonlyBadgeAnchorId" RawValue="@value" HasPendingChange="@_hasPendingChange"
|
||||||
DisplayValueChanged="@HandleDefaultValueChanged" OnBlur="@HandleDefaultBlur" />
|
DisplayValueChanged="@HandleDefaultValueChanged" OnBlur="@HandleDefaultBlur" />
|
||||||
</li>
|
</li>
|
||||||
@@ -70,11 +70,9 @@ else
|
|||||||
|
|
||||||
@code {
|
@code {
|
||||||
[Parameter] public EffectiveConfigFieldDescriptor Descriptor { get; set; } = null!;
|
[Parameter] public EffectiveConfigFieldDescriptor Descriptor { get; set; } = null!;
|
||||||
|
[Parameter] public string FieldKey { get; set; } = "";
|
||||||
[Parameter] public bool IsEditMode { get; set; }
|
[Parameter] public bool IsEditMode { get; set; }
|
||||||
[Parameter] public bool IsActive { get; set; }
|
[Parameter] public bool IsActive { get; set; }
|
||||||
[Parameter] public string? ActiveFieldKey { get; set; }
|
|
||||||
[Parameter] public EventCallback OnActivateEdit { get; set; }
|
|
||||||
[Parameter] public EventCallback<EffectiveConfigEditCommittedArgs> OnEditCommitted { get; set; }
|
|
||||||
[CascadingParameter] public IEffectiveConfigEditSession? Session { get; set; }
|
[CascadingParameter] public IEffectiveConfigEditSession? Session { get; set; }
|
||||||
|
|
||||||
private readonly string _anchorId = "ec-help-" + Guid.NewGuid().ToString("N")[..8];
|
private readonly string _anchorId = "ec-help-" + Guid.NewGuid().ToString("N")[..8];
|
||||||
@@ -127,8 +125,6 @@ else
|
|||||||
var args = new EffectiveConfigEditCommittedArgs(Descriptor.SectionId, Descriptor.OptionName, _valueAtActivation, newValue, source?.FilePath);
|
var args = new EffectiveConfigEditCommittedArgs(Descriptor.SectionId, Descriptor.OptionName, _valueAtActivation, newValue, source?.FilePath);
|
||||||
if (Ui != null)
|
if (Ui != null)
|
||||||
await Ui.CommitFieldAsync(args);
|
await Ui.CommitFieldAsync(args);
|
||||||
else if (OnEditCommitted.HasDelegate)
|
|
||||||
await OnEditCommitted.InvokeAsync(args);
|
|
||||||
}
|
}
|
||||||
_draftValue = null;
|
_draftValue = null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,14 +7,14 @@
|
|||||||
{
|
{
|
||||||
<span class="ec-field-value" @onclick:stopPropagation="true">
|
<span class="ec-field-value" @onclick:stopPropagation="true">
|
||||||
<input type="text" class="form-control form-control-sm" value="@(_editValue ?? DisplayValue)" @oninput="OnValueInput" @onfocusout="OnInputBlur" />
|
<input type="text" class="form-control form-control-sm" value="@(_editValue ?? DisplayValue)" @oninput="OnValueInput" @onfocusout="OnInputBlur" />
|
||||||
<OptionStateBadge AnchorId="@(ReadonlyBadgeAnchorId ?? "")" Source="@Source" OptionName="@Label" Value="@(RawValue ?? DisplayValue)" IsInteractive="@(DisplayMode == EffectiveConfigDisplayMode.Edit && !string.IsNullOrEmpty(ReadonlyBadgeAnchorId))" ShowEditableBadge="@ShowEditableBadge" HasPendingChange="@HasPendingChange" EditableAsButton="true" OnActivateEdit="@OnActivateEdit" />
|
<OptionStateBadge AnchorId="@(ReadonlyBadgeAnchorId ?? "")" Source="@Source" OptionName="@Label" Value="@(RawValue ?? DisplayValue)" IsInteractive="@(DisplayMode == EffectiveConfigDisplayMode.Edit && !string.IsNullOrEmpty(ReadonlyBadgeAnchorId))" ShowEditableBadge="@ShowEditableBadge" HasPendingChange="@HasPendingChange" EditableAsButton="true" FieldKey="@FieldKey" />
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<span class="ec-field-value">
|
<span class="ec-field-value">
|
||||||
@DisplayValue
|
@DisplayValue
|
||||||
<OptionStateBadge AnchorId="@(ReadonlyBadgeAnchorId ?? "")" Source="@Source" OptionName="@Label" Value="@(RawValue ?? DisplayValue)" IsInteractive="@(DisplayMode == EffectiveConfigDisplayMode.Edit && !string.IsNullOrEmpty(ReadonlyBadgeAnchorId))" ShowEditableBadge="@ShowEditableBadge" HasPendingChange="@HasPendingChange" EditableAsButton="true" OnActivateEdit="@OnActivateEdit" />
|
<OptionStateBadge AnchorId="@(ReadonlyBadgeAnchorId ?? "")" Source="@Source" OptionName="@Label" Value="@(RawValue ?? DisplayValue)" IsInteractive="@(DisplayMode == EffectiveConfigDisplayMode.Edit && !string.IsNullOrEmpty(ReadonlyBadgeAnchorId))" ShowEditableBadge="@ShowEditableBadge" HasPendingChange="@HasPendingChange" EditableAsButton="true" FieldKey="@FieldKey" />
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,7 +34,8 @@ else
|
|||||||
[Parameter] public bool ShowEditableBadge { get; set; }
|
[Parameter] public bool ShowEditableBadge { get; set; }
|
||||||
/// <summary>When true, badge shows "pending" and warning style to indicate this field has an unsaved change.</summary>
|
/// <summary>When true, badge shows "pending" and warning style to indicate this field has an unsaved change.</summary>
|
||||||
[Parameter] public bool HasPendingChange { get; set; }
|
[Parameter] public bool HasPendingChange { get; set; }
|
||||||
[Parameter] public EventCallback OnActivateEdit { get; set; }
|
/// <summary>Field key for activation via context when editable badge is clicked.</summary>
|
||||||
|
[Parameter] public string FieldKey { get; set; } = "";
|
||||||
/// <summary>When true, add ec-field-editing class and show input when DisplayMode is Edit.</summary>
|
/// <summary>When true, add ec-field-editing class and show input when DisplayMode is Edit.</summary>
|
||||||
[Parameter] public bool IsActive { get; set; }
|
[Parameter] public bool IsActive { get; set; }
|
||||||
/// <summary>When Edit and not readonly: raised when the user changes the value. Not yet wired to save.</summary>
|
/// <summary>When Edit and not readonly: raised when the user changes the value. Not yet wired to save.</summary>
|
||||||
|
|||||||
@@ -23,8 +23,7 @@
|
|||||||
var isOpen = hasSearch || IsSectionOpen(view.SectionId);
|
var isOpen = hasSearch || IsSectionOpen(view.SectionId);
|
||||||
<EffectiveConfigSectionPanel SectionId="@view.SectionId" Title="@view.Title" Descriptors="@sectionDescriptors" IsOpen="@isOpen" OnToggle="@OnSectionToggle"
|
<EffectiveConfigSectionPanel SectionId="@view.SectionId" Title="@view.Title" Descriptors="@sectionDescriptors" IsOpen="@isOpen" OnToggle="@OnSectionToggle"
|
||||||
DisplayMode="@( IsEditMode ? EffectiveConfigDisplayMode.Edit : EffectiveConfigDisplayMode.View )"
|
DisplayMode="@( IsEditMode ? EffectiveConfigDisplayMode.Edit : EffectiveConfigDisplayMode.View )"
|
||||||
IsEditMode="@IsEditMode" ActiveFieldKey="@ActiveFieldKey"
|
IsEditMode="@IsEditMode" ActiveFieldKey="@ActiveFieldKey" />
|
||||||
OnActivateField="@OnActivateField" OnFieldEditCommitted="@OnFieldEditCommitted" />
|
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -36,8 +35,6 @@
|
|||||||
[Parameter] public EventCallback<string> OnSectionToggle { get; set; }
|
[Parameter] public EventCallback<string> OnSectionToggle { get; set; }
|
||||||
[Parameter] public bool IsEditMode { get; set; }
|
[Parameter] public bool IsEditMode { get; set; }
|
||||||
[Parameter] public string? ActiveFieldKey { get; set; }
|
[Parameter] public string? ActiveFieldKey { get; set; }
|
||||||
[Parameter] public EventCallback<string> OnActivateField { get; set; }
|
|
||||||
[Parameter] public EventCallback<EffectiveConfigEditCommittedArgs> OnFieldEditCommitted { get; set; }
|
|
||||||
|
|
||||||
private bool IsSectionOpen(string id) => OpenSectionIds.Contains(id);
|
private bool IsSectionOpen(string id) => OpenSectionIds.Contains(id);
|
||||||
|
|
||||||
|
|||||||
@@ -22,8 +22,7 @@
|
|||||||
<CascadingValue Value="@Session">
|
<CascadingValue Value="@Session">
|
||||||
<CascadingValue Value="@_uiContext">
|
<CascadingValue Value="@_uiContext">
|
||||||
<EffectiveConfigPanels Status="@Status" Context="@Context" SearchTerm="@_searchTerm" OpenSectionIds="@_openPanels"
|
<EffectiveConfigPanels Status="@Status" Context="@Context" SearchTerm="@_searchTerm" OpenSectionIds="@_openPanels"
|
||||||
OnSectionToggle="OnSectionToggle" IsEditMode="@Session.IsEditMode" ActiveFieldKey="@Session.ActiveFieldKey"
|
OnSectionToggle="OnSectionToggle" IsEditMode="@Session.IsEditMode" ActiveFieldKey="@Session.ActiveFieldKey" />
|
||||||
OnActivateField="ActivateField" OnFieldEditCommitted="HandleFieldEditCommitted" />
|
|
||||||
</CascadingValue>
|
</CascadingValue>
|
||||||
</CascadingValue>
|
</CascadingValue>
|
||||||
<EffectiveConfigSaveFlow ShowModal="@_showSaveModal" PendingChanges="@Session.PendingChanges" Status="@Status" Session="@Session"
|
<EffectiveConfigSaveFlow ShowModal="@_showSaveModal" PendingChanges="@Session.PendingChanges" Status="@Status" Session="@Session"
|
||||||
|
|||||||
+2
-8
@@ -14,12 +14,8 @@
|
|||||||
@foreach (var f in Descriptors)
|
@foreach (var f in Descriptors)
|
||||||
{
|
{
|
||||||
var fieldKey = $"{SectionId}:{f.OptionName}";
|
var fieldKey = $"{SectionId}:{f.OptionName}";
|
||||||
<EffectiveConfigFieldDisplay Descriptor="@f"
|
<EffectiveConfigFieldDisplay Descriptor="@f" FieldKey="@fieldKey"
|
||||||
IsEditMode="@IsEditMode"
|
IsEditMode="@IsEditMode" IsActive="@(ActiveFieldKey == fieldKey)" />
|
||||||
IsActive="@(ActiveFieldKey == fieldKey)"
|
|
||||||
ActiveFieldKey="@ActiveFieldKey"
|
|
||||||
OnActivateEdit="@(() => OnActivateField.InvokeAsync(fieldKey))"
|
|
||||||
OnEditCommitted="@OnFieldEditCommitted" />
|
|
||||||
}
|
}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@@ -37,8 +33,6 @@
|
|||||||
[Parameter] public EffectiveConfigDisplayMode DisplayMode { get; set; } = EffectiveConfigDisplayMode.View;
|
[Parameter] public EffectiveConfigDisplayMode DisplayMode { get; set; } = EffectiveConfigDisplayMode.View;
|
||||||
[Parameter] public bool IsEditMode { get; set; }
|
[Parameter] public bool IsEditMode { get; set; }
|
||||||
[Parameter] public string? ActiveFieldKey { get; set; }
|
[Parameter] public string? ActiveFieldKey { get; set; }
|
||||||
[Parameter] public EventCallback<string> OnActivateField { get; set; }
|
|
||||||
[Parameter] public EventCallback<EffectiveConfigEditCommittedArgs> OnFieldEditCommitted { get; set; }
|
|
||||||
|
|
||||||
private async Task ToggleSection() => await OnToggle.InvokeAsync(SectionId);
|
private async Task ToggleSection() => await OnToggle.InvokeAsync(SectionId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ else if (ShowEditableBadge)
|
|||||||
{
|
{
|
||||||
<button type="button"
|
<button type="button"
|
||||||
class="badge ec-badge-inline border-0 ms-1 @(HasPendingChange ? "bg-warning text-dark" : "bg-primary")"
|
class="badge ec-badge-inline border-0 ms-1 @(HasPendingChange ? "bg-warning text-dark" : "bg-primary")"
|
||||||
@onclick="OnActivateEdit"
|
@onclick="OnEditableClick"
|
||||||
@onclick:stopPropagation="true"
|
@onclick:stopPropagation="true"
|
||||||
title="@(HasPendingChange ? "Pending change" : "Edit this field")"
|
title="@(HasPendingChange ? "Pending change" : "Edit this field")"
|
||||||
aria-label="Edit">
|
aria-label="Edit">
|
||||||
@@ -48,9 +48,16 @@ else if (ShowEditableBadge)
|
|||||||
[Parameter] public bool HasPendingChange { get; set; }
|
[Parameter] public bool HasPendingChange { get; set; }
|
||||||
/// <summary>When true, editable badge is a button; otherwise a static span.</summary>
|
/// <summary>When true, editable badge is a button; otherwise a static span.</summary>
|
||||||
[Parameter] public bool EditableAsButton { get; set; } = true;
|
[Parameter] public bool EditableAsButton { get; set; } = true;
|
||||||
[Parameter] public EventCallback OnActivateEdit { get; set; }
|
/// <summary>Field key for activation via context when editable badge is clicked.</summary>
|
||||||
|
[Parameter] public string? FieldKey { get; set; }
|
||||||
[CascadingParameter] public EffectiveConfigUiContext? Ui { get; set; }
|
[CascadingParameter] public EffectiveConfigUiContext? Ui { get; set; }
|
||||||
|
|
||||||
|
private Task OnEditableClick()
|
||||||
|
{
|
||||||
|
if (Ui == null || string.IsNullOrEmpty(FieldKey)) return Task.CompletedTask;
|
||||||
|
return Ui.ActivateFieldAsync(FieldKey);
|
||||||
|
}
|
||||||
|
|
||||||
private Task OnReadonlyClick()
|
private Task OnReadonlyClick()
|
||||||
{
|
{
|
||||||
if (Ui == null || Source == null) return Task.CompletedTask;
|
if (Ui == null || Source == null) return Task.CompletedTask;
|
||||||
|
|||||||
Reference in New Issue
Block a user