From a0bb19b8bb19821b4e06e3fd6d9b366b706b26a1 Mon Sep 17 00:00:00 2001 From: Syngnat Date: Tue, 14 Jul 2026 21:53:57 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat(sidebar):=20=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89=E5=AF=B9=E8=B1=A1=E5=88=86=E7=B1=BB?= =?UTF-8?q?=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增侧栏对象分类开关与仅显示表快捷设置 配置持久化并即时应用到所有连接 补充筛选、持久化与国际化回归测试 --- frontend/src/App.settings-center.test.ts | 13 ++- frontend/src/App.tsx | 91 ++++++++++++++++++- frontend/src/components/Sidebar.tsx | 11 ++- .../SidebarObjectGroups.i18n.test.ts | 21 +++++ frontend/src/store.test.ts | 28 ++++++ frontend/src/store.ts | 9 ++ .../src/utils/sidebarObjectVisibility.test.ts | 54 +++++++++++ frontend/src/utils/sidebarObjectVisibility.ts | 76 ++++++++++++++++ shared/i18n/de-DE.json | 4 + shared/i18n/en-US.json | 4 + shared/i18n/ja-JP.json | 4 + shared/i18n/ru-RU.json | 4 + shared/i18n/zh-CN.json | 4 + shared/i18n/zh-TW.json | 4 + 14 files changed, 323 insertions(+), 4 deletions(-) create mode 100644 frontend/src/utils/sidebarObjectVisibility.test.ts create mode 100644 frontend/src/utils/sidebarObjectVisibility.ts diff --git a/frontend/src/App.settings-center.test.ts b/frontend/src/App.settings-center.test.ts index b8b126db..8199fc74 100644 --- a/frontend/src/App.settings-center.test.ts +++ b/frontend/src/App.settings-center.test.ts @@ -15,7 +15,7 @@ const aiSettingsModalSource = readFileSync( describe('settings center layout', () => { it('uses the same split navigation shell as the tool center', () => { expect(appSource).toContain("type SettingsCenterGroupKey = 'preferences' | 'services' | 'about';"); - expect(appSource).toContain("type SettingsCenterPaneKey = 'language' | 'theme' | 'sidebar-metadata' | 'proxy' | 'web-auth' | 'ai' | 'about-go-navi';"); + expect(appSource).toContain("type SettingsCenterPaneKey = 'language' | 'theme' | 'sidebar-metadata' | 'sidebar-objects' | 'proxy' | 'web-auth' | 'ai' | 'about-go-navi';"); expect(appSource).toContain("const [activeSettingsCenterGroupKey, setActiveSettingsCenterGroupKey] = useState('preferences');"); expect(appSource).toContain("const [activeSettingsCenterPane, setActiveSettingsCenterPane] = useState(null);"); expect(appSource).toContain('style={toolCenterModalWorkspaceStyle}'); @@ -47,6 +47,17 @@ describe('settings center layout', () => { expect(appSource).not.toContain("setIsLanguageModalOpen(true)"); }); + it('adds persistent sidebar object visibility controls to preferences', () => { + expect(appSource).toContain("key: 'sidebar-objects'"); + expect(appSource).toContain("title: t('app.settings.sidebar_objects.title')"); + expect(appSource).toContain("description: t('app.settings.sidebar_objects.description')"); + expect(appSource).toContain("handleOpenSettingsCenterPane('preferences', 'sidebar-objects')"); + expect(appSource).toContain("if (activeSettingsCenterPane.key === 'sidebar-objects')"); + expect(appSource).toContain('renderSidebarObjectVisibilitySettingsPane();'); + expect(appSource).toContain('sidebarHiddenObjectGroups'); + expect(appSource).toContain('SIDEBAR_OBJECT_GROUP_KEYS.filter((key) => key !== \'tables\')'); + }); + it('adds browser auth management into the services settings group', () => { expect(appSource).toContain("key: 'web-auth' as const"); expect(appSource).toContain("title: t('app.settings.entry.web_auth.title')"); diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 6deb2519..1b34971d 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -105,6 +105,10 @@ import { setSidebarTableMetadataFieldSelected, type SidebarTableMetadataField, } from './utils/sidebarTableMetadata'; +import { + SIDEBAR_OBJECT_GROUP_KEYS, + type SidebarObjectGroupKey, +} from './utils/sidebarObjectVisibility'; import { getSecurityUpdateStatusMeta, resolveSecurityUpdateEntryVisibility, @@ -465,7 +469,7 @@ type ToolCenterPaneState = { }; type SettingsCenterGroupKey = 'preferences' | 'services' | 'about'; -type SettingsCenterPaneKey = 'language' | 'theme' | 'sidebar-metadata' | 'proxy' | 'web-auth' | 'ai' | 'about-go-navi'; +type SettingsCenterPaneKey = 'language' | 'theme' | 'sidebar-metadata' | 'sidebar-objects' | 'proxy' | 'web-auth' | 'ai' | 'about-go-navi'; type SettingsCenterPaneState = { key: SettingsCenterPaneKey; group: SettingsCenterGroupKey; @@ -4415,6 +4419,81 @@ function App() { utilityMutedTextStyle, utilityPanelStyle, ]); + const renderSidebarObjectVisibilitySettingsPane = useCallback(() => { + const hiddenObjectGroups = new Set(appearance.sidebarHiddenObjectGroups); + const objectGroupItems: Array<{ key: SidebarObjectGroupKey; label: string }> = [ + { key: 'savedQueries', label: t('sidebar.tree.saved_queries') }, + { key: 'tables', label: t('sidebar.object_group.tables') }, + { key: 'views', label: t('sidebar.object_group.views') }, + { key: 'materializedViews', label: t('sidebar.object_group.materialized_views') }, + { key: 'routines', label: t('sidebar.object_group.routines') }, + { key: 'triggers', label: t('sidebar.object_group.triggers') }, + { key: 'events', label: t('sidebar.object_group.events') }, + { key: 'sequences', label: t('sidebar.object_group.sequences') }, + { key: 'packages', label: t('sidebar.object_group.packages') }, + ]; + const setObjectGroupVisible = (key: SidebarObjectGroupKey, visible: boolean) => { + const nextHiddenObjectGroups = visible + ? appearance.sidebarHiddenObjectGroups.filter((item) => item !== key) + : Array.from(new Set([...appearance.sidebarHiddenObjectGroups, key])); + setAppearance({ sidebarHiddenObjectGroups: nextHiddenObjectGroups }); + }; + + return ( +
+
+
{t('app.settings.sidebar_objects.title')}
+
+ {t('app.settings.sidebar_objects.description')} +
+
+ {objectGroupItems.map((item) => ( +
+ {item.label} + setObjectGroupVisible(item.key, visible)} + /> +
+ ))} +
+
+ + +
+
+
+ ); + }, [ + appearance.sidebarHiddenObjectGroups, + overlayTheme.divider, + setAppearance, + t, + utilityMutedTextStyle, + utilityPanelStyle, + ]); const updateInstallActionLabel = updateInstallAction === 'install-and-restart' ? t('app.about.action.install_and_restart') : (updateInstallAction === 'launch-installer' @@ -6431,6 +6510,13 @@ function App() { description: t('app.settings.sidebar_metadata.description'), onClick: () => handleOpenSettingsCenterPane('preferences', 'sidebar-metadata'), }, + { + key: 'sidebar-objects', + icon: , + title: t('app.settings.sidebar_objects.title'), + description: t('app.settings.sidebar_objects.description'), + onClick: () => handleOpenSettingsCenterPane('preferences', 'sidebar-objects'), + }, ], }, { @@ -6524,6 +6610,9 @@ function App() { if (activeSettingsCenterPane.key === 'sidebar-metadata') { return renderSidebarMetadataSettingsPane(); } + if (activeSettingsCenterPane.key === 'sidebar-objects') { + return renderSidebarObjectVisibilitySettingsPane(); + } if (activeSettingsCenterPane.key === 'proxy') { return renderProxySettingsContent(); } diff --git a/frontend/src/components/Sidebar.tsx b/frontend/src/components/Sidebar.tsx index f6975f94..ed975c36 100644 --- a/frontend/src/components/Sidebar.tsx +++ b/frontend/src/components/Sidebar.tsx @@ -160,6 +160,7 @@ import { useExportProgressDialog } from './ExportProgressModal'; import { getShortcutPlatform, resolveShortcutDisplay } from '../utils/shortcuts'; import { buildExternalSQLRootNode, type ExternalSQLTreeNode } from '../utils/externalSqlTree'; import { resolveSidebarTableMetadataFields } from '../utils/sidebarTableMetadata'; +import { filterSidebarTreeByHiddenObjectGroups } from '../utils/sidebarObjectVisibility'; import { t } from '../i18n'; import MessagePublishModal from './MessagePublishModal'; import { @@ -687,6 +688,12 @@ const Sidebar: React.FC<{ const allSavedQueriesNode = useMemo(() => { return buildAllSavedQueriesTreeNode(savedQueries, connections, savedQueryGroups); }, [connections, savedQueries, savedQueryGroups]); + const sidebarHiddenObjectGroups = appearance.sidebarHiddenObjectGroups; + const visibleSidebarTreeData = useMemo( + () => filterSidebarTreeByHiddenObjectGroups(treeData, sidebarHiddenObjectGroups), + [sidebarHiddenObjectGroups, treeData], + ); + const sidebarObjectVisibilitySignature = sidebarHiddenObjectGroups.join('|') || 'all'; const snapshotTreeSelectionBeforeDrag = useCallback(() => { treeDragSelectionSnapshotRef.current = { selectedKeys: [...selectedKeys], @@ -2484,7 +2491,7 @@ const Sidebar: React.FC<{ setV2CommandActiveIndex, v2ExplorerFilter, sidebarTableMetadataFields, - treeData, + treeData: visibleSidebarTreeData, treeViewportWidth, treeHeight, isV2Ui, @@ -3267,7 +3274,7 @@ const Sidebar: React.FC<{ >
{ it('localizes database object group titles and default schema fallback', () => { [ @@ -56,4 +65,16 @@ describe('Sidebar object group i18n', () => { }); }); }); + + it('localizes the persistent object visibility settings', () => { + visibilityKeys.forEach((key) => { + expect(appSource).toContain(`t('${key}'`); + }); + locales.forEach((locale) => { + const catalog = JSON.parse(readFileSync(new URL(`../../../shared/i18n/${locale}.json`, import.meta.url), 'utf8')) as Record; + visibilityKeys.forEach((key) => { + expect(catalog[key], `${locale}:${key}`).toBeTruthy(); + }); + }); + }); }); diff --git a/frontend/src/store.test.ts b/frontend/src/store.test.ts index 806a6cd1..c861d168 100644 --- a/frontend/src/store.test.ts +++ b/frontend/src/store.test.ts @@ -75,6 +75,7 @@ describe('store appearance persistence', () => { expect(appearance.v2CommandSearchPersistentFilterEnabled).toBe(false); expect(appearance.v2SidebarPersistedFilter).toBe(''); expect(appearance.v2SidebarRailScale).toBe(1); + expect(appearance.sidebarHiddenObjectGroups).toEqual([]); expect(appearance.showDataTableVerticalBorders).toBe(false); expect(appearance.showDataTableRowNumber).toBe(true); expect(appearance.dataTableDensity).toBe('comfortable'); @@ -153,6 +154,33 @@ describe('store appearance persistence', () => { expect(appearance.v2SidebarRailScale).toBe(1.55); }); + it('persists and sanitizes hidden sidebar object groups', async () => { + const { useStore } = await importStore(); + + useStore.getState().setAppearance({ + sidebarHiddenObjectGroups: ['views', 'routines', 'views'], + }); + + const persisted = JSON.parse(storage.getItem('lite-db-storage') || '{}'); + expect(persisted.state.appearance.sidebarHiddenObjectGroups).toEqual(['views', 'routines']); + + vi.resetModules(); + const reloaded = await importStore(); + expect(reloaded.useStore.getState().appearance.sidebarHiddenObjectGroups).toEqual(['views', 'routines']); + + storage.setItem('lite-db-storage', JSON.stringify({ + state: { + appearance: { + sidebarHiddenObjectGroups: ['tables', 'unknown', 'tables', 1], + }, + }, + version: 16, + })); + vi.resetModules(); + const sanitized = await importStore(); + expect(sanitized.useStore.getState().appearance.sidebarHiddenObjectGroups).toEqual(['tables']); + }); + it('migrates legacy sidebar table comment settings into metadata fields and persists explicit selections', async () => { storage.setItem('lite-db-storage', JSON.stringify({ state: { diff --git a/frontend/src/store.ts b/frontend/src/store.ts index fa648ec5..4dea7bf0 100644 --- a/frontend/src/store.ts +++ b/frontend/src/store.ts @@ -115,6 +115,10 @@ import { sanitizeSidebarTableMetadataFields, type SidebarTableMetadataField, } from "./utils/sidebarTableMetadata"; +import { + sanitizeSidebarHiddenObjectGroups, + type SidebarObjectGroupKey, +} from "./utils/sidebarObjectVisibility"; export type TableDoubleClickAction = "open-data" | "open-design"; export type ThemeMode = "light" | "dark"; @@ -133,6 +137,7 @@ export interface AppearanceSettings extends DataGridDisplaySettings { v2CommandSearchPersistentFilterEnabled: boolean; v2SidebarPersistedFilter: string; v2SidebarRailScale: number; + sidebarHiddenObjectGroups: SidebarObjectGroupKey[]; customUIFontFamily: string | null; customMonoFontFamily: string | null; newQuerySqlTemplate: string | null; @@ -155,6 +160,7 @@ export const DEFAULT_APPEARANCE: AppearanceSettings = { v2CommandSearchPersistentFilterEnabled: false, v2SidebarPersistedFilter: "", v2SidebarRailScale: DEFAULT_V2_SIDEBAR_RAIL_SCALE, + sidebarHiddenObjectGroups: [], customUIFontFamily: null, customMonoFontFamily: null, newQuerySqlTemplate: null, @@ -3070,6 +3076,9 @@ const sanitizeAppearance = ( v2SidebarRailScale: sanitizeV2SidebarRailScale( appearance.v2SidebarRailScale, ), + sidebarHiddenObjectGroups: sanitizeSidebarHiddenObjectGroups( + appearance.sidebarHiddenObjectGroups, + ), customUIFontFamily: sanitizeFontFamilyInput(appearance.customUIFontFamily), customMonoFontFamily: sanitizeFontFamilyInput(appearance.customMonoFontFamily), newQuerySqlTemplate: sanitizeNewQuerySqlTemplate(appearance.newQuerySqlTemplate), diff --git a/frontend/src/utils/sidebarObjectVisibility.test.ts b/frontend/src/utils/sidebarObjectVisibility.test.ts new file mode 100644 index 00000000..4feaebbc --- /dev/null +++ b/frontend/src/utils/sidebarObjectVisibility.test.ts @@ -0,0 +1,54 @@ +import { describe, expect, it } from 'vitest'; + +import { + filterSidebarTreeByHiddenObjectGroups, + sanitizeSidebarHiddenObjectGroups, +} from './sidebarObjectVisibility'; + +describe('sidebar object visibility', () => { + it('keeps only enabled object categories while preserving the source tree', () => { + const tree = [{ + key: 'db', + type: 'database', + children: [ + { key: 'db-queries', type: 'queries-folder', children: [{ key: 'query-1', type: 'saved-query' }] }, + { key: 'db-tables', type: 'object-group', dataRef: { groupKey: 'tables' }, children: [{ key: 'orders', type: 'table' }] }, + { key: 'db-views', type: 'object-group', dataRef: { groupKey: 'views' } }, + { + key: 'db-schema-dbo', + type: 'object-group', + dataRef: { groupKey: 'schema' }, + children: [ + { key: 'dbo-tables', type: 'object-group', dataRef: { groupKey: 'tables' }, children: [{ key: 'customers', type: 'table' }] }, + { key: 'dbo-events', type: 'object-group', dataRef: { groupKey: 'events' } }, + ], + }, + ], + }]; + + const filtered = filterSidebarTreeByHiddenObjectGroups(tree, [ + 'savedQueries', + 'views', + 'events', + ]); + + expect(filtered[0].children?.map((node) => node.key)).toEqual(['db-tables', 'db-schema-dbo']); + expect(filtered[0].children?.[1].children?.map((node) => node.key)).toEqual(['dbo-tables']); + expect(tree[0].children?.map((node) => node.key)).toEqual([ + 'db-queries', + 'db-tables', + 'db-views', + 'db-schema-dbo', + ]); + }); + + it('drops invalid and duplicate persisted object group keys', () => { + expect(sanitizeSidebarHiddenObjectGroups([ + 'views', + 'views', + 'unknown', + 3, + ' tables ', + ])).toEqual(['views', 'tables']); + }); +}); diff --git a/frontend/src/utils/sidebarObjectVisibility.ts b/frontend/src/utils/sidebarObjectVisibility.ts new file mode 100644 index 00000000..e62f5232 --- /dev/null +++ b/frontend/src/utils/sidebarObjectVisibility.ts @@ -0,0 +1,76 @@ +export const SIDEBAR_OBJECT_GROUP_KEYS = [ + 'savedQueries', + 'tables', + 'views', + 'materializedViews', + 'sequences', + 'routines', + 'packages', + 'triggers', + 'events', +] as const; + +export type SidebarObjectGroupKey = (typeof SIDEBAR_OBJECT_GROUP_KEYS)[number]; + +type SidebarObjectVisibilityTreeNode = { + type?: string; + dataRef?: { groupKey?: unknown }; + children?: SidebarObjectVisibilityTreeNode[]; + isLeaf?: boolean; +}; + +const SIDEBAR_OBJECT_GROUP_KEY_SET = new Set(SIDEBAR_OBJECT_GROUP_KEYS); + +export const sanitizeSidebarHiddenObjectGroups = (value: unknown): SidebarObjectGroupKey[] => { + if (!Array.isArray(value)) return []; + const seen = new Set(); + value.forEach((item) => { + if (typeof item !== 'string') return; + const key = item.trim(); + if (SIDEBAR_OBJECT_GROUP_KEY_SET.has(key)) { + seen.add(key as SidebarObjectGroupKey); + } + }); + return Array.from(seen); +}; + +const resolveObjectGroupKey = ( + node: SidebarObjectVisibilityTreeNode, +): SidebarObjectGroupKey | null => { + if (node.type === 'queries-folder' || node.type === 'all-saved-queries') { + return 'savedQueries'; + } + if (node.type !== 'object-group') return null; + const groupKey = String(node.dataRef?.groupKey || '').trim(); + return SIDEBAR_OBJECT_GROUP_KEY_SET.has(groupKey) + ? groupKey as SidebarObjectGroupKey + : null; +}; + +const isSchemaGroupNode = (node: SidebarObjectVisibilityTreeNode): boolean => ( + node.type === 'object-group' && node.dataRef?.groupKey === 'schema' +); + +export const filterSidebarTreeByHiddenObjectGroups = ( + nodes: T[], + hiddenObjectGroups: readonly SidebarObjectGroupKey[], +): T[] => { + if (hiddenObjectGroups.length === 0) return nodes; + const hidden = new Set(hiddenObjectGroups); + + return nodes.flatMap((node): T[] => { + const objectGroupKey = resolveObjectGroupKey(node); + if (objectGroupKey && hidden.has(objectGroupKey)) return []; + + if (!node.children || node.children.length === 0) return [node]; + const children = filterSidebarTreeByHiddenObjectGroups(node.children as T[], hiddenObjectGroups); + if (isSchemaGroupNode(node) && children.length === 0) return []; + if (children.length === node.children.length) return [node]; + + return [{ + ...node, + children, + ...(children.length === 0 ? { isLeaf: true } : {}), + }]; + }); +}; diff --git a/shared/i18n/de-DE.json b/shared/i18n/de-DE.json index e6543bae..a219b09a 100644 --- a/shared/i18n/de-DE.json +++ b/shared/i18n/de-DE.json @@ -2673,6 +2673,10 @@ "app.settings.group.services.title": "Dienste", "app.settings.sidebar_metadata.description": "Festlegen, welche Tabellenmetadaten neben Tabellennamen in der linken Sidebar angezeigt werden.", "app.settings.sidebar_metadata.title": "Sidebar-Tabellenmetadaten", + "app.settings.sidebar_objects.action.show_all": "Alle anzeigen", + "app.settings.sidebar_objects.action.tables_only": "Nur Tabellen anzeigen", + "app.settings.sidebar_objects.description": "Wählen Sie die Objektkategorien aus, die im linken Datenbankbaum angezeigt werden. Änderungen gelten sofort für alle Verbindungen.", + "app.settings.sidebar_objects.title": "Sichtbare Sidebar-Objekte", "app.settings.title": "Einstellungscenter", "app.settings.web_auth.description": "Hier sehen Sie den aktuellen Status der Browserzugriffs-Authentifizierung, die Sitzungsrichtlinie und den 2FA-Status. Nach der Anmeldung können Sie auch das Administratorpasswort ändern.", "app.settings.web_auth.load_failed": "Browserzugriffs-Authentifizierungseinstellungen konnten nicht geladen werden", diff --git a/shared/i18n/en-US.json b/shared/i18n/en-US.json index d011f69c..3b788f41 100644 --- a/shared/i18n/en-US.json +++ b/shared/i18n/en-US.json @@ -2673,6 +2673,10 @@ "app.settings.group.services.title": "Services", "app.settings.sidebar_metadata.description": "Choose which table metadata appears beside table names in the left sidebar.", "app.settings.sidebar_metadata.title": "Sidebar Table Metadata", + "app.settings.sidebar_objects.action.show_all": "Show all", + "app.settings.sidebar_objects.action.tables_only": "Show tables only", + "app.settings.sidebar_objects.description": "Choose which object categories appear in the left database tree. Changes apply immediately to all connections.", + "app.settings.sidebar_objects.title": "Sidebar Object Visibility", "app.settings.title": "Settings Center", "app.settings.web_auth.description": "View the current browser access authentication status, session policy, and 2FA state. You can also change the admin password after signing in.", "app.settings.web_auth.load_failed": "Failed to load browser access authentication settings", diff --git a/shared/i18n/ja-JP.json b/shared/i18n/ja-JP.json index 45698af7..7680d868 100644 --- a/shared/i18n/ja-JP.json +++ b/shared/i18n/ja-JP.json @@ -2673,6 +2673,10 @@ "app.settings.group.services.title": "サービス", "app.settings.sidebar_metadata.description": "左サイドバーのテーブル名の横に表示するメタデータを選択します。", "app.settings.sidebar_metadata.title": "サイドバーテーブルメタデータ", + "app.settings.sidebar_objects.action.show_all": "すべて表示", + "app.settings.sidebar_objects.action.tables_only": "テーブルのみ表示", + "app.settings.sidebar_objects.description": "左側のデータベースツリーに表示するオブジェクトカテゴリを選択します。変更はすべての接続にすぐ適用されます。", + "app.settings.sidebar_objects.title": "サイドバーのオブジェクト表示", "app.settings.title": "設定センター", "app.settings.web_auth.description": "現在のブラウザアクセス認証状態、セッションポリシー、2FA の有効状態を確認できます。サインイン後に管理者パスワードも変更できます。", "app.settings.web_auth.load_failed": "ブラウザアクセス認証設定の読み込みに失敗しました", diff --git a/shared/i18n/ru-RU.json b/shared/i18n/ru-RU.json index 7459097f..5beb1a94 100644 --- a/shared/i18n/ru-RU.json +++ b/shared/i18n/ru-RU.json @@ -2673,6 +2673,10 @@ "app.settings.group.services.title": "Сервисы", "app.settings.sidebar_metadata.description": "Выберите, какие метаданные таблиц показывать рядом с именами таблиц в левом дереве.", "app.settings.sidebar_metadata.title": "Метаданные таблиц в боковой панели", + "app.settings.sidebar_objects.action.show_all": "Показать все", + "app.settings.sidebar_objects.action.tables_only": "Показывать только таблицы", + "app.settings.sidebar_objects.description": "Выберите категории объектов, отображаемые в левом дереве базы данных. Изменения сразу применяются ко всем подключениям.", + "app.settings.sidebar_objects.title": "Отображение объектов боковой панели", "app.settings.title": "Центр настроек", "app.settings.web_auth.description": "Здесь можно посмотреть текущее состояние аутентификации браузерного доступа, политику сеанса и статус 2FA. После входа здесь же можно сменить пароль администратора.", "app.settings.web_auth.load_failed": "Не удалось загрузить настройки аутентификации браузерного доступа", diff --git a/shared/i18n/zh-CN.json b/shared/i18n/zh-CN.json index eebacf06..a5215d5c 100644 --- a/shared/i18n/zh-CN.json +++ b/shared/i18n/zh-CN.json @@ -2673,6 +2673,10 @@ "app.settings.group.services.title": "服务配置", "app.settings.sidebar_metadata.description": "选择左侧树中表名后需要展示哪些元数据。", "app.settings.sidebar_metadata.title": "侧栏表元数据", + "app.settings.sidebar_objects.action.show_all": "显示全部", + "app.settings.sidebar_objects.action.tables_only": "仅显示表", + "app.settings.sidebar_objects.description": "选择左侧数据库树中需要显示的对象分类,设置会立即应用到所有连接。", + "app.settings.sidebar_objects.title": "侧栏对象显示", "app.settings.title": "设置中心", "app.settings.web_auth.description": "这里可以查看当前浏览器访问认证状态、会话策略和 2FA 启用情况,也可以在登录后修改管理员密码。", "app.settings.web_auth.load_failed": "读取浏览器访问认证设置失败", diff --git a/shared/i18n/zh-TW.json b/shared/i18n/zh-TW.json index 2a2bf929..5e0d60b6 100644 --- a/shared/i18n/zh-TW.json +++ b/shared/i18n/zh-TW.json @@ -2673,6 +2673,10 @@ "app.settings.group.services.title": "服務設定", "app.settings.sidebar_metadata.description": "選擇左側樹中表名後要顯示哪些中介資料。", "app.settings.sidebar_metadata.title": "側欄表格中介資料", + "app.settings.sidebar_objects.action.show_all": "顯示全部", + "app.settings.sidebar_objects.action.tables_only": "僅顯示表格", + "app.settings.sidebar_objects.description": "選擇左側資料庫樹中要顯示的物件分類,設定會立即套用至所有連線。", + "app.settings.sidebar_objects.title": "側欄物件顯示", "app.settings.title": "設定中心", "app.settings.web_auth.description": "這裡可以檢視目前瀏覽器存取驗證狀態、工作階段策略和 2FA 啟用情況,也可以在登入後修改管理員密碼。", "app.settings.web_auth.load_failed": "讀取瀏覽器存取驗證設定失敗",