refactor(ui): replace data connections table with TreeView grouped by site

This commit is contained in:
Joseph Doherty
2026-03-23 02:37:15 -04:00
parent 08d511f609
commit 4426f3e928

View File

@@ -25,50 +25,51 @@
}
else
{
<table class="table table-sm table-striped table-hover">
<thead class="table-dark">
<tr>
<th>ID</th>
<th>Name</th>
<th>Protocol</th>
<th>Site</th>
<th>Primary Config</th>
<th>Backup Config</th>
<th style="width: 160px;">Actions</th>
</tr>
</thead>
<tbody>
@if (_connections.Count == 0)
<TreeView TItem="DcTreeNode" Items="_treeRoots"
ChildrenSelector="n => n.Children"
HasChildrenSelector="n => n.Children.Count > 0"
KeySelector="n => n.Key"
StorageKey="data-connections-tree">
<NodeContent Context="node">
@if (node.Kind == DcNodeKind.Site)
{
<tr>
<td colspan="7" class="text-muted text-center">No data connections configured.</td>
</tr>
<span class="fw-semibold">@node.Label</span>
<span class="badge bg-secondary ms-1">@node.Children.Count</span>
}
@foreach (var conn in _connections)
else
{
<tr>
<td>@conn.Id</td>
<td>@conn.Name</td>
<td><span class="badge bg-secondary">@conn.Protocol</span></td>
<td>@(_siteLookup.GetValueOrDefault(conn.SiteId)?.Name ?? $"Site {conn.SiteId}")</td>
<td class="text-muted small text-truncate" style="max-width: 300px;">@(conn.PrimaryConfiguration ?? "—")</td>
<td class="text-muted small text-truncate" style="max-width: 300px;">@(conn.BackupConfiguration ?? "—")</td>
<td>
<button class="btn btn-outline-primary btn-sm py-0 px-1 me-1"
@onclick='() => NavigationManager.NavigateTo($"/admin/data-connections/{conn.Id}/edit")'>Edit</button>
<button class="btn btn-outline-danger btn-sm py-0 px-1"
@onclick="() => DeleteConnection(conn)">Delete</button>
</td>
</tr>
<span>@node.Label</span>
<span class="badge bg-info ms-2">@node.Connection!.Protocol</span>
}
</tbody>
</table>
</NodeContent>
<ContextMenu Context="node">
@if (node.Kind == DcNodeKind.DataConnection)
{
<button class="dropdown-item"
@onclick='() => NavigationManager.NavigateTo($"/admin/data-connections/{node.Connection!.Id}/edit")'>
Edit
</button>
<div class="dropdown-divider"></div>
<button class="dropdown-item text-danger"
@onclick="() => DeleteConnection(node.Connection!)">
Delete
</button>
}
</ContextMenu>
<EmptyContent>
<span class="text-muted fst-italic">No data connections configured.</span>
</EmptyContent>
</TreeView>
}
</div>
@code {
record DcTreeNode(string Key, string Label, DcNodeKind Kind, List<DcTreeNode> Children,
DataConnection? Connection = null);
enum DcNodeKind { Site, DataConnection }
private List<DcTreeNode> _treeRoots = new();
private List<DataConnection> _connections = new();
private Dictionary<int, Site> _siteLookup = new();
private bool _loading = true;
private string? _errorMessage;
@@ -87,8 +88,22 @@
try
{
var sites = await SiteRepository.GetAllSitesAsync();
_siteLookup = sites.ToDictionary(s => s.Id);
_connections = (await SiteRepository.GetAllDataConnectionsAsync()).ToList();
var connBySite = _connections.GroupBy(c => c.SiteId).ToDictionary(g => g.Key, g => g.ToList());
_treeRoots = sites.Select(site => new DcTreeNode(
Key: $"site-{site.Id}",
Label: site.Name,
Kind: DcNodeKind.Site,
Children: (connBySite.GetValueOrDefault(site.Id) ?? new())
.Select(c => new DcTreeNode(
Key: $"conn-{c.Id}",
Label: c.Name,
Kind: DcNodeKind.DataConnection,
Children: new(),
Connection: c))
.ToList()
)).ToList();
}
catch (Exception ex)
{