mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-08-10 00:33:28 +08:00
fix(data-grid): 修复行号列整格双击切换文本视图
This commit is contained in:
@@ -933,6 +933,7 @@ describe('DataGrid layout', () => {
|
||||
'data_grid.record_view.empty': 'No rows label',
|
||||
'data_grid.record_view.json_record_count': `${params?.count} JSON rows label`,
|
||||
'data_grid.record_view.edit_json': 'Edit JSON label',
|
||||
'data_grid.record_view.back_to_table': 'Back to table label',
|
||||
'data_grid.record_view.previous': 'Previous label',
|
||||
'data_grid.record_view.next': 'Next label',
|
||||
'data_grid.record_view.record_position': `Record label ${params?.current} of ${params?.total}`,
|
||||
@@ -1054,10 +1055,12 @@ describe('DataGrid layout', () => {
|
||||
jsonViewText="[]"
|
||||
translate={translate}
|
||||
onOpenJsonEditor={() => {}}
|
||||
onReturnToTable={() => {}}
|
||||
/>,
|
||||
);
|
||||
expect(jsonRecordMarkup).toContain('5 JSON rows label');
|
||||
expect(jsonRecordMarkup).toContain('Edit JSON label');
|
||||
expect(jsonRecordMarkup).toContain('Back to table label');
|
||||
expect(jsonRecordMarkup).not.toContain('data_grid.record_view');
|
||||
|
||||
const textRecordMarkup = renderToStaticMarkup(
|
||||
@@ -1076,6 +1079,7 @@ describe('DataGrid layout', () => {
|
||||
onPrev={() => {}}
|
||||
onNext={() => {}}
|
||||
onEditCurrent={() => {}}
|
||||
onReturnToTable={() => {}}
|
||||
formatTextViewValue={(value) => String(value)}
|
||||
/>,
|
||||
);
|
||||
@@ -1083,6 +1087,7 @@ describe('DataGrid layout', () => {
|
||||
expect(textRecordMarkup).toContain('Next label');
|
||||
expect(textRecordMarkup).toContain('Record label 1 of 2');
|
||||
expect(textRecordMarkup).toContain('Edit current label');
|
||||
expect(textRecordMarkup).toContain('Back to table label');
|
||||
expect(textRecordMarkup).toContain('raw_sql');
|
||||
expect(textRecordMarkup).toContain('TYPE varchar(128)');
|
||||
expect(textRecordMarkup).toContain('COMMENT SQL text payload');
|
||||
@@ -1105,6 +1110,7 @@ describe('DataGrid layout', () => {
|
||||
onPrev={() => {}}
|
||||
onNext={() => {}}
|
||||
onEditCurrent={() => {}}
|
||||
onReturnToTable={() => {}}
|
||||
formatTextViewValue={(value) => String(value)}
|
||||
/>,
|
||||
);
|
||||
@@ -1415,9 +1421,13 @@ describe('DataGrid layout', () => {
|
||||
expect(markup).toContain('align-items:center');
|
||||
expect(markup).toContain('min-height:var(--gonavi-header-min-height, 40px)');
|
||||
expect(markup).toContain('text-align:center');
|
||||
expect(markup).toContain('padding-inline:2');
|
||||
expect(markup).toContain('padding:0');
|
||||
expect(markup).toContain('vertical-align:middle');
|
||||
expect(markup).toContain('data-grid-row-number="true"');
|
||||
expect(markup).toContain('data-grid-row-number-action="true"');
|
||||
expect(markup).toContain('display:flex');
|
||||
expect(markup).toContain('width:100%');
|
||||
expect(markup).toContain('height:100%');
|
||||
expect(markup).toContain('width:36');
|
||||
// ant Table fixed 列会渲染 fix 相关 class
|
||||
expect(markup.includes('ant-table-cell-fix') || markup.includes('fixed')).toBe(true);
|
||||
|
||||
@@ -3322,6 +3322,10 @@ const DataGrid: React.FC<DataGridProps> = ({
|
||||
return ROW_NUMBER_COLUMN_WIDTH;
|
||||
}, [columnWidths]);
|
||||
|
||||
const handleRowNumberDoubleClick = useCallback((index: number) => {
|
||||
handleViewModeChange('text', { textRecordIndex: index });
|
||||
}, [handleViewModeChange]);
|
||||
|
||||
const rowNumberColumn = useMemo<ColumnType<any>>(() => ({
|
||||
title: (
|
||||
<div
|
||||
@@ -3368,12 +3372,18 @@ const DataGrid: React.FC<DataGridProps> = ({
|
||||
minWidth: 28,
|
||||
},
|
||||
}),
|
||||
onCell: () => ({
|
||||
onCell: (_record: Item, index?: number) => ({
|
||||
'data-grid-row-number-action': 'true',
|
||||
style: {
|
||||
width: rowNumberColumnWidth,
|
||||
minWidth: 28,
|
||||
paddingInline: 2,
|
||||
padding: 0,
|
||||
textAlign: 'center' as const,
|
||||
},
|
||||
onDoubleClick: (event: React.MouseEvent<HTMLElement>) => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
handleRowNumberDoubleClick(index ?? 0);
|
||||
},
|
||||
}),
|
||||
render: (_value: unknown, _record: Item, index: number) => {
|
||||
@@ -3381,12 +3391,31 @@ const DataGrid: React.FC<DataGridProps> = ({
|
||||
const pageSize = Math.max(1, Number(pagination?.pageSize) || 0);
|
||||
const offset = pageSize > 0 ? (currentPage - 1) * pageSize : 0;
|
||||
return (
|
||||
<span className="data-grid-row-number" data-grid-row-number="true">
|
||||
{offset + index + 1}
|
||||
</span>
|
||||
<Tooltip title={translateDataGrid('data_grid.row_number.double_click_to_view')}>
|
||||
<span
|
||||
className="data-grid-row-number"
|
||||
data-grid-row-number="true"
|
||||
style={{
|
||||
display: 'flex',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
minHeight: 24,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
cursor: 'pointer',
|
||||
}}
|
||||
onDoubleClick={(event) => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
handleRowNumberDoubleClick(index);
|
||||
}}
|
||||
>
|
||||
{offset + index + 1}
|
||||
</span>
|
||||
</Tooltip>
|
||||
);
|
||||
},
|
||||
}), [handleResizeAutoFit, handleResizeStart, pagination?.current, pagination?.pageSize, rowNumberColumnWidth]);
|
||||
}), [handleResizeAutoFit, handleResizeStart, handleRowNumberDoubleClick, pagination?.current, pagination?.pageSize, rowNumberColumnWidth, translateDataGrid]);
|
||||
|
||||
const tableColumns = useMemo(() => {
|
||||
const baseColumns = resolvedShowRowNumberColumn
|
||||
|
||||
@@ -12,6 +12,7 @@ interface DataGridJsonViewProps {
|
||||
jsonViewText: string;
|
||||
translate?: DataGridRecordViewTranslate;
|
||||
onOpenJsonEditor: () => void;
|
||||
onReturnToTable: () => void;
|
||||
}
|
||||
|
||||
export const DataGridJsonView: React.FC<DataGridJsonViewProps> = ({
|
||||
@@ -21,6 +22,7 @@ export const DataGridJsonView: React.FC<DataGridJsonViewProps> = ({
|
||||
jsonViewText,
|
||||
translate = defaultTranslate,
|
||||
onOpenJsonEditor,
|
||||
onReturnToTable,
|
||||
}) => (
|
||||
<div style={{ height: '100%', minHeight: 0, display: 'flex', flexDirection: 'column' }}>
|
||||
<div style={{ padding: '8px 10px', borderBottom: darkMode ? '1px solid rgba(255,255,255,0.08)' : '1px solid rgba(0,0,0,0.08)', display: 'flex', alignItems: 'center', gap: 8 }}>
|
||||
@@ -34,6 +36,9 @@ export const DataGridJsonView: React.FC<DataGridJsonViewProps> = ({
|
||||
{translate('data_grid.record_view.edit_json')}
|
||||
</Button>
|
||||
)}
|
||||
<Button size="small" onClick={onReturnToTable}>
|
||||
{translate('data_grid.record_view.back_to_table')}
|
||||
</Button>
|
||||
</div>
|
||||
<div style={{ flex: 1, minHeight: 0, padding: '8px 10px 10px 10px' }}>
|
||||
<Editor
|
||||
@@ -72,6 +77,7 @@ interface DataGridTextViewProps {
|
||||
onPrev: () => void;
|
||||
onNext: () => void;
|
||||
onEditCurrent: () => void;
|
||||
onReturnToTable: () => void;
|
||||
formatTextViewValue: (value: any, columnName?: string) => string;
|
||||
}
|
||||
|
||||
@@ -90,6 +96,7 @@ export const DataGridTextView: React.FC<DataGridTextViewProps> = ({
|
||||
onPrev,
|
||||
onNext,
|
||||
onEditCurrent,
|
||||
onReturnToTable,
|
||||
formatTextViewValue,
|
||||
}) => {
|
||||
const metaTextColor = darkMode ? 'rgba(255,255,255,0.52)' : 'rgba(0,0,0,0.48)';
|
||||
@@ -113,6 +120,9 @@ export const DataGridTextView: React.FC<DataGridTextViewProps> = ({
|
||||
{translate('data_grid.record_view.edit_current')}
|
||||
</Button>
|
||||
)}
|
||||
<Button size="small" onClick={onReturnToTable}>
|
||||
{translate('data_grid.record_view.back_to_table')}
|
||||
</Button>
|
||||
</div>
|
||||
<div className="custom-scrollbar" style={{ flex: 1, minHeight: 0, overflow: 'auto', padding: '8px 12px' }}>
|
||||
{currentTextRow ? displayOutputColumnNames.map((col) => {
|
||||
|
||||
@@ -852,6 +852,7 @@ const renderDataTableView = () => (
|
||||
canModifyData={canModifyData}
|
||||
jsonViewText={jsonViewText}
|
||||
translate={translateDataGrid}
|
||||
onReturnToTable={() => handleViewModeChange('table')}
|
||||
onOpenJsonEditor={handleOpenJsonEditor}
|
||||
/>
|
||||
) : (
|
||||
@@ -867,6 +868,7 @@ const renderDataTableView = () => (
|
||||
showColumnType={showColumnType}
|
||||
showColumnComment={showColumnComment}
|
||||
translate={translateDataGrid}
|
||||
onReturnToTable={() => handleViewModeChange('table')}
|
||||
onPrev={() => setTextRecordIndex((i: number) => Math.max(0, i - 1))}
|
||||
onNext={() => setTextRecordIndex((i: number) => Math.min(textViewRows.length - 1, i + 1))}
|
||||
onEditCurrent={openCurrentViewRowEditor}
|
||||
|
||||
@@ -386,6 +386,14 @@ export const buildDataGridCssText = ({
|
||||
.${gridId} .data-grid-row-number-cell {
|
||||
text-align: center !important;
|
||||
overflow: hidden !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
.${gridId} .ant-table-tbody-virtual-holder .ant-table-row > .ant-table-cell.data-grid-row-number-cell,
|
||||
.${gridId} .ant-table-tbody .ant-table-row > .ant-table-cell.data-grid-row-number-cell,
|
||||
.${gridId} .ant-table-header th.data-grid-row-number-cell,
|
||||
body[data-ui-version="v2"] .${gridId}.gn-v2-data-grid .ant-table-tbody-virtual-holder .ant-table-row > .ant-table-cell.data-grid-row-number-cell,
|
||||
body[data-ui-version="v2"] .${gridId}.gn-v2-data-grid .ant-table-tbody .ant-table-row > .ant-table-cell.data-grid-row-number-cell {
|
||||
padding: 0 !important;
|
||||
}
|
||||
.${gridId} .ant-table-thead > tr:first-child > th:first-child,
|
||||
|
||||
|
||||
@@ -99,4 +99,24 @@ describe('useDataGridDdlView i18n', () => {
|
||||
|
||||
expect(messageApi.error).toHaveBeenCalledWith('ORA-31603: object "USERS" not found');
|
||||
});
|
||||
|
||||
it('honors an explicit text row when opening from the row number', () => {
|
||||
const setTextRecordIndex = vi.fn();
|
||||
renderHook({
|
||||
selectedRowKeys: ['row-10'],
|
||||
mergedDisplayDataRef: {
|
||||
current: [
|
||||
{ __gonavi_row_key__: 'row-8' },
|
||||
{ __gonavi_row_key__: 'row-10' },
|
||||
],
|
||||
},
|
||||
setTextRecordIndex,
|
||||
});
|
||||
|
||||
act(() => {
|
||||
controller?.handleViewModeChange('text', { textRecordIndex: 0 });
|
||||
});
|
||||
|
||||
expect(setTextRecordIndex).toHaveBeenCalledWith(0);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -122,7 +122,7 @@ export interface UseDataGridDdlViewResult {
|
||||
ddlRequestSeqRef: React.MutableRefObject<number>;
|
||||
isTableSurfaceActive: boolean;
|
||||
handleOpenTableDdl: (options?: { asView?: boolean }) => Promise<void>;
|
||||
handleViewModeChange: (nextMode: GridViewMode) => void;
|
||||
handleViewModeChange: (nextMode: GridViewMode, options?: { textRecordIndex?: number }) => void;
|
||||
handleDdlSidebarResizeStart: (event: React.MouseEvent<HTMLDivElement>) => void;
|
||||
resetDdlViewState: () => void;
|
||||
closeDdlView: () => void;
|
||||
@@ -291,7 +291,7 @@ export const useDataGridDdlView = ({
|
||||
void handleOpenTableDdl({ asView: true });
|
||||
}, [canRestoreSharedDdlView, ddlContextKey, handleOpenTableDdl, hasPendingLocalTableViewRequest, isActive]);
|
||||
|
||||
const handleViewModeChange = React.useCallback((nextMode: GridViewMode) => {
|
||||
const handleViewModeChange = React.useCallback((nextMode: GridViewMode, options?: { textRecordIndex?: number }) => {
|
||||
setSuppressSharedDdlView(false);
|
||||
if ((nextMode === 'fields' || nextMode === 'ddl' || nextMode === 'er' || nextMode === 'sqlLog') && !isV2Ui) {
|
||||
setSharedDdlViewOpen(false);
|
||||
@@ -317,11 +317,17 @@ export const useDataGridDdlView = ({
|
||||
}
|
||||
|
||||
if (nextMode === 'text') {
|
||||
const selectedKey = selectedRowKeys[0];
|
||||
if (selectedKey !== undefined) {
|
||||
const idx = mergedDisplayDataRef.current.findIndex((row) => rowKeyStr(row?.__gonavi_row_key__) === rowKeyStr(selectedKey));
|
||||
if (idx >= 0) {
|
||||
setTextRecordIndex(idx);
|
||||
const explicitIndex = options?.textRecordIndex;
|
||||
if (explicitIndex !== undefined && Number.isFinite(explicitIndex)) {
|
||||
const maxIndex = Math.max(0, mergedDisplayDataRef.current.length - 1);
|
||||
setTextRecordIndex(Math.max(0, Math.min(Math.trunc(explicitIndex), maxIndex)));
|
||||
} else {
|
||||
const selectedKey = selectedRowKeys[0];
|
||||
if (selectedKey !== undefined) {
|
||||
const idx = mergedDisplayDataRef.current.findIndex((row) => rowKeyStr(row?.__gonavi_row_key__) === rowKeyStr(selectedKey));
|
||||
if (idx >= 0) {
|
||||
setTextRecordIndex(idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user