This is an automated email from the ASF dual-hosted git repository.
wu-sheng pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/skywalking-horizon-ui.git
The following commit(s) were added to refs/heads/main by this push:
new 54b5adc ui dashboards: don't bounce ?instance= when list is briefly
empty + cover full upstream wait in loading state
54b5adc is described below
commit 54b5adc596d87b15be981d5439f98c909dd69521
Author: Wu Sheng <[email protected]>
AuthorDate: Sun May 17 17:59:20 2026 +0800
ui dashboards: don't bounce ?instance= when list is briefly empty + cover
full upstream wait in loading state
Two complementary fixes that together stop the "two instances
visible but neither selected and no dashboard" symptom on
/layer/<x>/instance?service=&instance=:
1. Instance auto-pick watch was clearing the URL `?instance=` on
the transient empty-list state (service just resolved, the
layer-instances vue-query has fired but the response hasn't
landed yet). The clear caused a URL bounce: ?instance=X → no
instance → ?instance=X again, with dashboard.enabled going
false → true in between and the picker showing no highlight
during the gap. Now we simply wait for actual instance data;
if the list eventually resolves to truly empty (loading false +
length 0), the picker's own empty state handles it.
2. The "Reading data…" indicator was gated on
`isFetching && data === null` — that misses the window where
serviceName hasn't resolved (landing query still firing) and
the dashboard query hasn't even been enabled yet
(isFetching=false). The grid v-else rendered with empty
widgets during that gap. Now gates on `data === null && reachable`,
so the indicator covers the full upstream wait
(landing → service → instance/endpoint → dashboard). OAP-
unreachable still falls through to the existing error banner.
---
.../render/layer-dashboard/LayerDashboardsView.vue | 35 ++++++++++++++--------
1 file changed, 22 insertions(+), 13 deletions(-)
diff --git a/apps/ui/src/render/layer-dashboard/LayerDashboardsView.vue
b/apps/ui/src/render/layer-dashboard/LayerDashboardsView.vue
index fc6babb..246ba7f 100644
--- a/apps/ui/src/render/layer-dashboard/LayerDashboardsView.vue
+++ b/apps/ui/src/render/layer-dashboard/LayerDashboardsView.vue
@@ -172,10 +172,15 @@ watch(serviceName, (next, prev) => {
// the pick when the list arrived synchronously.
watch([instanceList, scope], ([list, s]) => {
if (s !== 'instance') return;
- if (list.length === 0) {
- if (selectedInstance.value) setSelectedInstance(null);
- return;
- }
+ // Don't clear the URL ?instance= when the list is TEMPORARILY
+ // empty (e.g. service just changed and the instance query is
+ // re-firing) — clearing causes a visible URL bounce that
+ // strips the operator's pick and breaks dashboard.enabled. We
+ // simply wait for actual instance data; if the list eventually
+ // resolves to truly empty (instancesLoading false + length 0),
+ // the picker's own empty state handles it and the dashboard
+ // gate keeps the widget batch quiet.
+ if (list.length === 0) return;
if (!selectedInstance.value || !list.some((i) => i.name ===
selectedInstance.value)) {
setSelectedInstance(list[0].name);
}
@@ -537,15 +542,19 @@ function isVisible(
<div v-else-if="widgets.length === 0" class="empty">
No widgets defined for this layer. Phase 7 admin will let operators add
their own.
</div>
- <!-- Single page-level loading state while the widget batch is
- in flight without a prior result. Replaces the per-widget
- "loading…" cards from f9866cf — the dashboard query is
- batched so the widgets all land together; one indicator is
- cleaner than N. Once the result is in `data`, the grid
- takes over and shows each widget's value / no-data / error
- normally. Background refetches (auto-refresh) keep showing
- the prior data, no flash. -->
- <div v-else-if="isFetching && data === null" class="empty reading">
+ <!-- Single page-level loading state while we don't yet have
+ widget data to render. Covers the whole upstream wait,
+ not just the dashboard fetch:
+ - landing query in flight (serviceName unresolved →
+ dashboard.enabled still false, isFetching=false,
+ but we're still loading)
+ - dashboard query in flight
+ The widget batch is server-side batched so widgets all
+ land together; one indicator is cleaner than N "loading…"
+ cards. Once `data` arrives, the grid takes over and shows
+ each widget's value / no-data / error normally. Background
+ refetches keep showing the prior data, no flash. -->
+ <div v-else-if="data === null && reachable" class="empty reading">
<span class="reading-dot" /> Reading data…
</div>
<div v-else class="grid">