feat(ui/deployment): consolidate sites/areas/instances into Topology page

Single /deployment/topology page replaces /deployment/instances (legacy URL
preserved as a secondary @page directive) and the /admin/areas* CRUD pages.
TreeView with Site → Area → Instance, V1–V7 visual guide (bi-building /
bi-diagram-3 / bi-box), always-visible empty containers, search dim, F2
inline area rename, and right-click context menus per node kind (Add Area,
Move to Area…, lifecycle actions, etc.).

Adds AreaService.MoveAreaAsync with cycle prevention, same-site enforcement,
and name-collision check at the new parent. Instance rename intentionally
out of scope — UniqueName is the site-side actor identity, requires its own
design pass.
This commit is contained in:
Joseph Doherty
2026-05-11 22:03:55 -04:00
parent b2eddd9713
commit f3386d0278
18 changed files with 1857 additions and 1122 deletions

View File

@@ -14,7 +14,7 @@
<div class="container-fluid mt-3">
<div class="d-flex align-items-center mb-3">
<a href="/deployment/instances" class="btn btn-outline-secondary btn-sm me-3">&larr; Back</a>
<a href="/deployment/topology" class="btn btn-outline-secondary btn-sm me-3">&larr; Back</a>
<h4 class="mb-0">Create Instance</h4>
</div>
@@ -74,6 +74,9 @@
</div>
@code {
[SupplyParameterFromQuery] public int? SiteId { get; set; }
[SupplyParameterFromQuery] public int? AreaId { get; set; }
private List<Site> _sites = new();
private List<Template> _templates = new();
private List<Area> _allAreas = new();
@@ -98,6 +101,15 @@
var areas = await TemplateEngineRepository.GetAreasBySiteIdAsync(site.Id);
_allAreas.AddRange(areas);
}
if (SiteId is int sid && _sites.Any(s => s.Id == sid))
{
_createSiteId = sid;
}
if (AreaId is int aid && _allAreas.Any(a => a.Id == aid && a.SiteId == _createSiteId))
{
_createAreaId = aid;
}
}
catch (Exception ex)
{
@@ -120,7 +132,7 @@
_createName.Trim(), _createTemplateId, _createSiteId, _createAreaId == 0 ? null : _createAreaId, user);
if (result.IsSuccess)
{
NavigationManager.NavigateTo("/deployment/instances");
NavigationManager.NavigateTo("/deployment/topology");
}
else
{
@@ -133,7 +145,7 @@
}
}
private void GoBack() => NavigationManager.NavigateTo("/deployment/instances");
private void GoBack() => NavigationManager.NavigateTo("/deployment/topology");
private async Task<string> GetCurrentUserAsync()
{