diff --git a/packages/ra-core/src/controller/button/useDeleteWithConfirmController.spec.tsx b/packages/ra-core/src/controller/button/useDeleteWithConfirmController.spec.tsx index edc777e5547..be5e46d2423 100644 --- a/packages/ra-core/src/controller/button/useDeleteWithConfirmController.spec.tsx +++ b/packages/ra-core/src/controller/button/useDeleteWithConfirmController.spec.tsx @@ -44,7 +44,7 @@ describe('useDeleteWithConfirmController', () => { const button = await screen.findByText('Delete'); fireEvent.click(button); - waitFor(() => expect(receivedMeta).toEqual('metadata'), { + await waitFor(() => expect(receivedMeta).toEqual('metadata'), { timeout: 1000, }); }); diff --git a/packages/ra-core/src/controller/button/useDeleteWithUndoController.spec.tsx b/packages/ra-core/src/controller/button/useDeleteWithUndoController.spec.tsx index 2de9f730efa..7566f0ef203 100644 --- a/packages/ra-core/src/controller/button/useDeleteWithUndoController.spec.tsx +++ b/packages/ra-core/src/controller/button/useDeleteWithUndoController.spec.tsx @@ -3,7 +3,11 @@ import expect from 'expect'; import { Route, Routes } from 'react-router'; import { fireEvent, screen, render, waitFor } from '@testing-library/react'; -import { testDataProvider } from '../../dataProvider'; +import { + testDataProvider, + UndoableMutation, + useTakeUndoableMutation, +} from '../../dataProvider'; import { CoreAdminContext } from '../../core'; import useDeleteWithUndoController, { UseDeleteWithUndoControllerParams, @@ -22,6 +26,12 @@ describe('useDeleteWithUndoController', () => { }), }); + let takeMutation: () => UndoableMutation | void; + const MutationTrigger = () => { + takeMutation = useTakeUndoableMutation(); + return null; + }; + const MockComponent = () => { const { handleDelete } = useDeleteWithUndoController({ record: { id: 1 }, @@ -38,13 +48,20 @@ describe('useDeleteWithUndoController', () => { } /> + ); const button = await screen.findByText('Delete'); fireEvent.click(button); - waitFor(() => expect(receivedMeta).toEqual('metadata'), { + + // Trigger the mutation. + await waitFor(() => new Promise(resolve => setTimeout(resolve, 0))); + const mutation = takeMutation(); + if (mutation) mutation({ isUndo: false }); + + await waitFor(() => expect(receivedMeta).toEqual('metadata'), { timeout: 1000, }); }); diff --git a/packages/ra-core/src/controller/input/useReferenceInputController.spec.tsx b/packages/ra-core/src/controller/input/useReferenceInputController.spec.tsx index 249ef374143..f77b6f11fd8 100644 --- a/packages/ra-core/src/controller/input/useReferenceInputController.spec.tsx +++ b/packages/ra-core/src/controller/input/useReferenceInputController.spec.tsx @@ -3,12 +3,20 @@ import { useState, useCallback, ReactElement } from 'react'; import { render, screen, fireEvent, waitFor } from '@testing-library/react'; import expect from 'expect'; -import { useReferenceInputController } from './useReferenceInputController'; +import { + useReferenceInputController, + UseReferenceInputControllerParams, +} from './useReferenceInputController'; import { CoreAdminContext } from '../../core'; -import { Form, useInput } from '../../form'; +import { ChoicesContextValue, Form, useInput } from '../../form'; import { testDataProvider } from '../../dataProvider'; +import { SortPayload } from '../../types'; -const ReferenceInputController = props => { +const ReferenceInputController = ( + props: UseReferenceInputControllerParams & { + children: (options: ChoicesContextValue) => React.ReactNode; + } +) => { const { children, ...rest } = props; const inputProps = useInput({ ...rest, @@ -160,7 +168,6 @@ describe('useReferenceInputController', () => {
{children} @@ -210,7 +217,10 @@ describe('useReferenceInputController', () => { it('should refetch reference getList when its props change', async () => { const children = jest.fn().mockReturnValue(

child

); const Component = () => { - const [sort, setSort] = useState({ field: 'title', order: 'ASC' }); + const [sort, setSort] = useState({ + field: 'title', + order: 'ASC', + }); const handleClick = useCallback( () => setSort({ field: 'body', order: 'DESC' }), [setSort] diff --git a/packages/ra-core/src/controller/input/useReferenceInputController.ts b/packages/ra-core/src/controller/input/useReferenceInputController.ts index 7ddbced53d2..2a384ea084b 100644 --- a/packages/ra-core/src/controller/input/useReferenceInputController.ts +++ b/packages/ra-core/src/controller/input/useReferenceInputController.ts @@ -1,12 +1,17 @@ import { useCallback, useEffect, useMemo, useState } from 'react'; import { useWatch } from 'react-hook-form'; -import type { UseQueryOptions } from '@tanstack/react-query'; +import { keepPreviousData, type UseQueryOptions } from '@tanstack/react-query'; import { useGetList } from '../../dataProvider'; import { useReference } from '../useReference'; import { useReferenceParams } from './useReferenceParams'; import { useWrappedSource } from '../../core'; -import type { FilterPayload, RaRecord, SortPayload } from '../../types'; +import type { + FilterPayload, + GetListResult, + RaRecord, + SortPayload, +} from '../../types'; import type { ChoicesContextValue } from '../../form'; /** @@ -45,7 +50,7 @@ import type { ChoicesContextValue } from '../../form'; * }); */ export const useReferenceInputController = ( - props: UseReferenceInputControllerParams + props: UseReferenceInputControllerParams ): ChoicesContextValue => { const { debounce, @@ -100,8 +105,10 @@ export const useReferenceInputController = ( }, { enabled: isGetMatchingEnabled, - placeholderData: previousData => previousData, - ...otherQueryOptions, + placeholderData: keepPreviousData, + ...(otherQueryOptions as UseQueryOptions< + GetListResult + >), } ); @@ -205,14 +212,11 @@ export interface UseReferenceInputControllerParams< debounce?: number; filter?: FilterPayload; queryOptions?: Omit< - UseQueryOptions<{ - data: RecordType[]; - total?: number; - pageInfo?: { - hasNextPage?: boolean; - hasPreviousPage?: boolean; - }; - }>, + UseQueryOptions< + | GetListResult + // useReference calls getManyAggregate, which returns a an array of records + | RecordType[] + >, 'queryFn' | 'queryKey' > & { meta?: any }; page?: number; diff --git a/packages/ra-ui-materialui/src/input/DatagridInput.stories.tsx b/packages/ra-ui-materialui/src/input/DatagridInput.stories.tsx index 888b76127b3..b2bd235d620 100644 --- a/packages/ra-ui-materialui/src/input/DatagridInput.stories.tsx +++ b/packages/ra-ui-materialui/src/input/DatagridInput.stories.tsx @@ -47,7 +47,6 @@ const BookEdit = () => { diff --git a/packages/ra-ui-materialui/src/input/DatagridInput.tsx b/packages/ra-ui-materialui/src/input/DatagridInput.tsx index b649fce16f1..d08ef532d69 100644 --- a/packages/ra-ui-materialui/src/input/DatagridInput.tsx +++ b/packages/ra-ui-materialui/src/input/DatagridInput.tsx @@ -175,7 +175,7 @@ export const DatagridInput = (inProps: DatagridInputProps) => { export type DatagridInputProps = Omit< CommonInputProps, - 'source' | 'readOnly' | 'disabled' + 'fullWidth' | 'source' | 'readOnly' | 'disabled' > & ChoicesProps & Omit & diff --git a/packages/ra-ui-materialui/src/input/sanitizeInputRestProps.ts b/packages/ra-ui-materialui/src/input/sanitizeInputRestProps.ts index 4d843ed54ea..14561eb19b4 100644 --- a/packages/ra-ui-materialui/src/input/sanitizeInputRestProps.ts +++ b/packages/ra-ui-materialui/src/input/sanitizeInputRestProps.ts @@ -41,6 +41,5 @@ export const sanitizeInputRestProps = ({ validate, validateFields, value, - fullWidth, ...rest }: any) => rest;