This is an automated email from the ASF dual-hosted git repository.

wusheng pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/skywalking-banyandb.git


The following commit(s) were added to refs/heads/main by this push:
     new b85e2038 fix(UI): moved "Debug Trace" button from below the table to 
above it and correct debug trace data (#826)
b85e2038 is described below

commit b85e20386a5b4554abc06b050caa250701436bac
Author: Fine0830 <[email protected]>
AuthorDate: Mon Oct 27 16:41:16 2025 +0800

    fix(UI): moved "Debug Trace" button from below the table to above it and 
correct debug trace data (#826)
---
 ui/src/components/Property/PropertyRead.vue        | 16 +++----
 ui/src/components/Read/index.vue                   | 14 +++---
 ui/src/components/TopNAggregation/index.vue        | 14 +++---
 ui/src/components/Trace/TraceRead.vue              | 16 +++----
 ui/src/components/TraceTree/MinTimeline.vue        |  5 ++-
 .../components/TraceTree/MinTimelineSelector.vue   |  4 +-
 ui/src/components/TraceTree/SpanNode.vue           |  3 +-
 ui/src/components/TraceTree/Table/TableItem.vue    | 52 +++++++++++++++-------
 ui/src/components/TraceTree/TraceContent.vue       |  2 +-
 ui/src/styles/custom.scss                          |  2 +
 ui/src/styles/main.scss                            | 18 ++++++++
 11 files changed, 88 insertions(+), 58 deletions(-)

diff --git a/ui/src/components/Property/PropertyRead.vue 
b/ui/src/components/Property/PropertyRead.vue
index 2eb567e5..3aba2344 100644
--- a/ui/src/components/Property/PropertyRead.vue
+++ b/ui/src/components/Property/PropertyRead.vue
@@ -149,7 +149,12 @@ limit: 10`;
         <el-button size="small" :icon="RefreshRight" @click="getProperties" 
plain />
       </div>
       <CodeMirror ref="yamlRef" v-model="yamlCode" mode="yaml" style="height: 
200px" :lint="true" />
-      <el-table :data="data.tableData" style="width: 100%; margin-top: 20px" 
border>
+      <div style="margin-top: 20px; margin-bottom: 10px; display: flex; 
justify-content: flex-end">
+        <el-button :icon="TrendCharts" @click="showTracesDialog = true" 
:disabled="!traceData" plain>
+          <span>Debug Trace</span>
+        </el-button>
+      </div>
+      <el-table :data="data.tableData" style="width: 100%" border>
         <el-table-column label="Group" prop="metadata.group" 
width="100"></el-table-column>
         <el-table-column label="Name" prop="metadata.name" 
width="120"></el-table-column>
         <el-table-column label="ModRevision" prop="metadata.modRevision" 
width="120"></el-table-column>
@@ -191,15 +196,6 @@ limit: 10`;
           </template>
         </el-table-column>
       </el-table>
-      <el-button
-        :icon="TrendCharts"
-        @click="showTracesDialog = true"
-        :disabled="!traceData"
-        plain
-        style="margin-top: 20px"
-      >
-        <span>Debug Trace</span>
-      </el-button>
     </el-card>
     <PropertyEditor ref="propertyEditorRef"></PropertyEditor>
     <PropertyValueReader ref="propertyValueViewerRef"></PropertyValueReader>
diff --git a/ui/src/components/Read/index.vue b/ui/src/components/Read/index.vue
index a2897485..333b6e3b 100644
--- a/ui/src/components/Read/index.vue
+++ b/ui/src/components/Read/index.vue
@@ -410,6 +410,11 @@ orderBy:
       <CodeMirror ref="yamlRef" v-model="data.code" mode="yaml" style="height: 
200px" :lint="true" :readonly="false" />
     </el-card>
     <el-card shadow="always">
+      <div style="margin-bottom: 10px; display: flex; justify-content: 
flex-end">
+        <el-button :icon="TrendCharts" :disabled="!traceData" 
@click="showTracesDialog = true" plain>
+          <span>Debug Trace</span>
+        </el-button>
+      </div>
       <el-table
         v-loading="data.loading"
         element-loading-text="loading"
@@ -453,15 +458,6 @@ orderBy:
           </template>
         </el-table-column>
       </el-table>
-      <el-button
-        :icon="TrendCharts"
-        :disabled="!traceData"
-        @click="showTracesDialog = true"
-        plain
-        style="margin-top: 20px"
-      >
-        <span>Debug Trace</span>
-      </el-button>
     </el-card>
   </div>
   <el-dialog
diff --git a/ui/src/components/TopNAggregation/index.vue 
b/ui/src/components/TopNAggregation/index.vue
index b54537e1..e959ecaa 100644
--- a/ui/src/components/TopNAggregation/index.vue
+++ b/ui/src/components/TopNAggregation/index.vue
@@ -172,6 +172,11 @@ fieldValueSort: 1`;
       <CodeMirror ref="yamlRef" v-model="yamlCode" mode="yaml" style="height: 
200px" :lint="true" />
     </el-card>
     <el-card>
+      <div style="margin-bottom: 10px; display: flex; justify-content: 
flex-end">
+        <el-button :icon="TrendCharts" @click="showTracesDialog = true" 
:disabled="!traceData" plain>
+          <span>Debug Trace</span>
+        </el-button>
+      </div>
       <el-table
         :data="currentList"
         style="width: 100%; margin: 10px 0; min-height: 440px"
@@ -192,15 +197,6 @@ fieldValueSort: 1`;
         @prev-click="changePage"
         @next-click="changePage"
       />
-      <el-button
-        :icon="TrendCharts"
-        @click="showTracesDialog = true"
-        :disabled="!traceData"
-        plain
-        :style="{ marginTop: '20px' }"
-      >
-        <span>Debug Trace</span>
-      </el-button>
     </el-card>
   </div>
   <el-dialog
diff --git a/ui/src/components/Trace/TraceRead.vue 
b/ui/src/components/Trace/TraceRead.vue
index 04f65396..5e0cc55c 100644
--- a/ui/src/components/Trace/TraceRead.vue
+++ b/ui/src/components/Trace/TraceRead.vue
@@ -360,7 +360,12 @@ orderBy:
           <span
             ><strong>Total {{ data.tableData.length }} span(s)</strong></span
           >
-          <el-button :icon="Download" @click="downloadMultipleSpans"> Download 
Selected </el-button>
+          <div>
+            <el-button :icon="TrendCharts" @click="showTracesDialog = true" 
:disabled="!traceData" plain>
+              <span>Debug Trace</span>
+            </el-button>
+            <el-button :icon="Download" @click="downloadMultipleSpans"> 
Download Selected </el-button>
+          </div>
         </div>
         <div class="table-container">
           <el-table
@@ -387,15 +392,6 @@ orderBy:
               </template>
             </el-table-column>
           </el-table>
-          <el-button
-            :icon="TrendCharts"
-            @click="showTracesDialog = true"
-            :disabled="!traceData"
-            plain
-            :style="{ marginTop: '20px' }"
-          >
-            <span>Debug Trace</span>
-          </el-button>
         </div>
       </div>
       <el-empty v-else description="No trace data found" style="margin-top: 
20px" />
diff --git a/ui/src/components/TraceTree/MinTimeline.vue 
b/ui/src/components/TraceTree/MinTimeline.vue
index 7d10504c..49cd8ce0 100644
--- a/ui/src/components/TraceTree/MinTimeline.vue
+++ b/ui/src/components/TraceTree/MinTimeline.vue
@@ -19,7 +19,10 @@ limitations under the License. -->
         <MinTimelineMarker :minTimestamp="minTimestamp" 
:maxTimestamp="maxTimestamp" :lineHeight="20" />
       </svg>
     </div>
-    <div class="timeline-content" :style="{ paddingRight: (spanList.length + 
1) * rowHeight < 200 ? '20px' : '14px' }">
+    <div
+      class="timeline-content scroll_bar_style"
+      :style="{ paddingRight: (spanList.length + 1) * rowHeight < 200 ? '20px' 
: '14px' }"
+    >
       <svg ref="svgEle" width="100%" :height="`${(spanList.length + 1) * 
rowHeight}px`">
         <MinTimelineOverlay
           :minTimestamp="minTimestamp"
diff --git a/ui/src/components/TraceTree/MinTimelineSelector.vue 
b/ui/src/components/TraceTree/MinTimelineSelector.vue
index a1a8330d..b34c8fb2 100644
--- a/ui/src/components/TraceTree/MinTimelineSelector.vue
+++ b/ui/src/components/TraceTree/MinTimelineSelector.vue
@@ -76,7 +76,7 @@ limitations under the License. -->
       y="0"
       width="6"
       height="40%"
-      fill="var(--el-color-primary)"
+      fill="var(--el-color-primary-light-5)"
       @mousedown="minRangeHandler.onMouseDown"
       cursor="pointer"
       transform="translate(-3)"
@@ -86,7 +86,7 @@ limitations under the License. -->
       y="0"
       width="6"
       height="40%"
-      fill="var(--el-color-primary)"
+      fill="var(--el-color-primary-light-5)"
       @mousedown="maxRangeHandler.onMouseDown"
       cursor="pointer"
       transform="translate(-3)"
diff --git a/ui/src/components/TraceTree/SpanNode.vue 
b/ui/src/components/TraceTree/SpanNode.vue
index e4b73def..5332a336 100644
--- a/ui/src/components/TraceTree/SpanNode.vue
+++ b/ui/src/components/TraceTree/SpanNode.vue
@@ -76,7 +76,8 @@ limitations under the License. -->
       }
     }
     const dur = end - start;
-    return Math.max(0, widthScale.value(dur));
+
+    return Math.max((props.maxTimestamp - props.minTimestamp) / 50, 
widthScale.value(dur));
   });
 </script>
 
diff --git a/ui/src/components/TraceTree/Table/TableItem.vue 
b/ui/src/components/TraceTree/Table/TableItem.vue
index 455bf7ba..d7ca7755 100644
--- a/ui/src/components/TraceTree/Table/TableItem.vue
+++ b/ui/src/components/TraceTree/Table/TableItem.vue
@@ -35,10 +35,16 @@ limitations under the License. -->
           :style="!displayChildren ? 'transform: rotate(-90deg);' : ''"
           @click.stop="toggle"
           v-if="data.children && data.children.length"
+          style="vertical-align: middle"
         >
           <ArrowDown />
         </el-icon>
-        {{ data.message }}
+        <el-icon v-if="tagError" style="color: red; margin-left: 3px; 
vertical-align: middle">
+          <WarningFilled />
+        </el-icon>
+        <i style="padding-left: 3px; vertical-align: middle; font-style: 
normal">
+          {{ data.message }}
+        </i>
       </div>
       <div class="start-time">
         {{ new Date(data.startTime).toLocaleString() }}
@@ -47,10 +53,10 @@ limitations under the License. -->
         {{ (data.duration / 1000 / 1000).toFixed(3) }}
       </div>
       <div class="exec-percent">
-        {{ outterPercent }}
+        {{ execPercent }}
       </div>
       <div class="exec-percent">
-        {{ innerPercent }}
+        {{ durationPercent }}
       </div>
       <div class="self">
         {{ (data.selfDuration / 1000 / 1000).toFixed(3) }}
@@ -89,7 +95,7 @@ limitations under the License. -->
 </template>
 <script setup>
   import { ref, computed } from 'vue';
-  import { ArrowDown } from '@element-plus/icons-vue';
+  import { ArrowDown, WarningFilled } from '@element-plus/icons-vue';
 
   const props = defineProps({
     data: Object,
@@ -101,20 +107,35 @@ limitations under the License. -->
   const tagsDialogVisible = ref(false);
   const MAX_VISIBLE_TAGS = 1;
 
-  const outterPercent = computed(() => {
+  const tagError = computed(() => {
+    return props.data.tags.find((tag) => tag.key === 'error_msg');
+  });
+  const execPercent = computed(() => {
     if (props.data.level === 1) {
       return '100%';
     }
-    const exec = props.data.endTime - props.data.startTime ? 
props.data.endTime - props.data.startTime : 0;
-    let result = (exec / props.data.totalExec) * 100;
-    result = result > 100 ? 100 : result;
-    const resultStr = result.toFixed(2) + '%';
-    return resultStr === '0.00%' ? '0.9%' : resultStr;
+    const exec = props.data.endTime - props.data.startTime;
+    if (exec < 0) {
+      return '-';
+    }
+    const result = (exec / props.data.totalExec) * 100;
+    if (isNaN(result)) {
+      return '-';
+    }
+    if (result <= 0) {
+      return '0';
+    }
+    return `${result.toFixed(2)}%`;
   });
-  const innerPercent = computed(() => {
+  const durationPercent = computed(() => {
     const result = (props.data.selfDuration / props.data.duration) * 100;
-    const resultStr = result.toFixed(2) + '%';
-    return resultStr === '0.00%' ? '0.9%' : resultStr;
+    if (isNaN(result)) {
+      return '-';
+    }
+    if (result <= 0) {
+      return '0';
+    }
+    return `${result.toFixed(2)}%`;
   });
   const inTimeRange = computed(() => {
     if (props.selectedMinTimestamp === undefined || props.selectedMaxTimestamp 
=== undefined) {
@@ -176,12 +197,11 @@ limitations under the License. -->
   }
 
   .trace-item > div {
-    padding: 0 5px;
+    padding: 5px;
     display: inline-block;
     border: 1px solid transparent;
     border-right: 1px dotted silver;
     overflow: hidden;
-    line-height: 30px;
     text-overflow: ellipsis;
     white-space: nowrap;
   }
@@ -189,6 +209,8 @@ limitations under the License. -->
   .trace-item > div.method {
     padding-left: 10px;
     cursor: pointer;
+    // display: inline-flex;
+    // align-items: center;
   }
 
   .trace-item div.exec-percent {
diff --git a/ui/src/components/TraceTree/TraceContent.vue 
b/ui/src/components/TraceTree/TraceContent.vue
index 3c7a3b10..8b809cb9 100644
--- a/ui/src/components/TraceTree/TraceContent.vue
+++ b/ui/src/components/TraceTree/TraceContent.vue
@@ -92,7 +92,7 @@ limitations under the License. -->
         convertTree(i);
       }
     }
-    d.selfDuration = selfDuration < 0 ? 0 : selfDuration;
+    d.selfDuration = selfDuration > 0 ? selfDuration : 0;
     return d;
   }
   function getAllNodes(tree) {
diff --git a/ui/src/styles/custom.scss b/ui/src/styles/custom.scss
index 7574a74d..aad57b6c 100644
--- a/ui/src/styles/custom.scss
+++ b/ui/src/styles/custom.scss
@@ -63,6 +63,8 @@ html {
   --theme-background: #fff;
   --active-color: var(--el-color-primary);
   --disabled-color: #ccc;
+  --scrollbar-track: #e3dede;
+  --scrollbar-thumb: #aaa5a5;
 }
 
 div {
diff --git a/ui/src/styles/main.scss b/ui/src/styles/main.scss
index 2ac4a71a..b810bce6 100644
--- a/ui/src/styles/main.scss
+++ b/ui/src/styles/main.scss
@@ -235,3 +235,21 @@
 .margin-all-little {
   margin: 10px;
 }
+
+.scroll_bar_style::-webkit-scrollbar {
+  width: 5px;
+  height: 5px;
+  background-color: var(--scrollbar-track);
+}
+
+.scroll_bar_style::-webkit-scrollbar-track {
+  background-color: var(--scrollbar-track);
+  border-radius: 3px;
+  box-shadow: inset 0 0 6px var(--color-placeholder-font);
+}
+
+.scroll_bar_style::-webkit-scrollbar-thumb {
+  border-radius: 3px;
+  box-shadow: inset 0 0 6px var(--color-placeholder-font);
+  background-color: var(--scrollbar-thumb);
+}

Reply via email to