feat(central-ui): Debug View picks the instance through InstancePicker
The flat instance <select> on Debug View is replaced by the shared InstancePicker area-tree combobox (design 2026-09-08 §3): the page now loads the site's areas alongside its Enabled instances in LoadInstancesForSite and hands both lists to the picker with ItemLabel = "UniqueName (State)", Disabled="@_connected" and DataTestPrefix="debug-instance". Both lists are now REPLACED rather than cleared in place wherever the site changes (LoadInstancesForSite, StartFresh) — the picker compares Areas and Instances by reference and a new object is what tells it the site changed. The ?siteId=/?instanceId= deep link and the localStorage reconnect keep setting _selectedInstanceId directly; the picker reads it on parameter set, so both paths are unchanged. Claude-Session: https://claude.ai/code/session_01NcMG6xXdsJbmD2wYAgkK29
This commit is contained in:
@@ -82,14 +82,10 @@
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label small">Instance</label>
|
||||
<select class="form-select form-select-sm" data-test="debug-instance-select"
|
||||
@bind="_selectedInstanceId" @bind:after="OnInstanceSelectionChanged" disabled="@_connected">
|
||||
<option value="0">Select instance...</option>
|
||||
@foreach (var inst in _siteInstances)
|
||||
{
|
||||
<option value="@inst.Id">@inst.UniqueName (@inst.State)</option>
|
||||
}
|
||||
</select>
|
||||
<InstancePicker Areas="_siteAreas" Instances="_siteInstances"
|
||||
ItemLabel="@(i => $"{i.UniqueName} ({i.State})")"
|
||||
SelectedInstanceId="_selectedInstanceId" SelectedInstanceIdChanged="OnInstancePicked"
|
||||
Disabled="@_connected" DataTestPrefix="debug-instance" />
|
||||
</div>
|
||||
<div class="col-md-3 d-flex align-items-end gap-2">
|
||||
@if (!_connected)
|
||||
@@ -257,6 +253,11 @@
|
||||
|
||||
private List<Site> _sites = new();
|
||||
private List<Instance> _siteInstances = new();
|
||||
|
||||
// The site's areas, backing the InstancePicker's tree. Both lists are REPLACED
|
||||
// (never mutated in place) on a site change — the picker compares them by
|
||||
// reference and treats a new object as "the site changed".
|
||||
private List<Area> _siteAreas = new();
|
||||
private int _selectedSiteId;
|
||||
private int _selectedInstanceId;
|
||||
private bool _loading = true;
|
||||
@@ -429,7 +430,8 @@
|
||||
|
||||
private async Task LoadInstancesForSite()
|
||||
{
|
||||
_siteInstances.Clear();
|
||||
_siteInstances = new();
|
||||
_siteAreas = new();
|
||||
_selectedInstanceId = 0;
|
||||
if (_selectedSiteId == 0) return;
|
||||
// Site scoping (CentralUI-002): re-check the claim server-side — a query
|
||||
@@ -445,6 +447,7 @@
|
||||
_siteInstances = (await TemplateEngineRepository.GetInstancesBySiteIdAsync(_selectedSiteId))
|
||||
.Where(i => i.State == InstanceState.Enabled)
|
||||
.ToList();
|
||||
_siteAreas = (await TemplateEngineRepository.GetAreasBySiteIdAsync(_selectedSiteId)).ToList();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -452,6 +455,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Handles a pick from the <c>InstancePicker</c> combobox.</summary>
|
||||
private void OnInstancePicked(int id)
|
||||
{
|
||||
_selectedInstanceId = id;
|
||||
OnInstanceSelectionChanged();
|
||||
}
|
||||
|
||||
private void OnInstanceSelectionChanged()
|
||||
{
|
||||
// No-op; selection is tracked via _selectedInstanceId binding
|
||||
@@ -597,7 +607,8 @@
|
||||
await Disconnect();
|
||||
_selectedSiteId = 0;
|
||||
_selectedInstanceId = 0;
|
||||
_siteInstances.Clear();
|
||||
_siteInstances = new();
|
||||
_siteAreas = new();
|
||||
_toast.ShowInfo("Cleared previous session — select a site and instance to begin.", autoDismissMs: 5000);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user