diff --git a/packages/toolpad-app/src/toolpadDataSources/postgres/client.tsx b/packages/toolpad-app/src/toolpadDataSources/postgres/client.tsx index 54f3a27983e..63b8efa6213 100644 --- a/packages/toolpad-app/src/toolpadDataSources/postgres/client.tsx +++ b/packages/toolpad-app/src/toolpadDataSources/postgres/client.tsx @@ -7,6 +7,7 @@ import { useForm } from 'react-hook-form'; import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline'; import ErrorOutlineIcon from '@mui/icons-material/ErrorOutline'; import SyncIcon from '@mui/icons-material/Sync'; +import { getObjectKey } from '@mui/toolpad-core/objectKey'; import SplitPane from '../../components/SplitPane'; import ErrorAlert from '../../toolpad/AppEditor/PageEditor/ErrorAlert'; import ParametersEditor from '../../toolpad/AppEditor/PageEditor/ParametersEditor'; @@ -189,6 +190,7 @@ function QueryEditor({ const rawRows: any[] = preview?.data || EMPTY_ROWS; const columns: GridColDef[] = React.useMemo(() => parseColumns(inferColumns(rawRows)), [rawRows]); const rows = React.useMemo(() => rawRows.map((row, id) => ({ id, ...row })), [rawRows]); + const previewGridKey = React.useMemo(() => getObjectKey(columns), [columns]); return ( @@ -220,7 +222,7 @@ function QueryEditor({ {preview?.error ? ( ) : ( - + )} diff --git a/packages/toolpad-app/tsconfig.json b/packages/toolpad-app/tsconfig.json index 646db9a3032..3c36a973aaf 100644 --- a/packages/toolpad-app/tsconfig.json +++ b/packages/toolpad-app/tsconfig.json @@ -2,7 +2,8 @@ "compilerOptions": { "paths": { // TODO: remove when we move to typescript 4.7 (supports package exports) - "@mui/toolpad-core/runtime": ["../toolpad-core/dist/runtime"] + "@mui/toolpad-core/runtime": ["../toolpad-core/dist/runtime"], + "@mui/toolpad-core/objectKey": ["../toolpad-core/dist/objectKey"] }, "target": "es5", "lib": ["dom", "dom.iterable", "esnext"], diff --git a/packages/toolpad-components/src/DataGrid.tsx b/packages/toolpad-components/src/DataGrid.tsx index 7d1c021915a..f6bc268e521 100644 --- a/packages/toolpad-components/src/DataGrid.tsx +++ b/packages/toolpad-components/src/DataGrid.tsx @@ -13,10 +13,12 @@ import { GridSelectionModel, GridValueFormatterParams, GridColDef, + GridValueGetterParams, } from '@mui/x-data-grid-pro'; import * as React from 'react'; import { useNode, createComponent } from '@mui/toolpad-core'; import { Box, debounce, LinearProgress, Skeleton, styled } from '@mui/material'; +import { getObjectKey } from '@mui/toolpad-core/objectKey'; // Pseudo random number. See https://stackoverflow.com/a/47593316 function mulberry32(a: number): () => number { @@ -124,13 +126,19 @@ const DEFAULT_TYPES = new Set([ 'actions', ]); +function dateValueGetter({ value }: GridValueGetterParams) { + return typeof value === 'number' ? new Date(value) : value; +} + const COLUMN_TYPES: Record> = { json: { valueFormatter: ({ value: cellValue }: GridValueFormatterParams) => JSON.stringify(cellValue), }, - datetime: { - valueFormatter: ({ value: cellValue }: GridValueFormatterParams) => - typeof cellValue === 'number' ? new Date(cellValue) : cellValue, + date: { + valueGetter: dateValueGetter, + }, + dateTime: { + valueGetter: dateValueGetter, }, }; @@ -286,6 +294,13 @@ const DataGridComponent = React.forwardRef(function DataGridComponent( const columns: GridColumns = React.useMemo(() => parseColumns(columnsProp || []), [columnsProp]); + // The grid doesn't react to changes to the column prop, so it needs to be remounted + // when that updates to reflect changes made in the editor. + const key = React.useMemo( + () => [rowIdFieldProp ?? '', getObjectKey(columnsProp)].join('::'), + [columnsProp, rowIdFieldProp], + ); + return (
(); +let nextId = 0; + +function getNextId(): string { + const id = `object-id::${nextId}`; + nextId += 1; + return id; +} + +/** + * Used to generate ids for object instances. + */ +export function getObjectKey(object: any): string { + let id = weakMap.get(object); + if (!id) { + id = getNextId(); + weakMap.set(object, id); + } + return id; +}