From 2d9d5f0e9823bdb1449a9766becc4c54107677f4 Mon Sep 17 00:00:00 2001 From: Syngnat Date: Sun, 10 May 2026 20:55:16 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat(data-grid):=20=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E5=8F=B3=E9=94=AE=E5=A4=8D=E5=88=B6=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E5=90=8D=E7=A7=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增单元格右键菜单“复制字段名称” - 将表格复制成功提示改为中文 - 补充字段名称解析回归测试 --- .../src/components/DataGrid.layout.test.tsx | 7 ++++- frontend/src/components/DataGrid.tsx | 30 ++++++++++++++++++- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/DataGrid.layout.test.tsx b/frontend/src/components/DataGrid.layout.test.tsx index 7f3d57c..853638f 100644 --- a/frontend/src/components/DataGrid.layout.test.tsx +++ b/frontend/src/components/DataGrid.layout.test.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { renderToStaticMarkup } from 'react-dom/server'; import { describe, expect, it, vi } from 'vitest'; -import DataGrid, { formatCellDisplayText } from './DataGrid'; +import DataGrid, { formatCellDisplayText, resolveContextMenuFieldName } from './DataGrid'; vi.mock('../store', () => ({ useStore: (selector: (state: any) => any) => selector({ @@ -87,6 +87,11 @@ describe('DataGrid layout', () => { expect(formatCellDisplayText('2026-05-10T09:12:33.456+08:00')).toBe('2026-05-10 09:12:33.456'); }); + it('resolves the field name copied from the cell context menu', () => { + expect(resolveContextMenuFieldName('created_at', '创建时间')).toBe('created_at'); + expect(resolveContextMenuFieldName('', 'fallback_name')).toBe('fallback_name'); + }); + it('renders a DDL action for table data pages only', () => { const tableMarkup = renderToStaticMarkup( { + const name = String(dataIndex || title || '').trim(); + return name; +}; const trimSimpleCache = (cache: Map, limit: number) => { if (cache.size < limit) return; @@ -4274,9 +4278,19 @@ const DataGrid: React.FC = ({ const copyToClipboard = useCallback((text: string) => { navigator.clipboard.writeText(text).catch(console.error); - void message.success("Copied to clipboard"); + void message.success("已复制到剪贴板"); }, []); + const handleCopyContextMenuFieldName = useCallback(() => { + const fieldName = resolveContextMenuFieldName(cellContextMenu.dataIndex, cellContextMenu.title); + if (!fieldName) { + void message.info('未识别到字段名称'); + return; + } + copyToClipboard(fieldName); + setCellContextMenu(prev => ({ ...prev, visible: false })); + }, [cellContextMenu.dataIndex, cellContextMenu.title, copyToClipboard]); + const getClipboardRows = useCallback(() => ( pickRowsForClipboard({ rows: mergedDisplayData as Array>, @@ -6534,6 +6548,20 @@ const DataGrid: React.FC = ({ }} onClick={(e) => e.stopPropagation()} > +
e.currentTarget.style.background = darkMode ? '#303030' : '#f5f5f5'} + onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'} + onClick={handleCopyContextMenuFieldName} + > + + 复制字段名称 +
+
{canModifyData && ( <>