From cbca312a5030f1fa1b7e817c0cc7cfba0dc353d2 Mon Sep 17 00:00:00 2001 From: Syngnat Date: Fri, 24 Jul 2026 20:20:23 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20fix(sidebar):=20=E5=B0=86?= =?UTF-8?q?=E8=A1=A8=E7=BD=AE=E9=A1=B6=E6=98=9F=E6=A0=87=E6=94=B9=E4=B8=BA?= =?UTF-8?q?=E5=8F=AA=E8=AF=BB=E7=8A=B6=E6=80=81=E6=8C=87=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 仅为已置顶表展示非交互实心星标 - 保留右键菜单中的置顶与取消置顶入口 - 补充侧边栏置顶指示器回归测试 --- .../Sidebar.locate-toolbar.test.tsx | 75 ++++++++++++------- frontend/src/components/Sidebar.tsx | 4 - .../components/sidebar/SidebarTreeTitle.tsx | 41 +++------- .../sidebar/useSidebarV2ActionHandlers.tsx | 1 - frontend/src/v2-theme.css | 25 +------ 5 files changed, 63 insertions(+), 83 deletions(-) diff --git a/frontend/src/components/Sidebar.locate-toolbar.test.tsx b/frontend/src/components/Sidebar.locate-toolbar.test.tsx index f3adcab1..0b7220e5 100644 --- a/frontend/src/components/Sidebar.locate-toolbar.test.tsx +++ b/frontend/src/components/Sidebar.locate-toolbar.test.tsx @@ -2292,17 +2292,45 @@ describe('Sidebar locate toolbar', () => { }).map((entry) => entry.tableName)).toEqual(['orders', 'users', 'audit']); }); - it('keeps the v2 table pin action on sidebar table rows', () => { - const source = readSidebarSource(); + it('renders a non-interactive pin indicator only for pinned v2 sidebar tables', () => { + const source = readSourceFile('./sidebar/SidebarTreeTitle.tsx'); const css = readV2ThemeCss(); + const baseOptions = { + hoverTitle: 'orders', + statusBadge: null, + getV2TreeMetaText: () => '', + sidebarTableMetadataFields: [], + snapshotTreeSelectionBeforeDrag: vi.fn(), + restoreTreeSelectionAfterDrag: vi.fn(), + treeDragSelectSuppressUntilRef: { current: 0 }, + setIsTreeDragging: vi.fn(), + }; + const renderTableTitle = (pinnedSidebarTable: boolean) => renderToStaticMarkup(renderSidebarV2TreeTitle({ + ...baseOptions, + node: { + type: 'table', + title: 'orders', + key: 'conn-main-orders', + dataRef: { + id: 'conn', + dbName: 'main', + tableName: 'orders', + pinnedSidebarTable, + }, + }, + })); - expect(source).toContain('data-v2-sidebar-table-pin-action="true"'); - expect(source).toContain('node?.dataRef?.pinnedSidebarTable ? : '); - expect(source).toContain('toggleSidebarTablePinned(node);'); - expect(source).toContain("message.success(shouldPin ? t('sidebar.message.table_pinned') : t('sidebar.message.table_unpinned'));"); - expect(css).toMatch(/\.gn-v2-table-pin-action \{[^}]*opacity: 0;/s); - expect(css).toMatch(/\.gn-v2-table-pin-action\.is-pinned \{[^}]*color: #f59e0b;[^}]*opacity: 1;/s); - expect(css).toMatch(/\.ant-tree-node-content-wrapper:hover \.gn-v2-table-pin-action,/s); + const unpinnedMarkup = renderTableTitle(false); + const pinnedMarkup = renderTableTitle(true); + expect(unpinnedMarkup).not.toContain('data-v2-sidebar-table-pin-indicator'); + expect(pinnedMarkup).toContain('data-v2-sidebar-table-pin-indicator="true"'); + expect(pinnedMarkup).toContain(`aria-label="${t('sidebar.status.pinned')}"`); + expect(pinnedMarkup).not.toContain(' { @@ -2887,23 +2915,19 @@ describe('Sidebar locate toolbar', () => { expect(source).toContain("t('connection.sidebar.delete.failureFallback')"); }); - it('localizes the sidebar table pin action title and aria-label via i18n keys', () => { - const source = readSidebarSource(); - const tablePinActionStart = source.indexOf("const tablePinAction = node.type === 'table' ? ("); - const tablePinActionEnd = source.indexOf('aria-pressed=', tablePinActionStart); - const tablePinActionSource = source.slice(tablePinActionStart, tablePinActionEnd); - const normalizedTablePinActionSource = tablePinActionSource.replace(/\s+/g, ' '); + it('localizes the sidebar table pin indicator via the pinned status key', () => { + const source = readSourceFile('./sidebar/SidebarTreeTitle.tsx'); + const tablePinIndicatorStart = source.indexOf("const tablePinIndicator = node.type === 'table'"); + const tablePinIndicatorEnd = source.indexOf('', tablePinIndicatorStart); + const tablePinIndicatorSource = source.slice(tablePinIndicatorStart, tablePinIndicatorEnd); + const normalizedTablePinIndicatorSource = tablePinIndicatorSource.replace(/\s+/g, ' '); - expect(tablePinActionStart).toBeGreaterThanOrEqual(0); - expect(tablePinActionEnd).toBeGreaterThan(tablePinActionStart); - expect(normalizedTablePinActionSource).toContain( - "title={node?.dataRef?.pinnedSidebarTable ? t('sidebar.action.unpin_table') : t('sidebar.action.pin_table')}", - ); - expect(normalizedTablePinActionSource).toContain( - "aria-label={node?.dataRef?.pinnedSidebarTable ? t('sidebar.action.unpin_table') : t('sidebar.action.pin_table')}", - ); - expect(tablePinActionSource).not.toContain("'取消置顶表'"); - expect(tablePinActionSource).not.toContain("'置顶表'"); + expect(tablePinIndicatorStart).toBeGreaterThanOrEqual(0); + expect(tablePinIndicatorEnd).toBeGreaterThan(tablePinIndicatorStart); + expect(normalizedTablePinIndicatorSource).toContain("title={t('sidebar.status.pinned')}"); + expect(normalizedTablePinIndicatorSource).toContain("aria-label={t('sidebar.status.pinned')}"); + expect(tablePinIndicatorSource).not.toContain('sidebar.action.pin_table'); + expect(tablePinIndicatorSource).not.toContain('sidebar.action.unpin_table'); }); it('localizes legacy sidebar connection and redis menu labels', () => { @@ -3324,7 +3348,6 @@ describe('Sidebar locate toolbar', () => { hoverTitle: 'users', statusBadge: null, getV2TreeMetaText: () => '', - toggleSidebarTablePinned: vi.fn(), snapshotTreeSelectionBeforeDrag: vi.fn(), restoreTreeSelectionAfterDrag: vi.fn(), treeDragSelectSuppressUntilRef: { current: 0 }, diff --git a/frontend/src/components/Sidebar.tsx b/frontend/src/components/Sidebar.tsx index 486329ce..145da1b7 100644 --- a/frontend/src/components/Sidebar.tsx +++ b/frontend/src/components/Sidebar.tsx @@ -2388,7 +2388,6 @@ const Sidebar: React.FC<{ const { getConnectionNodeForAction, - toggleSidebarTablePinned, handleV2TableContextMenuAction, handleTableGroupSortAction, handleV2TableGroupContextMenuAction, @@ -2577,8 +2576,6 @@ const Sidebar: React.FC<{ refreshV2TableContextMenuStatsRef.current = refreshV2TableContextMenuStats; const getV2TreeMetaTextRef = useRef(getV2TreeMetaText); getV2TreeMetaTextRef.current = getV2TreeMetaText; - const toggleSidebarTablePinnedRef = useRef(toggleSidebarTablePinned); - toggleSidebarTablePinnedRef.current = toggleSidebarTablePinned; const renderV2TreeTitle = useCallback((node: any, hoverTitle: string, statusBadge: React.ReactNode) => renderSidebarV2TreeTitle({ node, @@ -2586,7 +2583,6 @@ const Sidebar: React.FC<{ statusBadge, getV2TreeMetaText: getV2TreeMetaTextRef.current, sidebarTableMetadataFields, - toggleSidebarTablePinned: toggleSidebarTablePinnedRef.current, snapshotTreeSelectionBeforeDrag, restoreTreeSelectionAfterDrag, treeDragSelectSuppressUntilRef, diff --git a/frontend/src/components/sidebar/SidebarTreeTitle.tsx b/frontend/src/components/sidebar/SidebarTreeTitle.tsx index cd7e6cb9..1888610b 100644 --- a/frontend/src/components/sidebar/SidebarTreeTitle.tsx +++ b/frontend/src/components/sidebar/SidebarTreeTitle.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { Tooltip } from 'antd'; -import { StarFilled, StarOutlined } from '@ant-design/icons'; +import { StarFilled } from '@ant-design/icons'; import { t } from '../../i18n'; import { SIDEBAR_SQL_EDITOR_DRAG_MIME, encodeSidebarSqlEditorDragPayload } from '../../utils/sidebarSqlDrag'; import { @@ -25,7 +25,6 @@ type SidebarV2TreeTitleOptions = { statusBadge: React.ReactNode; getV2TreeMetaText: (node: any) => string; sidebarTableMetadataFields: SidebarTableMetadataField[]; - toggleSidebarTablePinned: (node: any) => void; snapshotTreeSelectionBeforeDrag: () => void; restoreTreeSelectionAfterDrag: () => void; treeDragSelectSuppressUntilRef: React.MutableRefObject; @@ -116,7 +115,6 @@ export const renderSidebarV2TreeTitle = ({ statusBadge, getV2TreeMetaText, sidebarTableMetadataFields, - toggleSidebarTablePinned, snapshotTreeSelectionBeforeDrag, restoreTreeSelectionAfterDrag, treeDragSelectSuppressUntilRef, @@ -178,33 +176,16 @@ export const renderSidebarV2TreeTitle = ({ node.type === 'redis-db' ? 'is-redis-db' : '', node.type === 'table' && node?.dataRef?.pinnedSidebarTable ? 'is-pinned-table' : '', ].filter(Boolean).join(' '); - const tablePinAction = node.type === 'table' ? ( - +