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 ebc2268  ui debug panel: snappier toggle, no horizontal scroll, no 
page cover
ebc2268 is described below

commit ebc226865da603a22257470e0eb36f1150e55a77
Author: Wu Sheng <[email protected]>
AuthorDate: Sun May 17 17:47:56 2026 +0800

    ui debug panel: snappier toggle, no horizontal scroll, no page cover
    
    Addressed three operator-reported issues with the new bottom
    panel:
    
    1. Snappier toggle. `v-if` was tearing down + re-mounting the
       panel on every click (re-attach event listeners, re-bind
       reactivity). Switched to `v-show` so the VNode tree stays
       mounted and only `display` flips — instant response.
    
    2. No horizontal scroll in the sidebar. `.sw-nav` was using
       `overflow: auto` which let the new Admin → "Debug events"
       toggle row spill the sidebar horizontally if the row was
       slightly wider than the column. Now `overflow-x: hidden;
       overflow-y: auto;`. Also tightened `.sw-nav-toggle` with
       `min-width: 0` + ellipsis on its label span so the row clips
       cleanly instead of pushing the container.
    
    3. Page content no longer covered. `.sw-main` gains a
       `has-debug-panel` modifier when the toggle is on, reserving
       the 26px collapsed bar height as `padding-bottom`. The expanded
       popover stays a transient overlay — operators close it
       explicitly, reserving its full 260px permanently would burn
       vertical real estate.
---
 apps/ui/src/shell/AppShell.vue        | 17 ++++++++++++++++-
 apps/ui/src/shell/AppSidebar.vue      | 11 +++++++++++
 apps/ui/src/shell/DebugEventPanel.vue |  7 +++++--
 packages/design-tokens/src/tokens.css |  2 +-
 4 files changed, 33 insertions(+), 4 deletions(-)

diff --git a/apps/ui/src/shell/AppShell.vue b/apps/ui/src/shell/AppShell.vue
index 5a28234..bea678f 100644
--- a/apps/ui/src/shell/AppShell.vue
+++ b/apps/ui/src/shell/AppShell.vue
@@ -26,6 +26,7 @@ import ZipkinTracePopout from 
'@/layer/traces/ZipkinTracePopout.vue';
 import { ensureConfigBundle, useConfigBundle } from '@/controls/configBundle';
 import { useClickTracking } from '@/controls/useClickTracking';
 import { useLayers } from '@/shell/useLayers';
+import { useDebugPanel } from '@/controls/debugPanel';
 
 // Kick the config preload once the shell mounts (i.e. after the auth
 // guard has let the user through). All layer dashboard configs +
@@ -59,13 +60,20 @@ const menuSettled = computed<boolean>(
 const initReady = computed<boolean>(
   () => menuSettled.value && bundleLoaded.value,
 );
+
+// Reserve bottom padding on the main pane equal to the panel's
+// collapsed height when the debug panel is enabled, so the panel
+// doesn't overlay page content. The expanded popover is still a
+// transient overlay (operator dismisses it explicitly) — reserving
+// 260px permanently would waste real estate.
+const { enabled: debugPanelEnabled } = useDebugPanel();
 </script>
 
 <template>
   <div class="sw">
     <AppSidebar />
     <AppTopbar />
-    <main class="sw-main">
+    <main class="sw-main" :class="{ 'has-debug-panel': debugPanelEnabled }">
       <!-- Sticky strip under the topbar; only renders when the graphql
            (`:12800`) poll reports unreachable. Admin-port (`:17128`)
            failures render per-page via AdminFeatureWarning, not here. -->
@@ -98,6 +106,13 @@ const initReady = computed<boolean>(
 </template>
 
 <style scoped>
+/* Reserve room for the collapsed DebugEventPanel (26px) when it's
+ * enabled so the panel doesn't overlay page content. Expanded
+ * popover stays a transient overlay — operators close it
+ * explicitly, reserving its full 260px permanently would waste
+ * vertical real estate. */
+.sw-main.has-debug-panel { padding-bottom: 26px; }
+
 .sw-init {
   padding: 48px 20px;
   display: flex;
diff --git a/apps/ui/src/shell/AppSidebar.vue b/apps/ui/src/shell/AppSidebar.vue
index ac9cb42..46d48b7 100644
--- a/apps/ui/src/shell/AppSidebar.vue
+++ b/apps/ui/src/shell/AppSidebar.vue
@@ -953,11 +953,22 @@ watch(
  * "on" reads consistently with selected nav items. */
 .sw-nav-toggle {
   width: 100%;
+  min-width: 0;
   background: transparent;
   border: none;
   font: inherit;
   text-align: left;
   cursor: pointer;
+  /* Defensive: keep the label + badge inside the sidebar even if
+   * future copy grows. Combined with `.sw-nav` overflow-x: hidden,
+   * the row clips cleanly instead of forcing a horizontal scroll. */
+  overflow: hidden;
+}
+.sw-nav-toggle > span:not(.sw-badge) {
+  min-width: 0;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
 }
 .sw-nav-toggle .sw-badge.ok {
   color: var(--sw-ok);
diff --git a/apps/ui/src/shell/DebugEventPanel.vue 
b/apps/ui/src/shell/DebugEventPanel.vue
index e14627c..5876850 100644
--- a/apps/ui/src/shell/DebugEventPanel.vue
+++ b/apps/ui/src/shell/DebugEventPanel.vue
@@ -54,8 +54,11 @@ const eventCount = computed<number>(() => all.value.length);
 </script>
 
 <template>
-  <div v-if="enabled" class="dbg" :class="['dbg-kind-' + latestKind, { open 
}]" data-no-event-track>
-    <div v-if="open" class="dbg-popover">
+  <!-- v-show (not v-if) so the toggle responds instantly — the
+       VNode tree stays mounted, only display flips. Saves the
+       re-mount + sticky-listener re-attach cost on every click. -->
+  <div v-show="enabled" class="dbg" :class="['dbg-kind-' + latestKind, { open 
}]" data-no-event-track>
+    <div v-show="open" class="dbg-popover">
       <header class="dbg-pop-head">
         <span class="dbg-title">Framework events</span>
         <span class="dbg-tag">last {{ eventCount }}</span>
diff --git a/packages/design-tokens/src/tokens.css 
b/packages/design-tokens/src/tokens.css
index 92919ee..b1111d5 100644
--- a/packages/design-tokens/src/tokens.css
+++ b/packages/design-tokens/src/tokens.css
@@ -132,7 +132,7 @@
 .sw-brand-mark svg { width: 13px; height: 13px; color: #fff; }
 .sw-brand small { font-weight: 500; color: var(--sw-fg-2); margin-left: 2px; }
 
-.sw-nav { padding: 8px 6px; flex: 1; overflow: auto; }
+.sw-nav { padding: 8px 6px; flex: 1; overflow-x: hidden; overflow-y: auto; }
 .sw-nav-section {
   font-size: 10px; font-weight: 700; text-transform: uppercase; 
letter-spacing: 0.1em;
   color: var(--sw-fg-3); padding: 14px 14px 4px;

Reply via email to