feat(ui/topology): open instance in Debug View from context menu
Adds a Debug View item to the instance context menu on /deployment/topology that navigates to /deployment/debug-view with siteId and instanceId query parameters; the page now auto-connects when those are present (falling back to the existing localStorage auto-reconnect otherwise). Disabled for non-Enabled instances since debug streaming only targets enabled ones. Also fixes a latent NRE in DebugView.OnInitializedAsync: the toast ref isn't bound yet during init, so transient load failures are now stashed and surfaced from OnAfterRenderAsync where the toast is ready.
This commit is contained in:
@@ -247,6 +247,9 @@
|
|||||||
@code {
|
@code {
|
||||||
private const int MaxRows = 200;
|
private const int MaxRows = 200;
|
||||||
|
|
||||||
|
[SupplyParameterFromQuery] public int? SiteId { get; set; }
|
||||||
|
[SupplyParameterFromQuery] public int? InstanceId { get; set; }
|
||||||
|
|
||||||
private List<Site> _sites = new();
|
private List<Site> _sites = new();
|
||||||
private List<Instance> _siteInstances = new();
|
private List<Instance> _siteInstances = new();
|
||||||
private int _selectedSiteId;
|
private int _selectedSiteId;
|
||||||
@@ -287,6 +290,8 @@
|
|||||||
private DebugStreamSession? _session;
|
private DebugStreamSession? _session;
|
||||||
private ToastNotification _toast = default!;
|
private ToastNotification _toast = default!;
|
||||||
|
|
||||||
|
private string? _initError;
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -295,7 +300,7 @@
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_toast.ShowError($"Failed to load sites: {ex.Message}");
|
_initError = $"Failed to load sites: {ex.Message}";
|
||||||
}
|
}
|
||||||
_loading = false;
|
_loading = false;
|
||||||
}
|
}
|
||||||
@@ -304,6 +309,29 @@
|
|||||||
{
|
{
|
||||||
if (!firstRender) return;
|
if (!firstRender) return;
|
||||||
|
|
||||||
|
if (_initError != null)
|
||||||
|
{
|
||||||
|
_toast.ShowError(_initError);
|
||||||
|
_initError = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SiteId is > 0 && InstanceId is > 0)
|
||||||
|
{
|
||||||
|
_selectedSiteId = SiteId.Value;
|
||||||
|
await LoadInstancesForSite();
|
||||||
|
if (_siteInstances.Any(i => i.Id == InstanceId.Value))
|
||||||
|
{
|
||||||
|
_selectedInstanceId = InstanceId.Value;
|
||||||
|
await Connect();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_toast.ShowError("Requested instance is not available for debug streaming.");
|
||||||
|
}
|
||||||
|
StateHasChanged();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var storedSiteId = await JS.InvokeAsync<string>("localStorage.getItem", "debugView.siteId");
|
var storedSiteId = await JS.InvokeAsync<string>("localStorage.getItem", "debugView.siteId");
|
||||||
var storedInstanceId = await JS.InvokeAsync<string>("localStorage.getItem", "debugView.instanceId");
|
var storedInstanceId = await JS.InvokeAsync<string>("localStorage.getItem", "debugView.instanceId");
|
||||||
|
|
||||||
|
|||||||
@@ -452,6 +452,11 @@
|
|||||||
@onclick='() => NavigationManager.NavigateTo($"/deployment/instances/{inst.Id}/configure")'>
|
@onclick='() => NavigationManager.NavigateTo($"/deployment/instances/{inst.Id}/configure")'>
|
||||||
Configure
|
Configure
|
||||||
</button>
|
</button>
|
||||||
|
<button class="dropdown-item"
|
||||||
|
@onclick='() => NavigationManager.NavigateTo($"/deployment/debug-view?siteId={node.SiteId}&instanceId={inst.Id}")'
|
||||||
|
disabled="@(inst.State != InstanceState.Enabled)">
|
||||||
|
Debug View
|
||||||
|
</button>
|
||||||
<button class="dropdown-item" @onclick="() => ShowDiff(inst)"
|
<button class="dropdown-item" @onclick="() => ShowDiff(inst)"
|
||||||
disabled="@(_actionInProgress || inst.State == InstanceState.NotDeployed)">Diff</button>
|
disabled="@(_actionInProgress || inst.State == InstanceState.NotDeployed)">Diff</button>
|
||||||
<button class="dropdown-item" @onclick="() => OpenMoveInstanceDialog(node)">Move to Area…</button>
|
<button class="dropdown-item" @onclick="() => OpenMoveInstanceDialog(node)">Move to Area…</button>
|
||||||
|
|||||||
Reference in New Issue
Block a user