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();