feat(adminui): AliasTagModal + Tags-tab Add-alias (Galaxy picker)

This commit is contained in:
Joseph Doherty
2026-06-11 21:37:04 -04:00
parent 943bc5f709
commit 4af27ea173
2 changed files with 309 additions and 3 deletions
@@ -138,7 +138,12 @@ else
}
else if (_activeTab == "tags")
{
<div class="d-flex justify-content-end mb-2">
<div class="d-flex justify-content-end align-items-center gap-2 mb-2">
@if (_gateways.Count == 0)
{
<span class="text-muted small">No Galaxy gateway in this cluster</span>
}
<button type="button" class="btn btn-outline-primary btn-sm" @onclick="OpenAddAlias" disabled="@(_gateways.Count == 0)">Add alias (browse Galaxy)</button>
<button type="button" class="btn btn-outline-primary btn-sm" @onclick="OpenAddTag">Add tag</button>
</div>
@if (!string.IsNullOrWhiteSpace(_tagError))
@@ -157,7 +162,7 @@ else
{
<table class="table table-sm">
<thead>
<tr><th>Name</th><th>Driver</th><th>Data type</th><th>Access</th><th class="text-end">Actions</th></tr>
<tr><th>Name</th><th>Driver</th><th>Data type</th><th>Access</th><th>Source</th><th class="text-end">Actions</th></tr>
</thead>
<tbody>
@foreach (var t in _tags)
@@ -167,8 +172,22 @@ else
<td class="mono">@t.DriverInstanceId</td>
<td>@t.DataType</td>
<td>@t.AccessLevel</td>
<td>
@if (t.IsAlias)
{
<span class="badge bg-info me-1">alias</span>
<span class="mono small">@t.Source</span>
}
</td>
<td class="text-end">
<button type="button" class="btn btn-outline-secondary btn-sm me-1" @onclick="() => OpenEditTag(t.TagId)">Edit</button>
@if (t.IsAlias)
{
<button type="button" class="btn btn-outline-secondary btn-sm me-1" @onclick="() => OpenEditAlias(t.TagId)">Edit</button>
}
else
{
<button type="button" class="btn btn-outline-secondary btn-sm me-1" @onclick="() => OpenEditTag(t.TagId)">Edit</button>
}
<button type="button" class="btn btn-outline-danger btn-sm" @onclick="() => DeleteTag(t.TagId)">Delete</button>
</td>
</tr>
@@ -180,6 +199,10 @@ else
<TagModal Visible="_tagModalVisible" IsNew="_tagModalIsNew" EquipmentId="@EquipmentId"
Existing="_tagModalExisting" Drivers="_tagDriverOptions"
OnSaved="OnTagSavedAsync" OnCancel="@(() => { _tagModalVisible = false; })" />
<AliasTagModal Visible="_aliasModalVisible" IsNew="_aliasModalIsNew" EquipmentId="@EquipmentId"
Existing="_aliasModalExisting" Gateways="_gateways"
OnSaved="OnAliasSavedAsync" OnCancel="@(() => { _aliasModalVisible = false; })" />
}
else if (_activeTab == "vtags")
{
@@ -300,6 +323,14 @@ else
private TagEditDto? _tagModalExisting;
private IReadOnlyList<(string Id, string Display, string DriverType)> _tagDriverOptions = Array.Empty<(string, string, string)>();
// --- Alias-tag modal state (Galaxy alias = an equipment Tag bound to a GalaxyMxGateway driver). The
// gateways are reloaded alongside _tags so the Add-alias button can disable itself when none exist. ---
private IReadOnlyList<(string DriverInstanceId, string Display, string DriverConfig)> _gateways
= Array.Empty<(string, string, string)>();
private bool _aliasModalVisible;
private bool _aliasModalIsNew;
private AliasTagEditDto? _aliasModalExisting;
// --- Virtual Tags tab state. _vtags is null until the tab is first activated. ---
private IReadOnlyList<EquipmentVirtualTagRow>? _vtags;
private string? _vtagError;
@@ -339,6 +370,8 @@ else
private async Task ReloadTagsAsync()
{
_tags = await Svc.LoadTagsForEquipmentAsync(EquipmentId!);
// Also refresh the candidate Galaxy gateways so the Add-alias affordance reflects the cluster.
_gateways = await Svc.LoadGalaxyGatewaysForEquipmentAsync(EquipmentId!);
}
private async Task OpenAddTag()
@@ -379,6 +412,33 @@ else
else { _tagError = r.Error; }
}
// --- Alias-tag handlers (mirror the tag handlers; aliases live in the same _tags list + delete the
// same way, so only the create/edit modal differs — it embeds the Galaxy live-browse picker). ---
private void OpenAddAlias()
{
_tagError = null;
_aliasModalIsNew = true;
_aliasModalExisting = null;
_aliasModalVisible = true;
}
private async Task OpenEditAlias(string tagId)
{
_tagError = null;
var dto = await Svc.LoadAliasTagAsync(tagId);
if (dto is null) { _tagError = "That alias no longer exists; the list was refreshed."; await ReloadTagsAsync(); return; }
_aliasModalIsNew = false;
_aliasModalExisting = dto;
_aliasModalVisible = true;
}
private async Task OnAliasSavedAsync()
{
_aliasModalVisible = false;
await ReloadTagsAsync();
}
// --- Virtual Tags tab handlers ---
private async Task ReloadVirtualTagsAsync()