fix(adminui): confirm before deleting role grants, clusters, nodes and ACLs (lmxopcua#785)
v2-ci / unit-tests (push) Waiting to run
v2-ci / unit-tests (push) Waiting to run
The four Delete buttons deleted on the first click. They now open the shared RawConfirmDialog naming the item; only Confirm deletes. Adds bUnit (test-only) render tests: modal opens without deleting, Cancel keeps the item, Confirm deletes. Claude-Session: https://claude.ai/code/session_01GT67AEHd2Acv1YPwGfXEoV
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
@rendermode RenderMode.InteractiveServer
|
||||
@using Microsoft.AspNetCore.Components.Forms
|
||||
@using Microsoft.EntityFrameworkCore
|
||||
@using ZB.MOM.WW.OtOpcUa.AdminUI.Components.Shared.Raw
|
||||
@using System.ComponentModel.DataAnnotations
|
||||
@using ZB.MOM.WW.OtOpcUa.AdminUI.Acls
|
||||
@using ZB.MOM.WW.OtOpcUa.Configuration
|
||||
@@ -148,12 +149,16 @@ else
|
||||
<button type="submit" class="btn btn-primary" disabled="@_busy">@(IsNew ? "Create" : "Save changes")</button>
|
||||
<a href="/clusters/@ClusterId/acls" class="btn btn-outline-secondary">Cancel</a>
|
||||
</div>
|
||||
@if (!IsNew) { <button type="button" class="btn btn-outline-danger ms-auto" @onclick="DeleteAsync" disabled="@_busy">Delete</button> }
|
||||
@if (!IsNew) { <button type="button" class="btn btn-outline-danger ms-auto" @onclick="() => _confirmDeleteVisible = true" disabled="@_busy">Delete</button> }
|
||||
</div>
|
||||
</EditForm>
|
||||
|
||||
<AclScopePickerModal Visible="_pickerVisible" ClusterId="@ClusterId"
|
||||
OnPicked="ScopePicked" OnCancel="() => _pickerVisible = false" />
|
||||
|
||||
<RawConfirmDialog @bind-Visible="_confirmDeleteVisible" Title="Delete ACL"
|
||||
Message="@($"Delete ACL '{NodeAclId}' (principal '{_form.Principal}') from cluster '{ClusterId}'? This cannot be undone.")"
|
||||
OnConfirm="DeleteAsync" />
|
||||
}
|
||||
</PageErrorBoundary>
|
||||
|
||||
@@ -175,6 +180,7 @@ else
|
||||
private NodeAcl? _existing;
|
||||
private bool _loaded;
|
||||
private bool _busy;
|
||||
private bool _confirmDeleteVisible;
|
||||
private string? _error;
|
||||
private bool _pickerVisible;
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
@rendermode RenderMode.InteractiveServer
|
||||
@using Microsoft.AspNetCore.Components.Forms
|
||||
@using Microsoft.EntityFrameworkCore
|
||||
@using ZB.MOM.WW.OtOpcUa.AdminUI.Components.Shared.Raw
|
||||
@using System.ComponentModel.DataAnnotations
|
||||
@using ZB.MOM.WW.OtOpcUa.Configuration
|
||||
@using ZB.MOM.WW.OtOpcUa.Configuration.Entities
|
||||
@@ -99,11 +100,15 @@ else
|
||||
</button>
|
||||
<a href="/clusters/@ClusterId" class="btn btn-outline-secondary">Cancel</a>
|
||||
</div>
|
||||
<button type="button" class="btn btn-outline-danger ms-auto" @onclick="DeleteAsync" disabled="@_busy">
|
||||
<button type="button" class="btn btn-outline-danger ms-auto" @onclick="() => _confirmDeleteVisible = true" disabled="@_busy">
|
||||
Delete cluster
|
||||
</button>
|
||||
</div>
|
||||
</EditForm>
|
||||
|
||||
<RawConfirmDialog @bind-Visible="_confirmDeleteVisible" Title="Delete cluster"
|
||||
Message="@($"Delete cluster '{ClusterId}'? This cannot be undone.")"
|
||||
OnConfirm="DeleteAsync" />
|
||||
}
|
||||
</PageErrorBoundary>
|
||||
|
||||
@@ -114,6 +119,7 @@ else
|
||||
private ServerCluster? _existing;
|
||||
private bool _loaded;
|
||||
private bool _busy;
|
||||
private bool _confirmDeleteVisible;
|
||||
private string? _error;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
@rendermode RenderMode.InteractiveServer
|
||||
@using Microsoft.AspNetCore.Components.Forms
|
||||
@using Microsoft.EntityFrameworkCore
|
||||
@using ZB.MOM.WW.OtOpcUa.AdminUI.Components.Shared.Raw
|
||||
@using System.ComponentModel.DataAnnotations
|
||||
@using ZB.MOM.WW.OtOpcUa.Configuration
|
||||
@using ZB.MOM.WW.OtOpcUa.Configuration.Entities
|
||||
@@ -116,12 +117,16 @@ else
|
||||
</div>
|
||||
@if (!IsNew)
|
||||
{
|
||||
<button type="button" class="btn btn-outline-danger ms-auto" @onclick="DeleteAsync" disabled="@_busy">
|
||||
<button type="button" class="btn btn-outline-danger ms-auto" @onclick="() => _confirmDeleteVisible = true" disabled="@_busy">
|
||||
Delete
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
</EditForm>
|
||||
|
||||
<RawConfirmDialog @bind-Visible="_confirmDeleteVisible" Title="Delete node"
|
||||
Message="@($"Delete node '{NodeId}' from cluster '{ClusterId}'? This cannot be undone.")"
|
||||
OnConfirm="DeleteAsync" />
|
||||
}
|
||||
</PageErrorBoundary>
|
||||
|
||||
@@ -135,6 +140,7 @@ else
|
||||
private ClusterNode? _existing;
|
||||
private bool _loaded;
|
||||
private bool _busy;
|
||||
private bool _confirmDeleteVisible;
|
||||
private string? _error;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
@attribute [Authorize(Policy = AdminUiPolicies.FleetAdmin)]
|
||||
@rendermode RenderMode.InteractiveServer
|
||||
@using Microsoft.Extensions.Options
|
||||
@using ZB.MOM.WW.OtOpcUa.AdminUI.Components.Shared.Raw
|
||||
@using ZB.MOM.WW.OtOpcUa.Configuration.Entities
|
||||
@using ZB.MOM.WW.OtOpcUa.Configuration.Enums
|
||||
@using ZB.MOM.WW.OtOpcUa.Configuration.Services
|
||||
@@ -65,7 +66,7 @@
|
||||
<tr>
|
||||
<td title="@r.LdapGroup"><span class="mono">@DisplayText.Abbreviate(r.LdapGroup, 48)</span></td>
|
||||
<td><span class="chip chip-idle">@r.Role</span></td>
|
||||
<td><button class="btn btn-sm btn-outline-danger" @onclick="() => DeleteAsync(r.Id)" disabled="@_busy">Delete</button></td>
|
||||
<td><button class="btn btn-sm btn-outline-danger" @onclick="() => _pendingDelete = r" disabled="@_busy">Delete</button></td>
|
||||
</tr>
|
||||
}
|
||||
}
|
||||
@@ -74,6 +75,11 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<RawConfirmDialog Visible="@(_pendingDelete is not null)" VisibleChanged="@(v => { if (!v) _pendingDelete = null; })"
|
||||
Title="Delete role grant"
|
||||
Message="@($"Delete the role grant mapping LDAP group '{_pendingDelete?.LdapGroup}' to role {_pendingDelete?.Role}? This cannot be undone.")"
|
||||
OnConfirm="ConfirmDeleteAsync" />
|
||||
|
||||
@if (_options is not null)
|
||||
{
|
||||
<section class="panel rise mt-3" style="animation-delay:.14s">
|
||||
@@ -113,6 +119,7 @@
|
||||
private AdminRole _newRole = AdminRole.Viewer;
|
||||
private string? _error;
|
||||
private bool _busy;
|
||||
private LdapGroupRoleMapping? _pendingDelete;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
@@ -143,6 +150,13 @@
|
||||
finally { _busy = false; }
|
||||
}
|
||||
|
||||
private async Task ConfirmDeleteAsync()
|
||||
{
|
||||
var id = _pendingDelete?.Id;
|
||||
_pendingDelete = null;
|
||||
if (id is Guid g) await DeleteAsync(g);
|
||||
}
|
||||
|
||||
private async Task DeleteAsync(Guid id)
|
||||
{
|
||||
_error = null; _busy = true;
|
||||
|
||||
Reference in New Issue
Block a user