🐛 fix(tab): 修复 Schema 副行显示 (#851) (#852)

## 关联 Issue

Fixes #851

## 问题根因

Tab 标签展示的 Schema 字段只从 `tableName`、`viewName` 等对象名称的限定前缀推导,没有读取
`TabData.schemaName`。当 PostgreSQL / Kingbase 标签使用“裸对象名 + 独立 schema
元数据”时,Schema 副行为空,而仍启用的 Database 字段继续展示数据库名,表现为选择 Schema 后仍只看到数据库名称。

## 修复方案

- Schema 标签值优先使用 `TabData.schemaName`,缺失时保留原有的限定对象名解析逻辑。
- 增加“裸表名 + 独立 schema 元数据”的回归测试,确认双行标签副行展示 `SCHEMA:reporting`。
- 不改变数据库字段、对象标题、标签配置格式或已有 schema 限定名行为。

## 验证结果

| 验证项 | 命令或步骤 | 结果 |
| --- | --- | --- |
| 缺陷复现 | `npm --prefix frontend test --
src/utils/tabDisplay.test.ts`(修复前) | 新增用例失败:副行实际为空,期望 `SCHEMA:reporting`
|
| Schema 副行回归 | `npm --prefix frontend test --
src/utils/tabDisplay.test.ts` | 通过,23/23 |
| 标签展示相关测试 | `npm --prefix frontend test --
src/components/TabManager.hover.test.tsx
src/components/TabManager.recent.test.ts src/utils/tabDisplay.test.ts` |
通过,38/38 |
| 完整前端测试 | `npm --prefix frontend test` | 通过,445 个文件、3770/3770 |
| 前端生产构建 | `npm --prefix frontend run build` | 通过,TypeScript 与 Vite 构建完成
|
| GUI 设置交互 | 浏览器模式打开“设置中心 → 主题与外观 → 工作区”,启用 Schema | 通过,Schema
自动加入副行,预览更新;测试后已恢复原设置 |
| GUI 布局 | 1280×720 与应用最小支持宽度 900×720 | 通过,无白屏或控件重叠 |
| Diff 检查 | `git diff --check`、`git diff --cached --check` | 通过 |

浏览器 Mock 不提供 PostgreSQL / Kingbase schema 表数据,无法在 GUI 中构造“裸表名 + 独立
schema 元数据”的精确对象标签;该路径由新增回归测试覆盖。内置浏览器未提供控制台日志读取接口。

## 风险与兼容性

改动仅影响标签 Schema 字段的取值优先级。已有 `schemaName` 时使用专用元数据;未提供时继续从限定对象名解析。无公共
API、配置、持久化格式、数据、并发或性能变化。

## 回滚方式

回滚提交 `90020799ad078d3cb5db7bc495fb6f23d1f6bc68` 即可。回滚只恢复旧的标签 Schema
推导逻辑,不影响数据或配置。
This commit is contained in:
Syngnat
2026-08-06 12:11:24 +08:00
committed by GitHub
2 changed files with 22 additions and 1 deletions

View File

@@ -407,6 +407,27 @@ describe('tabDisplay', () => {
expect(model.fullTitle).toBe('TABLE events · [PROD]·analytics·SCHEMA:reporting·10.0.0.9');
});
it('uses explicit schema metadata for unqualified table names', () => {
const tableTab: TabData = {
id: 'pg-1-analytics-table-reporting-events',
title: 'events',
type: 'table',
connectionId: 'pg-1',
dbName: 'analytics',
tableName: 'events',
schemaName: 'reporting',
};
const model = buildTabDisplayModel(tableTab, undefined, {
layout: 'double',
primaryElements: ['object'],
secondaryElements: ['schema'],
});
expect(model.primaryText).toBe('events');
expect(model.secondaryText).toBe('SCHEMA:reporting');
});
it('sanitizes tab display settings with fallback defaults', () => {
expect(sanitizeTabDisplaySettings({
layout: 'invalid' as never,

View File

@@ -554,7 +554,7 @@ const getTabDisplayElementValue = (
case 'database':
return String(tab.dbName || '').trim();
case 'schema':
return getSchemaFromTabObjectLabel(rawObjectLabel);
return String(tab.schemaName || '').trim() || getSchemaFromTabObjectLabel(rawObjectLabel);
case 'host':
return resolveConnectionHostSummary(connection?.config);
default: