feat(sidebar): 支持表元数据显示配置

- 新增侧栏表元数据字段配置并兼容旧版表备注开关
- 设置中心新增侧栏表元数据入口并移除树上重复显示开关
- 批量补齐表大小、创建时间、修改时间等元数据加载与渲染
- 统一表元数据格式化逻辑并修复 V2 左树横向滚动裁切
- 补充设置中心、store、侧栏元数据相关回归测试与多语言文案
This commit is contained in:
Syngnat
2026-07-02 12:54:43 +08:00
parent 92eb4266da
commit 68d4081fcf
23 changed files with 1097 additions and 251 deletions

View File

@@ -0,0 +1,27 @@
import { describe, expect, it } from 'vitest';
import {
resolveSidebarTableMetadataFields,
sanitizeSidebarTableMetadataFields,
setSidebarTableMetadataFieldSelected,
} from './sidebarTableMetadata';
describe('sidebarTableMetadata', () => {
it('keeps the default sidebar table metadata to row counts when no value is provided', () => {
expect(resolveSidebarTableMetadataFields(undefined, false)).toEqual(['rows']);
});
it('migrates the legacy sidebar table comment toggle into the metadata field list', () => {
expect(resolveSidebarTableMetadataFields(undefined, true)).toEqual(['comment', 'rows']);
});
it('preserves an explicit empty metadata selection while filtering unknown fields', () => {
expect(sanitizeSidebarTableMetadataFields([], [])).toEqual([]);
expect(sanitizeSidebarTableMetadataFields(['updatedAt', 'unknown', 'rows'], [])).toEqual(['rows', 'updatedAt']);
});
it('toggles metadata fields in a canonical display order', () => {
expect(setSidebarTableMetadataFieldSelected(['rows'], 'size', true)).toEqual(['rows', 'size']);
expect(setSidebarTableMetadataFieldSelected(['comment', 'rows', 'size'], 'comment', false)).toEqual(['rows', 'size']);
});
});

View File

@@ -0,0 +1,86 @@
export const SIDEBAR_TABLE_METADATA_FIELDS = [
'comment',
'rows',
'size',
'createdAt',
'updatedAt',
] as const;
export type SidebarTableMetadataField =
typeof SIDEBAR_TABLE_METADATA_FIELDS[number];
export interface SidebarTableMetadataSnapshot {
tableComment?: string;
rowCount?: number;
tableSize?: number;
createdAt?: string;
updatedAt?: string;
}
export const DEFAULT_SIDEBAR_TABLE_METADATA_FIELDS: SidebarTableMetadataField[] = [
'rows',
];
const isSidebarTableMetadataField = (
value: unknown,
): value is SidebarTableMetadataField =>
typeof value === 'string'
&& SIDEBAR_TABLE_METADATA_FIELDS.includes(
value as SidebarTableMetadataField,
);
const orderSidebarTableMetadataFields = (
fields: Iterable<SidebarTableMetadataField>,
): SidebarTableMetadataField[] => {
const selected = new Set(fields);
return SIDEBAR_TABLE_METADATA_FIELDS.filter((field) => selected.has(field));
};
export const sanitizeSidebarTableMetadataFields = (
value: unknown,
fallback: SidebarTableMetadataField[] = DEFAULT_SIDEBAR_TABLE_METADATA_FIELDS,
): SidebarTableMetadataField[] => {
if (!Array.isArray(value)) {
return orderSidebarTableMetadataFields(fallback);
}
const normalized = orderSidebarTableMetadataFields(
value.filter(isSidebarTableMetadataField),
);
if (normalized.length === 0) {
return orderSidebarTableMetadataFields(fallback);
}
return normalized;
};
export const resolveSidebarTableMetadataFields = (
value: unknown,
legacyShowSidebarTableComment = false,
): SidebarTableMetadataField[] => {
if (Array.isArray(value)) {
return orderSidebarTableMetadataFields(
value.filter(isSidebarTableMetadataField),
);
}
const defaults = new Set<SidebarTableMetadataField>(
DEFAULT_SIDEBAR_TABLE_METADATA_FIELDS,
);
if (legacyShowSidebarTableComment) {
defaults.add('comment');
}
return orderSidebarTableMetadataFields(defaults);
};
export const setSidebarTableMetadataFieldSelected = (
fields: SidebarTableMetadataField[],
target: SidebarTableMetadataField,
selected: boolean,
): SidebarTableMetadataField[] => {
const next = new Set(resolveSidebarTableMetadataFields(fields));
if (selected) {
next.add(target);
} else {
next.delete(target);
}
return orderSidebarTableMetadataFields(next);
};