From 26cc83e351d540f2ddaab0d132b1775317fc8ebd Mon Sep 17 00:00:00 2001
From: t8y2 <1156263951@qq.com>
Date: Thu, 21 May 2026 17:43:35 +0800
Subject: [PATCH] feat(desktop): improve data tabs switcher UX
---
.../src/components/layout/AppTabBar.vue | 85 +++++++++++++++----
apps/desktop/src/i18n/locales/en.ts | 1 +
apps/desktop/src/i18n/locales/es.ts | 1 +
apps/desktop/src/i18n/locales/zh-CN.ts | 1 +
.../app-tests/appTabBarDataTabsMenu.test.ts | 17 ++++
5 files changed, 87 insertions(+), 18 deletions(-)
create mode 100644 packages/app-tests/appTabBarDataTabsMenu.test.ts
diff --git a/apps/desktop/src/components/layout/AppTabBar.vue b/apps/desktop/src/components/layout/AppTabBar.vue
index 180e2cf6f..ef6c6181c 100644
--- a/apps/desktop/src/components/layout/AppTabBar.vue
+++ b/apps/desktop/src/components/layout/AppTabBar.vue
@@ -1,7 +1,7 @@
@@ -126,19 +158,16 @@ function tabIconClass(tab: QueryTab) {
: 'h-10 items-center bg-background px-2'
"
>
-
+ class="pointer-events-none absolute left-0 z-10 h-full w-6 bg-linear-to-r from-background from-40% to-transparent"
+ aria-hidden="true"
+ />
@@ -262,13 +291,33 @@ function tabIconClass(tab: QueryTab) {
-
+ class="pointer-events-none absolute right-0 z-20 h-full w-6 bg-linear-to-l from-background from-40% to-transparent"
+ aria-hidden="true"
+ />
+
+
+
+
+
+
+
+
+ {{ tabDisplayTitle(tab) }}
+
+
+
+
diff --git a/apps/desktop/src/i18n/locales/en.ts b/apps/desktop/src/i18n/locales/en.ts
index f437df546..323a1c1b7 100644
--- a/apps/desktop/src/i18n/locales/en.ts
+++ b/apps/desktop/src/i18n/locales/en.ts
@@ -225,6 +225,7 @@ export default {
resultN: "Result {n}",
scrollLeft: "Scroll tabs left",
scrollRight: "Scroll tabs right",
+ openDataTabs: "Open tables",
},
chart: {
title: "Chart",
diff --git a/apps/desktop/src/i18n/locales/es.ts b/apps/desktop/src/i18n/locales/es.ts
index 4b89b8a5b..a221f19bb 100644
--- a/apps/desktop/src/i18n/locales/es.ts
+++ b/apps/desktop/src/i18n/locales/es.ts
@@ -220,6 +220,7 @@ export default {
resultN: "Resultado {n}",
scrollLeft: "Desplazar pestañas a la izquierda",
scrollRight: "Desplazar pestañas a la derecha",
+ openDataTabs: "Tablas abiertas",
},
chart: {
title: "Gráfico",
diff --git a/apps/desktop/src/i18n/locales/zh-CN.ts b/apps/desktop/src/i18n/locales/zh-CN.ts
index 15358b817..ac80cae27 100644
--- a/apps/desktop/src/i18n/locales/zh-CN.ts
+++ b/apps/desktop/src/i18n/locales/zh-CN.ts
@@ -223,6 +223,7 @@ export default {
resultN: "结果 {n}",
scrollLeft: "向左滚动标签页",
scrollRight: "向右滚动标签页",
+ openDataTabs: "已打开的数据表",
},
chart: {
title: "图表",
diff --git a/packages/app-tests/appTabBarDataTabsMenu.test.ts b/packages/app-tests/appTabBarDataTabsMenu.test.ts
new file mode 100644
index 000000000..842022a7a
--- /dev/null
+++ b/packages/app-tests/appTabBarDataTabsMenu.test.ts
@@ -0,0 +1,17 @@
+import { readFileSync } from "node:fs";
+import assert from "node:assert/strict";
+import test from "node:test";
+
+test("tab bar exposes a data-table-only dropdown switcher", () => {
+ const source = readFileSync("apps/desktop/src/components/layout/AppTabBar.vue", "utf8");
+
+ assert.match(source, /tab\.mode === "data"/);
+ assert.match(source, /showPinnedDataTabsMenu = computed\(\(\) => dataTabs\.value\.length > 0 && \(canScrollLeft\.value \|\| canScrollRight\.value\)\)/);
+ assert.match(source, /const dataTabsMenuContainerClass = computed\(\(\) =>/);
+ assert.match(source, /
/);
+ assert.match(source, /t\(['"]tabs\.openDataTabs['"]\)/);
+ assert.match(source, /DropdownMenuContent align="end" class="w-auto min-w-36 max-w-60"/);
+ assert.match(source, /ChevronDown class="h-4 w-4"/);
+ assert.match(source, /
/);
+ assert.match(source, /@click="activateDataTab\(tab\.id\)"/);
+});