diff --git a/examples/demo/src/orders/OrderList.tsx b/examples/demo/src/orders/OrderList.tsx index 43eab5bd8cb..e0337691324 100644 --- a/examples/demo/src/orders/OrderList.tsx +++ b/examples/demo/src/orders/OrderList.tsx @@ -1,14 +1,12 @@ import * as React from 'react'; -import { Fragment, useCallback, useEffect, useState } from 'react'; +import { Fragment, useCallback } from 'react'; import { AutocompleteInput, BooleanField, Datagrid, DateField, DateInput, - RaRecord, List, - ListContextProvider, NullableBooleanInput, NumberField, ReferenceInput, @@ -87,38 +85,12 @@ const useGetTotals = (filterValues: any) => { const TabbedDatagrid = () => { const listContext = useListContext(); - const { - data, - filterValues, - setFilters, - displayedFilters, - isLoading, - } = listContext; + const { filterValues, setFilters, displayedFilters } = listContext; const isXSmall = useMediaQuery(theme => theme.breakpoints.down('sm') ); - const [ordered, setOrdered] = useState([]); - const [delivered, setDelivered] = useState([]); - const [cancelled, setCancelled] = useState([]); const totals = useGetTotals(filterValues) as any; - useEffect(() => { - if (isLoading) { - return; - } - switch (filterValues.status) { - case 'ordered': - setOrdered(data); - break; - case 'delivered': - setDelivered(data); - break; - case 'cancelled': - setCancelled(data); - break; - } - }, [data, isLoading, filterValues.status]); - const handleChange = useCallback( (event: React.ChangeEvent<{}>, value: any) => { setFilters && @@ -131,13 +103,6 @@ const TabbedDatagrid = () => { [displayedFilters, filterValues, setFilters] ); - const selectedData = - filterValues.status === 'ordered' - ? ordered - : filterValues.status === 'delivered' - ? delivered - : cancelled; - return ( { {isXSmall ? ( - - - + ) : ( <> {filterValues.status === 'ordered' && ( - - - - - - - - - - - - + + + + + + + + + + )} {filterValues.status === 'delivered' && ( - - - - - - - - - - - - - + + + + + + + + + + + )} {filterValues.status === 'cancelled' && ( - - - - - - - - - - - - - + + + + + + + + + + + )} )} diff --git a/packages/ra-core/src/controller/list/ListContextProvider.tsx b/packages/ra-core/src/controller/list/ListContextProvider.tsx index 349c122ba5d..f24d63889ff 100644 --- a/packages/ra-core/src/controller/list/ListContextProvider.tsx +++ b/packages/ra-core/src/controller/list/ListContextProvider.tsx @@ -6,6 +6,7 @@ import { ListPaginationContext, usePickPaginationContext, } from './ListPaginationContext'; +import { ListControllerResult } from './useListController'; /** * Create a List Context and several thematic List subcontext. @@ -34,7 +35,13 @@ import { * @see ListContext * @see ListFilterContext */ -export const ListContextProvider = ({ value, children }) => ( +export const ListContextProvider = ({ + value, + children, +}: { + value: ListControllerResult; + children: React.ReactNode; +}) => ( diff --git a/packages/ra-core/src/controller/list/useListController.ts b/packages/ra-core/src/controller/list/useListController.ts index 2530b9dc1ac..f57a39785f5 100644 --- a/packages/ra-core/src/controller/list/useListController.ts +++ b/packages/ra-core/src/controller/list/useListController.ts @@ -219,7 +219,7 @@ export interface ListControllerResult { onUnselectItems: () => void; page: number; perPage: number; - refetch: UseGetListHookValue['refetch']; + refetch: (() => void) | UseGetListHookValue['refetch']; resource: string; selectedIds: RecordType['id'][]; setFilters: ( diff --git a/packages/ra-core/src/form/choices/ChoicesContext.ts b/packages/ra-core/src/form/choices/ChoicesContext.ts index 3421d93bba5..d7b2340cc48 100644 --- a/packages/ra-core/src/form/choices/ChoicesContext.ts +++ b/packages/ra-core/src/form/choices/ChoicesContext.ts @@ -1,4 +1,5 @@ import { createContext } from 'react'; +import { UseGetListHookValue } from '../../dataProvider/useGetList'; import { FilterPayload, RaRecord, SortPayload } from '../../types'; /** @@ -24,7 +25,7 @@ export type ChoicesContextValue = { isLoading: boolean; page: number; perPage: number; - refetch: () => void; + refetch: (() => void) | UseGetListHookValue['refetch']; resource: string; selectedChoices: RecordType[]; setFilters: ( diff --git a/packages/ra-ui-materialui/src/field/ArrayField.tsx b/packages/ra-ui-materialui/src/field/ArrayField.tsx index 68b53144cd4..0722981f328 100644 --- a/packages/ra-ui-materialui/src/field/ArrayField.tsx +++ b/packages/ra-ui-materialui/src/field/ArrayField.tsx @@ -87,7 +87,8 @@ export const ArrayField: FC = memo(props => { sort: { field: null, order: null }, displayedFilters: null, filterValues: null, - hasCreate: null, + hasNextPage: null, + hasPreviousPage: null, hideFilter: null, isFetching: false, isLoading: false, @@ -96,6 +97,7 @@ export const ArrayField: FC = memo(props => { onUnselectItems: null, page: null, perPage: null, + refetch: null, resource, setFilters: null, setPage: null, diff --git a/packages/ra-ui-materialui/src/list/filter/FilterListItem.spec.tsx b/packages/ra-ui-materialui/src/list/filter/FilterListItem.spec.tsx index 595bf994efb..85ddf678061 100644 --- a/packages/ra-ui-materialui/src/list/filter/FilterListItem.spec.tsx +++ b/packages/ra-ui-materialui/src/list/filter/FilterListItem.spec.tsx @@ -2,15 +2,41 @@ import * as React from 'react'; import expect from 'expect'; import { render, cleanup } from '@testing-library/react'; -import { ListContextProvider } from 'ra-core'; +import { ListContextProvider, ListControllerResult } from 'ra-core'; import { FilterListItem } from './FilterListItem'; +const defaultListContext: ListControllerResult = { + data: [], + displayedFilters: null, + filterValues: null, + hasNextPage: false, + hasPreviousPage: false, + hideFilter: (filterName: string) => {}, + isFetching: false, + isLoading: false, + onSelect: (ids: any[]) => {}, + onToggleItem: (id: any) => {}, + onUnselectItems: () => {}, + page: 1, + perPage: 10, + refetch: () => {}, + resource: 'posts', + selectedIds: [], + setFilters: (filters: any) => {}, + setPage: (page: number) => {}, + setPerPage: (perPage: number) => {}, + setSort: (sort: any) => {}, + showFilter: (filterName: string) => {}, + sort: { field: '', order: 'ASC' }, + total: 0, +}; + describe('', () => { afterEach(cleanup); it("should display the item label when it's a string", () => { const { queryByText } = render( - + ); @@ -19,7 +45,7 @@ describe('', () => { it("should display the item label when it's an element", () => { const { queryByTestId } = render( - + Foo} value={{ foo: 'bar' }} @@ -31,40 +57,40 @@ describe('', () => { it('should not appear selected if filterValues is empty', () => { const { getByText } = render( - + ); - expect(getByText('Foo').parentElement.dataset.selected).toBe('false'); + expect(getByText('Foo').parentElement?.dataset.selected).toBe('false'); }); it('should not appear selected if filterValues does not contain value', () => { const { getByText } = render( ); - expect(getByText('Foo').parentElement.dataset.selected).toBe('false'); + expect(getByText('Foo').parentElement?.dataset.selected).toBe('false'); }); it('should appear selected if filterValues is equal to value', () => { const { getByText } = render( ); - expect(getByText('Foo').parentElement.dataset.selected).toBe('true'); + expect(getByText('Foo').parentElement?.dataset.selected).toBe('true'); }); it('should appear selected if filterValues is equal to value for nested filters', () => { const { getByText } = render( ', () => { /> ); - expect(getByText('Foo').parentElement.dataset.selected).toBe('true'); + expect(getByText('Foo').parentElement?.dataset.selected).toBe('true'); }); it('should appear selected if filterValues contains value', () => { const { getByText } = render( ); - expect(getByText('Foo').parentElement.dataset.selected).toBe('true'); + expect(getByText('Foo').parentElement?.dataset.selected).toBe('true'); }); });