refactor(ui/shared): introduce IDialogService + DialogHost
Eliminates the per-page <ConfirmDialog @ref="_confirmDialog" ConfirmButtonClass="btn-danger" /> boilerplate. Pages now inject IDialogService and call ConfirmAsync(title, message, danger: true) programmatically. New scoped service holds a single active dialog (throws on nested calls), with a global DialogHost mounted once in MainLayout that renders the modal markup, owns body scroll-lock via Bootstrap's modal-open class, traps focus on the modal element, and handles Escape-to-cancel. Same service also exposes PromptAsync, used to replace the bespoke NewFolderDialog. Both ConfirmDialog and NewFolderDialog components are deleted — their callers (~13 pages across Admin/Design/Deployment /Monitoring) now go through the service. DiffDialog stays as-is — different use case (before/after content). bUnit tests in TopologyPageTests, DataConnectionsPageTests, and TemplatesPageTests register IDialogService in their service collection. Also: a top-of-file Razor comment on Sites.razor pointing future implementers at it as the reference list-page pattern.
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
@* Reference pattern for list pages: card grid (col-lg-6) + flex header + search filter + kebab dropdown + Bootstrap collapse for noisy detail + @key on iterated cards + "No X match the filter." inline + empty-state CTA. Mirror this when building new list pages. *@
|
||||
@page "/admin/sites"
|
||||
@using ScadaLink.Security
|
||||
@using ScadaLink.Commons.Entities.Sites
|
||||
@@ -11,6 +12,7 @@
|
||||
@inject AuthenticationStateProvider AuthStateProvider
|
||||
@inject NavigationManager NavigationManager
|
||||
@inject IJSRuntime JS
|
||||
@inject IDialogService Dialog
|
||||
|
||||
<div class="container-fluid mt-3">
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
@@ -41,7 +43,6 @@
|
||||
</div>
|
||||
|
||||
<ToastNotification @ref="_toast" />
|
||||
<ConfirmDialog @ref="_confirmDialog" ConfirmButtonClass="btn-danger" />
|
||||
|
||||
@if (_loading)
|
||||
{
|
||||
@@ -173,7 +174,6 @@
|
||||
private string _search = "";
|
||||
|
||||
private ToastNotification _toast = default!;
|
||||
private ConfirmDialog _confirmDialog = default!;
|
||||
|
||||
private IEnumerable<Site> FilteredSites =>
|
||||
string.IsNullOrWhiteSpace(_search)
|
||||
@@ -213,9 +213,10 @@
|
||||
|
||||
private async Task DeleteSite(Site site)
|
||||
{
|
||||
var confirmed = await _confirmDialog.ShowAsync(
|
||||
var confirmed = await Dialog.ConfirmAsync(
|
||||
"Delete Site",
|
||||
$"Delete site '{site.Name}' ({site.SiteIdentifier})? This cannot be undone.",
|
||||
"Delete Site");
|
||||
danger: true);
|
||||
|
||||
if (!confirmed) return;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user