mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-07-13 00:13:33 +08:00
✨ feat(data-grid): 支持表头整列选择
- 单元格编辑模式下点击可写列表头选中整列数据 - 保留排序、筛选、外键跳转和列宽调整交互 - 补充表头整列选择回归测试 Fixes #622
This commit is contained in:
@@ -1036,6 +1036,54 @@ describe('DataGrid DDL interactions', () => {
|
||||
},
|
||||
);
|
||||
|
||||
it('selects every editable cell in a column when its header is clicked in cell edit mode', async () => {
|
||||
messageApi.info.mockResolvedValue(undefined);
|
||||
let renderer: ReactTestRenderer;
|
||||
await act(async () => {
|
||||
renderer = create(
|
||||
<DataGrid
|
||||
data={[
|
||||
{ __gonavi_row_key__: 'row-1', id: 1, name: 'Ada' },
|
||||
{ __gonavi_row_key__: 'row-2', id: 2, name: 'Linus' },
|
||||
]}
|
||||
columnNames={['id', 'name']}
|
||||
loading={false}
|
||||
tableName="users"
|
||||
dbName="main"
|
||||
connectionId="conn-1"
|
||||
pkColumns={['id']}
|
||||
/>,
|
||||
);
|
||||
});
|
||||
await waitForEffects();
|
||||
|
||||
await act(async () => {
|
||||
renderer!.root.findByType(DataGridToolbarFrame).props.onToggleCellEditMode();
|
||||
});
|
||||
await waitForEffects();
|
||||
|
||||
const nameColumn = testRenderState.latestColumns.find((column) => column.key === 'name');
|
||||
expect(nameColumn?.editable).toBe(true);
|
||||
const headerProps = nameColumn.onHeaderCell(nameColumn);
|
||||
const event = {
|
||||
target: { closest: vi.fn(() => null) },
|
||||
currentTarget: { querySelector: vi.fn(() => null) },
|
||||
preventDefault: vi.fn(),
|
||||
stopPropagation: vi.fn(),
|
||||
};
|
||||
|
||||
await act(async () => {
|
||||
headerProps.onClickCapture(event);
|
||||
});
|
||||
|
||||
const toolbar = renderer!.root.findByType(DataGridToolbarFrame);
|
||||
expect(event.preventDefault).toHaveBeenCalledOnce();
|
||||
expect(event.stopPropagation).toHaveBeenCalledOnce();
|
||||
expect(toolbar.props.cellEditMode).toBe(true);
|
||||
expect(toolbar.props.selectedCellsSize).toBe(2);
|
||||
renderer!.unmount();
|
||||
});
|
||||
|
||||
it('opens the v2 column header context menu from table headers', async () => {
|
||||
setCurrentLanguage('en-US');
|
||||
storeState.appearance.uiVersion = 'v2';
|
||||
|
||||
@@ -1599,6 +1599,27 @@ const DataGrid: React.FC<DataGridProps> = ({
|
||||
resetCellSelection();
|
||||
}, [resetCellSelection]);
|
||||
|
||||
const selectEditableColumnCells = useCallback((columnName: string) => {
|
||||
if (
|
||||
!cellEditModeRef.current
|
||||
|| !canModifyData
|
||||
|| !isWritableResultColumn(columnName, effectiveEditLocator)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
resetCellSelection(false);
|
||||
const nextSelection = new Set<string>();
|
||||
displayDataRef.current.forEach((row) => {
|
||||
const rowKey = row?.[GONAVI_ROW_KEY];
|
||||
if (rowKey === undefined || rowKey === null) return;
|
||||
nextSelection.add(makeCellKey(rowKeyStr(rowKey), columnName));
|
||||
});
|
||||
currentSelectionRef.current = nextSelection;
|
||||
setSelectedCells(nextSelection);
|
||||
updateCellSelection(nextSelection);
|
||||
}, [canModifyData, effectiveEditLocator, makeCellKey, resetCellSelection, rowKeyStr, updateCellSelection]);
|
||||
|
||||
useEffect(() => {
|
||||
closeCellEditModeRef.current = closeCellEditMode;
|
||||
}, [closeCellEditMode]);
|
||||
@@ -2548,12 +2569,19 @@ const DataGrid: React.FC<DataGridProps> = ({
|
||||
showColumnHeaderContextMenu(event, key);
|
||||
},
|
||||
onClickCapture: (event: React.MouseEvent<HTMLElement>) => {
|
||||
if (!onSort) return;
|
||||
const eventTarget = event.target as HTMLElement | null;
|
||||
if (eventTarget?.closest?.('[data-grid-fk-jump="true"]')) return;
|
||||
if (eventTarget?.closest?.('[data-grid-column-filter-trigger="true"]')) return;
|
||||
if (eventTarget?.closest?.('[data-grid-column-filter-popover="true"]')) return;
|
||||
if (eventTarget?.closest?.('.ant-select-dropdown')) return;
|
||||
if (eventTarget?.closest?.('.react-resizable-handle')) return;
|
||||
if (cellEditMode && canModifyData && isWritableResultColumn(key, effectiveEditLocator)) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
selectEditableColumnCells(key);
|
||||
return;
|
||||
}
|
||||
if (!onSort) return;
|
||||
const headerCell = event.currentTarget as HTMLElement;
|
||||
const upArrow = headerCell.querySelector('.ant-table-column-sorter-up') as HTMLElement | null;
|
||||
const downArrow = headerCell.querySelector('.ant-table-column-sorter-down') as HTMLElement | null;
|
||||
@@ -2574,7 +2602,7 @@ const DataGrid: React.FC<DataGridProps> = ({
|
||||
},
|
||||
}),
|
||||
}));
|
||||
}, [canModifyData, columnWidths, currentConnConfig, dataTableDensity, displayColumnNames, displayColumnTypeMap, enableVirtual, handleResizeAutoFit, handleResizeStart, isV2Ui, language, normalizedPageFindText, onSort, pinnedLeftColumnSet, renderColumnTitle, showColumnComment, showColumnHeaderContextMenu, showColumnType, sortInfo]);
|
||||
}, [canModifyData, cellEditMode, columnWidths, currentConnConfig, dataTableDensity, displayColumnNames, displayColumnTypeMap, effectiveEditLocator, enableVirtual, handleResizeAutoFit, handleResizeStart, isV2Ui, language, normalizedPageFindText, onSort, pinnedLeftColumnSet, renderColumnTitle, selectEditableColumnCells, showColumnComment, showColumnHeaderContextMenu, showColumnType, sortInfo]);
|
||||
|
||||
const mergedColumns = useMemo(() => columns.map((col): ColumnType<any> => {
|
||||
const dataIndex = String(col.dataIndex);
|
||||
|
||||
Reference in New Issue
Block a user