From d08ab62f924ce5ed3ebdc08328a1d3d1a80fef08 Mon Sep 17 00:00:00 2001 From: Syngnat Date: Wed, 24 Jun 2026 15:56:07 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20fix(data-grid):=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E5=88=B7=E6=96=B0=E5=90=8E=E6=9C=AA=E6=8F=90=E4=BA=A4?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=A2=AB=E6=B8=85=E7=A9=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/DataGrid.ddl.test.tsx | 58 +++++++++++++++++++ .../src/components/DataGrid.layout.test.tsx | 7 ++- frontend/src/components/DataGridShell.tsx | 8 +-- 3 files changed, 64 insertions(+), 9 deletions(-) diff --git a/frontend/src/components/DataGrid.ddl.test.tsx b/frontend/src/components/DataGrid.ddl.test.tsx index 1d1961b..26fcf07 100644 --- a/frontend/src/components/DataGrid.ddl.test.tsx +++ b/frontend/src/components/DataGrid.ddl.test.tsx @@ -1091,6 +1091,64 @@ describe('DataGrid DDL interactions', () => { renderer!.unmount(); }); + it('keeps pending local changes visible after refreshing the grid', async () => { + const reloadSpy = vi.fn(); + + const Harness = () => { + const [rows, setRows] = React.useState([ + { __gonavi_row_key__: 'row-1', id: 1, name: 'old' }, + ]); + + return ( + { + reloadSpy(); + setRows([{ __gonavi_row_key__: 'row-1', id: 1, name: 'old' }]); + }} + /> + ); + }; + + let renderer: ReactTestRenderer; + await act(async () => { + renderer = create(); + }); + await waitForEffects(); + + await act(async () => { + renderer!.root.findByType(DataGridToolbarFrame).props.onAddRow(); + }); + await waitForEffects(); + + expect(testRenderState.latestTableProps.dataSource).toHaveLength(2); + expect(renderer!.root.findByType(DataGridToolbarFrame).props.pendingChangeCount).toBe(1); + + await act(async () => { + renderer!.root.findByType(DataGridToolbarFrame).props.onRefresh(); + }); + await waitForEffects(); + await waitForEffects(); + + expect(reloadSpy).toHaveBeenCalledTimes(1); + expect(testRenderState.latestTableProps.dataSource).toHaveLength(2); + expect(testRenderState.latestTableProps.dataSource[1][GONAVI_ROW_KEY]).toContain('new-'); + expect(renderer!.root.findByType(DataGridToolbarFrame).props.pendingChangeCount).toBe(1); + renderer!.unmount(); + }); + it('localizes v2 column header fallback labels', () => { setCurrentLanguage('en-US'); diff --git a/frontend/src/components/DataGrid.layout.test.tsx b/frontend/src/components/DataGrid.layout.test.tsx index 03206fc..816aa19 100644 --- a/frontend/src/components/DataGrid.layout.test.tsx +++ b/frontend/src/components/DataGrid.layout.test.tsx @@ -2037,10 +2037,13 @@ describe('DataGrid layout', () => { } }); - it('clears modified cell markers when refreshing the grid', () => { + it('keeps pending cell markers when refreshing the grid', () => { const source = readDataGridSource(); - expect(source).toMatch(/const handleRefreshGrid = useCallback\(\(\) => \{[\s\S]*setModifiedColumns\(\{\}\);[\s\S]*if \(onReload\) onReload\(\);[\s\S]*\}, \[[\s\S]*clearAutoCommitTimer[\s\S]*onReload[\s\S]*\]\);/); + expect(source).toMatch(/const handleRefreshGrid = useCallback\(\(\) => \{[\s\S]*setSelectedRowKeys\(\[\]\);[\s\S]*if \(onReload\) onReload\(\);[\s\S]*\}, \[[\s\S]*onReload[\s\S]*\]\);/); + expect(source).not.toMatch(/const handleRefreshGrid = useCallback\(\(\) => \{[\s\S]*setAddedRows\(\[\]\);[\s\S]*if \(onReload\) onReload\(\);[\s\S]*\}\,/); + expect(source).not.toMatch(/const handleRefreshGrid = useCallback\(\(\) => \{[\s\S]*setModifiedRows\(\{\}\);[\s\S]*if \(onReload\) onReload\(\);[\s\S]*\}\,/); + expect(source).not.toMatch(/const handleRefreshGrid = useCallback\(\(\) => \{[\s\S]*setDeletedRowKeys\(new Set\(\)\);[\s\S]*if \(onReload\) onReload\(\);[\s\S]*\}\,/); }); it('routes temporal inline editors through the current connection config', () => { diff --git a/frontend/src/components/DataGridShell.tsx b/frontend/src/components/DataGridShell.tsx index 8140cff..bdecebc 100644 --- a/frontend/src/components/DataGridShell.tsx +++ b/frontend/src/components/DataGridShell.tsx @@ -479,12 +479,6 @@ const renderDataTableView = () => ( ), [columnMetaMap, columnMetaMapByLowerName, currentConnConfig, dbType, displayColumnNames, effectiveEditLocator, rowEditorOpen, rowEditorRowKey]); const handleRefreshGrid = useCallback(() => { - clearAutoCommitTimer(); - autoCommitFailedTokenRef.current = -1; - setAddedRows([]); - setModifiedRows({}); - setDeletedRowKeys(new Set()); - setModifiedColumns({}); setSelectedRowKeys([]); const normalizedTableName = String(tableName || '').trim(); const normalizedDbName = String(dbName || '').trim(); @@ -496,7 +490,7 @@ const renderDataTableView = () => ( setMetadataReloadVersion((value: number) => value + 1); } if (onReload) onReload(); - }, [clearAutoCommitTimer, connectionId, dbName, onReload, tableName]); + }, [connectionId, dbName, onReload, tableName]); const handleResetPendingChanges = useCallback(() => { clearAutoCommitTimer();