From ebb2c1006efeeccbaa78b47f895859ffcbbd4131 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=8C=E4=B8=AB=E8=AE=B2=E6=A2=B5?= Date: Wed, 23 Sep 2026 14:43:43 +0800 Subject: [PATCH] fix(tabs): hide database label for connection-only targets --- .../lib/__tests__/tabs/tabPresentation.spec.ts | 18 ++++++++++++++++++ .../__tests__/connectionDatabaseInfo.spec.ts | 11 ++++++++++- .../lib/connection/connectionDatabaseInfo.ts | 8 ++++++++ apps/desktop/src/lib/tabs/tabPresentation.ts | 9 +++++++-- 4 files changed, 43 insertions(+), 3 deletions(-) diff --git a/apps/desktop/src/lib/__tests__/tabs/tabPresentation.spec.ts b/apps/desktop/src/lib/__tests__/tabs/tabPresentation.spec.ts index 5b30830171..db28971ded 100644 --- a/apps/desktop/src/lib/__tests__/tabs/tabPresentation.spec.ts +++ b/apps/desktop/src/lib/__tests__/tabs/tabPresentation.spec.ts @@ -322,6 +322,24 @@ describe("tab group presentation", () => { ]); }); + it("omits the database row from tooltips for connections without a database target", () => { + const store = useConnectionStore(); + store.sidebarLayout = { + groups: [], + order: [{ type: "connection", id: "conn-1" }], + }; + + for (const dbType of ["dynamodb", "elasticsearch", "easysearch", "meilisearch", "solr", "qdrant", "weaviate", "chromadb", "etcd", "zookeeper", "nacos", "consul", "mq", "mqtt", "victoriametrics"] as const) { + store.connections = [{ id: "conn-1", name: "Local", db_type: dbType, database: "default" } as ConnectionConfig]; + + const lines = tabTooltipLines(queryTab({ database: "default" }), translate); + + expect(lines, dbType).toContainEqual({ label: "Connection:", value: "Local" }); + expect(lines, dbType).toContainEqual({ label: "Group:", value: "Ungrouped" }); + expect(lines, dbType).not.toContainEqual({ label: "Database:", value: "default" }); + } + }); + it("labels a top-level connection as ungrouped", () => { const store = useConnectionStore(); store.connections = [{ id: "conn-1", name: "PostgreSQL", db_type: "postgres", database: "app" } as ConnectionConfig]; diff --git a/apps/desktop/src/lib/connection/__tests__/connectionDatabaseInfo.spec.ts b/apps/desktop/src/lib/connection/__tests__/connectionDatabaseInfo.spec.ts index 1461251b74..117e72d0b1 100644 --- a/apps/desktop/src/lib/connection/__tests__/connectionDatabaseInfo.spec.ts +++ b/apps/desktop/src/lib/connection/__tests__/connectionDatabaseInfo.spec.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from "vitest"; import type { ConnectionConfig } from "@/types/database"; -import { connectionConfigFingerprint, databaseInfoCopyText, databaseInfoRows, isTauriCommandUnavailable, normalizeConnectionTestResult } from "@/lib/connection/connectionDatabaseInfo"; +import { connectionConfigFingerprint, databaseInfoCopyText, databaseInfoRows, isTauriCommandUnavailable, normalizeConnectionTestResult, supportsConnectionDatabaseInfo } from "@/lib/connection/connectionDatabaseInfo"; function config(overrides: Partial = {}): ConnectionConfig { return { @@ -17,6 +17,15 @@ function config(overrides: Partial = {}): ConnectionConfig { } describe("connectionDatabaseInfo", () => { + it("hides database information for connections without database metadata", () => { + for (const dbType of ["dynamodb", "elasticsearch", "easysearch", "meilisearch", "solr", "qdrant", "weaviate", "chromadb", "etcd", "zookeeper", "nacos", "consul", "mq", "mqtt", "victoriametrics"] as const) { + expect(supportsConnectionDatabaseInfo(dbType)).toBe(false); + } + for (const dbType of ["mysql", "redis", "mongodb", "milvus", "turso", "cloudflare-d1", "plugin"] as const) { + expect(supportsConnectionDatabaseInfo(dbType)).toBe(true); + } + }); + it("normalizes structured and legacy responses with a configured product fallback", () => { expect(normalizeConnectionTestResult("Connection successful", config())).toEqual({ message: "Connection successful", diff --git a/apps/desktop/src/lib/connection/connectionDatabaseInfo.ts b/apps/desktop/src/lib/connection/connectionDatabaseInfo.ts index 4fc1b8266c..f1eec49276 100644 --- a/apps/desktop/src/lib/connection/connectionDatabaseInfo.ts +++ b/apps/desktop/src/lib/connection/connectionDatabaseInfo.ts @@ -7,6 +7,14 @@ export interface DatabaseInfoRow { value: string; } +// These connections have no real database metadata. VictoriaMetrics exposes a +// configured label as a synthetic database node, not a server database. +const DATABASE_INFO_UNSUPPORTED_TYPES = new Set(["dynamodb", "elasticsearch", "easysearch", "meilisearch", "solr", "qdrant", "weaviate", "chromadb", "etcd", "zookeeper", "nacos", "consul", "mq", "mqtt", "victoriametrics"]); + +export function supportsConnectionDatabaseInfo(dbType: ConnectionConfig["db_type"]): boolean { + return !DATABASE_INFO_UNSUPPORTED_TYPES.has(dbType); +} + const DATABASE_INFO_FIELDS: readonly DatabaseInfoField[] = ["productName", "productVersion", "currentDatabase", "serverComment", "serverCharset", "serverCollation", "unquotedIdentifierCase", "quotedIdentifierCase", "driverName", "driverVersion", "jdbcVersion"]; const IDENTIFIER_CASES = new Set(["lower", "upper", "mixed"]); diff --git a/apps/desktop/src/lib/tabs/tabPresentation.ts b/apps/desktop/src/lib/tabs/tabPresentation.ts index 37bc91f083..6daaa7978d 100644 --- a/apps/desktop/src/lib/tabs/tabPresentation.ts +++ b/apps/desktop/src/lib/tabs/tabPresentation.ts @@ -3,6 +3,7 @@ import { useSettingsStore } from "@/stores/settingsStore"; import { hexToRgba } from "@/lib/common/color"; import type { CSSProperties } from "vue"; import { findConnectionGroupPath } from "@/lib/sidebar/sidebarLayout"; +import { supportsConnectionDatabaseInfo } from "@/lib/connection/connectionDatabaseInfo"; import { splitMongoCommandRanges } from "@/lib/mongo/mongoShellCommand"; import { executableStatementRanges, splitSqlStatementRanges, sqlStatementParameterOptionsForCompatibility, type SqlTextRange } from "@/lib/sql/sqlStatementRanges"; import type { SqlParameterOptions } from "@/lib/sql/sqlParameters"; @@ -259,8 +260,12 @@ export function tabDisplayTitle(tab: QueryTab, t: Translate): string { export function tabTooltipLines(tab: QueryTab, t: Translate): { label: string; value: string }[] { const connName = connectionDisplayName(tab.connectionId); const groupName = connectionGroupDisplayName(tab.connectionId, t); - const database = databaseDisplayNameForTab(tab.connectionId, tab.database, t); - const lines: { label: string; value: string }[] = [{ label: t("tabs.tooltipConnection"), value: connName }, ...(groupName ? [{ label: t("tabs.tooltipGroup"), value: groupName }] : []), { label: t("tabs.tooltipDatabase"), value: database }]; + const connection = useConnectionStore().getConfig(tab.connectionId); + const lines: { label: string; value: string }[] = [ + { label: t("tabs.tooltipConnection"), value: connName }, + ...(groupName ? [{ label: t("tabs.tooltipGroup"), value: groupName }] : []), + ...(!connection || supportsConnectionDatabaseInfo(connection.db_type) ? [{ label: t("tabs.tooltipDatabase"), value: databaseDisplayNameForTab(tab.connectionId, tab.database, t) }] : []), + ]; if (tab.mode === "query" && queryTitle(tab)) { lines.unshift({ label: t("tabs.tooltipTitle"), value: tab.title }); }