diff --git a/src/ScadaLink.CentralUI/Components/Pages/Deployment/Instances.razor b/src/ScadaLink.CentralUI/Components/Pages/Deployment/Instances.razor
index 371087b..1ed59f1 100644
--- a/src/ScadaLink.CentralUI/Components/Pages/Deployment/Instances.razor
+++ b/src/ScadaLink.CentralUI/Components/Pages/Deployment/Instances.razor
@@ -75,100 +75,69 @@
-
+ else if (inst.State == InstanceState.Disabled)
+ {
+
+ }
+
+
+
+
+ }
+
+
+ No instances match the current filters.
+
+
+
+
@_filteredInstances.Count instance(s) total
@@ -230,9 +199,13 @@
return authState.User.FindFirst("Username")?.Value ?? "unknown";
}
+ record InstanceTreeNode(string Key, string Label, InstanceNodeKind Kind,
+ List
Children, Instance? Instance = null,
+ bool IsStale = false);
+ enum InstanceNodeKind { Site, Area, Instance }
+
private List _allInstances = new();
private List _filteredInstances = new();
- private List _pagedInstances = new();
private List _sites = new();
private List _templates = new();
private List _allAreas = new();
@@ -246,9 +219,9 @@
private string _filterStatus = string.Empty;
private string _filterSearch = string.Empty;
- private int _currentPage = 1;
- private int _totalPages;
- private const int PageSize = 25;
+ private List _treeRoots = new();
+ private TreeView _instanceTree = default!;
+ private object? _selectedKey;
private ToastNotification _toast = default!;
private ConfirmDialog _confirmDialog = default!;
@@ -312,26 +285,66 @@
return true;
}).OrderBy(i => i.UniqueName).ToList();
- _totalPages = Math.Max(1, (int)Math.Ceiling(_filteredInstances.Count / (double)PageSize));
- if (_currentPage > _totalPages) _currentPage = 1;
- UpdatePage();
+ BuildTree();
}
- private void GoToPage(int page)
+ private void BuildTree()
{
- if (page < 1 || page > _totalPages) return;
- _currentPage = page;
- UpdatePage();
+ _treeRoots = _sites.Select(site =>
+ {
+ var siteAreas = _allAreas.Where(a => a.SiteId == site.Id).ToList();
+ var siteInstances = _filteredInstances.Where(i => i.SiteId == site.Id).ToList();
+
+ var areaNodes = BuildAreaNodes(siteAreas, siteInstances, parentId: null);
+
+ var unassigned = siteInstances
+ .Where(i => i.AreaId == null)
+ .Select(MakeInstanceNode)
+ .ToList();
+
+ var children = areaNodes.Concat(unassigned).ToList();
+
+ return new InstanceTreeNode(
+ Key: $"site-{site.Id}",
+ Label: site.Name,
+ Kind: InstanceNodeKind.Site,
+ Children: children);
+ })
+ .Where(s => s.Children.Count > 0)
+ .ToList();
}
- private void UpdatePage()
+ private List BuildAreaNodes(List allAreas,
+ List instances, int? parentId)
{
- _pagedInstances = _filteredInstances
- .Skip((_currentPage - 1) * PageSize)
- .Take(PageSize)
+ return allAreas
+ .Where(a => a.ParentAreaId == parentId)
+ .Select(area =>
+ {
+ var childAreas = BuildAreaNodes(allAreas, instances, area.Id);
+ var areaInstances = instances
+ .Where(i => i.AreaId == area.Id)
+ .Select(MakeInstanceNode)
+ .ToList();
+ var children = childAreas.Concat(areaInstances).ToList();
+ return new InstanceTreeNode(
+ Key: $"area-{area.Id}",
+ Label: area.Name,
+ Kind: InstanceNodeKind.Area,
+ Children: children);
+ })
+ .Where(a => a.Children.Count > 0)
.ToList();
}
+ private InstanceTreeNode MakeInstanceNode(Instance inst) => new(
+ Key: $"inst-{inst.Id}",
+ Label: inst.UniqueName,
+ Kind: InstanceNodeKind.Instance,
+ Children: new(),
+ Instance: inst,
+ IsStale: _stalenessMap.GetValueOrDefault(inst.Id));
+
private string GetTemplateName(int templateId) =>
_templates.FirstOrDefault(t => t.Id == templateId)?.Name ?? $"#{templateId}";