mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-05-21 08:10:29 +08:00
✨ feat(data-grid): 支持右键复制字段名称
- 新增单元格右键菜单“复制字段名称” - 将表格复制成功提示改为中文 - 补充字段名称解析回归测试
This commit is contained in:
@@ -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(
|
||||
<DataGrid
|
||||
|
||||
@@ -163,6 +163,10 @@ const splitCellKey = (cellKey: string): { rowKey: string; colName: string } | nu
|
||||
colName: cellKey.slice(sepIndex + CELL_KEY_SEP.length),
|
||||
};
|
||||
};
|
||||
export const resolveContextMenuFieldName = (dataIndex: string, title?: string): string => {
|
||||
const name = String(dataIndex || title || '').trim();
|
||||
return name;
|
||||
};
|
||||
|
||||
const trimSimpleCache = (cache: Map<string, string>, limit: number) => {
|
||||
if (cache.size < limit) return;
|
||||
@@ -4274,9 +4278,19 @@ const DataGrid: React.FC<DataGridProps> = ({
|
||||
|
||||
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<Record<string, unknown>>,
|
||||
@@ -6534,6 +6548,20 @@ const DataGrid: React.FC<DataGridProps> = ({
|
||||
}}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
padding: '8px 12px',
|
||||
cursor: 'pointer',
|
||||
transition: 'background 0.2s',
|
||||
}}
|
||||
onMouseEnter={(e) => e.currentTarget.style.background = darkMode ? '#303030' : '#f5f5f5'}
|
||||
onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}
|
||||
onClick={handleCopyContextMenuFieldName}
|
||||
>
|
||||
<CopyOutlined style={{ marginRight: 8 }} />
|
||||
复制字段名称
|
||||
</div>
|
||||
<div style={{ height: 1, background: darkMode ? '#303030' : '#f0f0f0', margin: '4px 0' }} />
|
||||
{canModifyData && (
|
||||
<>
|
||||
<div
|
||||
|
||||
Reference in New Issue
Block a user