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 9e7d32a ui dashboards: make click feedback immediate (named loading +
picker hold)
9e7d32a is described below
commit 9e7d32af25bd2472cababd15627d010d7769cc21
Author: Wu Sheng <[email protected]>
AuthorDate: Sun May 17 19:59:07 2026 +0800
ui dashboards: make click feedback immediate (named loading + picker hold)
Two visible-by-tick-zero responses on click:
1. The "Reading data…" indicator now names the new selection
("Reading data for agent::songs / instance-3…"). The operator
sees WHAT is loading the moment the cascade resets — no more
anonymous spinner.
2. Service picker holds open for 140ms after click instead of
unmounting in the same tick. That single animation frame is
what gives Vue a chance to paint the `.row.active` highlight on
the just-clicked row, so the click visibly registers before the
picker animates away. Without the hold the picker disappeared
so fast the selected state was never rendered, and the operator
saw "nothing happened" until the BFF response landed.
No additional fetches — the cascade timing is unchanged. This is
strictly about giving the click a visible echo at the moment it
fires, per CLAUDE.md's cascade-clear-then-load principle.
---
apps/ui/src/layer/LayerShell.vue | 9 ++++++++-
.../ui/src/render/layer-dashboard/LayerDashboardsView.vue | 15 ++++++++++++++-
2 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/apps/ui/src/layer/LayerShell.vue b/apps/ui/src/layer/LayerShell.vue
index eff3ea0..161c3b3 100644
--- a/apps/ui/src/layer/LayerShell.vue
+++ b/apps/ui/src/layer/LayerShell.vue
@@ -186,8 +186,15 @@ function togglePicker(): void {
pickerOpen.value = !pickerOpen.value;
}
function pickService(id: string): void {
+ // Update selection FIRST and let the picker render the highlight
+ // on the just-clicked row before unmounting — closing in the same
+ // tick swallows the visual confirmation that the click registered.
+ // 140ms is short enough to feel responsive and long enough for one
+ // animation frame to paint the new `:class="{ active }"` state.
setSelected(id);
- pickerOpen.value = false;
+ setTimeout(() => {
+ pickerOpen.value = false;
+ }, 140);
}
// ── Header identity ──────────────────────────────────────────────────
diff --git a/apps/ui/src/render/layer-dashboard/LayerDashboardsView.vue
b/apps/ui/src/render/layer-dashboard/LayerDashboardsView.vue
index 15dfd23..f603254 100644
--- a/apps/ui/src/render/layer-dashboard/LayerDashboardsView.vue
+++ b/apps/ui/src/render/layer-dashboard/LayerDashboardsView.vue
@@ -638,7 +638,20 @@ function isVisible(
each widget's value / no-data / error normally. Background
refetches keep showing the prior data, no flash. -->
<div v-else-if="!dataIsFresh && reachable" class="empty reading">
- <span class="reading-dot" /> Reading data…
+ <span class="reading-dot" />
+ <span>
+ Reading data
+ <template v-if="serviceName">
+ for <b>{{ serviceName }}</b>
+ <template v-if="scope === 'instance' && selectedInstance">
+ / <b>{{ selectedInstance }}</b>
+ </template>
+ <template v-else-if="scope === 'endpoint' && selectedEndpoint">
+ / <b>{{ selectedEndpoint }}</b>
+ </template>
+ </template>
+ …
+ </span>
</div>
<div v-else class="grid">
<div