diff --git a/UPGRADE.md b/UPGRADE.md
index 5cb2bd40b8c..e76a2689507 100644
--- a/UPGRADE.md
+++ b/UPGRADE.md
@@ -331,4 +331,27 @@ When using custom component with ReferenceInputController, you should rename the
+ />
+ )}
+
-```
\ No newline at end of file
+```
+
+## `loadedOnce` prop renamed as `loaded`
+
+The `List`, `ReferenceArrayfield` and `ReferenceManyField` used to inject an `loadedOnce` prop to their child. This prop has been renamed to `loaded`.
+
+As a consequence, the components usually used as children of these 3 components now accept a `loaded` prop instead of `loadedOnce`. This concerns `Datagrid`, `SingleFieldList`, and `GridList`.
+
+This change is transparent unless you use a custom view component inside a `List`, `ReferenceArrayfield` or `ReferenceManyField`.
+
+```diff
+const PostList = props => (
+
+
+
+)
+
+-const MyListView = ({ loadedOnce, ...props }) => (
++const MyListView = ({ loaded, ...props }) => (
+- if (!loadedOnce) return null;
++ if (!loaded) return null;
+ // rest of the view
+);
+```
diff --git a/examples/demo/src/products/GridList.js b/examples/demo/src/products/GridList.js
index 1a8642ced48..a003f90b946 100644
--- a/examples/demo/src/products/GridList.js
+++ b/examples/demo/src/products/GridList.js
@@ -106,7 +106,7 @@ const LoadedGridList = ({ ids, data, basePath, width }) => {
);
};
-const GridList = ({ loadedOnce, ...props }) =>
- loadedOnce ? : ;
+const GridList = ({ loaded, ...props }) =>
+ loaded ? : ;
export default withWidth()(GridList);
diff --git a/packages/ra-core/src/controller/field/ReferenceArrayFieldController.spec.tsx b/packages/ra-core/src/controller/field/ReferenceArrayFieldController.spec.tsx
index 5de569df050..c871a0d33cd 100644
--- a/packages/ra-core/src/controller/field/ReferenceArrayFieldController.spec.tsx
+++ b/packages/ra-core/src/controller/field/ReferenceArrayFieldController.spec.tsx
@@ -7,7 +7,7 @@ import { crudGetManyAccumulate } from '../../actions';
describe('', () => {
afterEach(cleanup);
- it('should set the loadedOnce prop to false when related records are not yet fetched', () => {
+ it('should set the loaded prop to false when related records are not yet fetched', () => {
const children = jest.fn().mockReturnValue('child');
renderWithRedux(
@@ -32,14 +32,14 @@ describe('', () => {
);
expect(children.mock.calls[0][0]).toEqual({
currentSort: { field: 'id', order: 'ASC' },
- loadedOnce: false,
+ loaded: false,
referenceBasePath: '',
data: null,
ids: [1, 2],
});
});
- it('should set the loadedOnce prop to true when at least one related record is found', () => {
+ it('should set the loaded prop to true when at least one related record is found', () => {
const children = jest.fn().mockReturnValue('child');
renderWithRedux(
@@ -70,7 +70,7 @@ describe('', () => {
expect(children.mock.calls[0][0]).toEqual({
currentSort: { field: 'id', order: 'ASC' },
- loadedOnce: true,
+ loaded: true,
referenceBasePath: '',
data: {
2: {
@@ -109,7 +109,7 @@ describe('', () => {
);
expect(children.mock.calls[0][0]).toEqual({
currentSort: { field: 'id', order: 'ASC' },
- loadedOnce: true,
+ loaded: true,
referenceBasePath: '',
data: {
1: { id: 1, title: 'hello' },
@@ -146,7 +146,7 @@ describe('', () => {
);
expect(children.mock.calls[0][0]).toEqual({
currentSort: { field: 'id', order: 'ASC' },
- loadedOnce: true,
+ loaded: true,
referenceBasePath: '',
data: {
'abc-1': { id: 'abc-1', title: 'hello' },
diff --git a/packages/ra-core/src/controller/field/ReferenceArrayFieldController.tsx b/packages/ra-core/src/controller/field/ReferenceArrayFieldController.tsx
index 14decb7a283..441b2abbec6 100644
--- a/packages/ra-core/src/controller/field/ReferenceArrayFieldController.tsx
+++ b/packages/ra-core/src/controller/field/ReferenceArrayFieldController.tsx
@@ -1,10 +1,10 @@
import { FunctionComponent, ReactNode, ReactElement } from 'react';
-import useReferenceArray from './useReferenceArray';
+import useReferenceArrayFieldController from './useReferenceArrayFieldController';
import { Identifier, RecordMap, Record, Sort } from '../..';
interface ChildrenFuncParams {
- loadedOnce: boolean;
+ loaded: boolean;
ids: Identifier[];
data: RecordMap;
referenceBasePath: string;
@@ -21,36 +21,9 @@ interface Props {
}
/**
- * A container component that fetches records from another resource specified
- * by an array of *ids* in current record.
- *
- * You must define the fields to be passed to the iterator component as children.
- *
- * @example Display all the products of the current order as datagrid
- * // order = {
- * // id: 123,
- * // product_ids: [456, 457, 458],
- * // }
- *
- *
- *
- *
- *
- *
- *
- *
- *
- * @example Display all the categories of the current product as a list of chips
- * // product = {
- * // id: 456,
- * // category_ids: [11, 22, 33],
- * // }
- *
- *
- *
- *
- *
+ * Render prop version of the useReferenceArrayFieldController hook.
*
+ * @see useReferenceArrayFieldController
*/
const ReferenceArrayFieldController: FunctionComponent = ({
resource,
@@ -65,7 +38,7 @@ const ReferenceArrayFieldController: FunctionComponent = ({
field: 'id',
order: 'ASC',
},
- ...useReferenceArray({
+ ...useReferenceArrayFieldController({
resource,
reference,
basePath,
diff --git a/packages/ra-core/src/controller/field/ReferenceManyFieldController.spec.tsx b/packages/ra-core/src/controller/field/ReferenceManyFieldController.spec.tsx
index 1f22d0fa9dc..d1eaad7148a 100644
--- a/packages/ra-core/src/controller/field/ReferenceManyFieldController.spec.tsx
+++ b/packages/ra-core/src/controller/field/ReferenceManyFieldController.spec.tsx
@@ -5,7 +5,7 @@ import ReferenceManyFieldController from './ReferenceManyFieldController';
import renderWithRedux from '../../util/renderWithRedux';
describe('', () => {
- it('should set loadedOnce to false when related records are not yet fetched', () => {
+ it('should set loaded to false when related records are not yet fetched', () => {
const children = jest.fn().mockReturnValue('children');
const { dispatch } = renderWithRedux(
- *
- *
- *
- *
- *
- *
- *
- *
- * @example Display all the books by the current author, only the title
- *
- *
- *
- *
- *
- *
- * By default, restricts the possible values to 25. You can extend this limit
- * by setting the `perPage` prop.
- *
- * @example
- *
- * ...
- *
- *
- * By default, orders the possible values by id desc. You can change this order
- * by setting the `sort` prop (an object with `field` and `order` properties).
- *
- * @example
- *
- * ...
- *
- *
- * Also, you can filter the query used to populate the possible values. Use the
- * `filter` prop for that.
- *
- * @example
- *
- * ...
- *
+ * @see useReferenceManyFieldController
*/
export const ReferenceManyFieldController: FunctionComponent = ({
resource,
@@ -100,10 +59,10 @@ export const ReferenceManyFieldController: FunctionComponent = ({
const {
data,
ids,
- loadedOnce,
+ loaded,
referenceBasePath,
total,
- } = useReferenceMany({
+ } = useReferenceManyFieldController({
resource,
reference,
record,
@@ -120,7 +79,7 @@ export const ReferenceManyFieldController: FunctionComponent = ({
currentSort: sort,
data,
ids,
- loadedOnce,
+ loaded,
page,
perPage,
referenceBasePath,
diff --git a/packages/ra-core/src/controller/field/index.ts b/packages/ra-core/src/controller/field/index.ts
index 341d655ad65..1c5adcfc803 100644
--- a/packages/ra-core/src/controller/field/index.ts
+++ b/packages/ra-core/src/controller/field/index.ts
@@ -2,14 +2,14 @@ import ReferenceArrayFieldController from './ReferenceArrayFieldController';
import ReferenceFieldController from './ReferenceFieldController';
import ReferenceManyFieldController from './ReferenceManyFieldController';
import getResourceLinkPath from './getResourceLinkPath';
-import useReferenceArray from './useReferenceArray';
-import useReferenceMany from './useReferenceMany';
+import useReferenceArrayFieldController from './useReferenceArrayFieldController';
+import useReferenceManyFieldController from './useReferenceManyFieldController';
export {
- useReferenceArray,
+ useReferenceArrayFieldController,
ReferenceArrayFieldController,
ReferenceFieldController,
getResourceLinkPath,
- useReferenceMany,
+ useReferenceManyFieldController,
ReferenceManyFieldController,
};
diff --git a/packages/ra-core/src/controller/field/useReferenceArray.ts b/packages/ra-core/src/controller/field/useReferenceArrayFieldController.ts
similarity index 88%
rename from packages/ra-core/src/controller/field/useReferenceArray.ts
rename to packages/ra-core/src/controller/field/useReferenceArrayFieldController.ts
index b70bb159683..4188845f190 100644
--- a/packages/ra-core/src/controller/field/useReferenceArray.ts
+++ b/packages/ra-core/src/controller/field/useReferenceArrayFieldController.ts
@@ -8,7 +8,7 @@ import { getReferencesByIds } from '../../reducer/admin/references/oneToMany';
import { ReduxState, Record, RecordMap, Identifier } from '../../types';
interface ReferenceArrayProps {
- loadedOnce: boolean;
+ loaded: boolean;
ids: Identifier[];
data: RecordMap;
referenceBasePath: string;
@@ -25,7 +25,7 @@ interface Option {
/**
* @typedef ReferenceArrayProps
* @type {Object}
- * @property {boolean} loadedOnce: boolean indicating if the reference has already beeen loaded
+ * @property {boolean} loaded: boolean indicating if the reference has already beeen loaded
* @property {Array} ids: the list of ids.
* @property {Object} data: Object holding the reference data by their ids
* @property {string} referenceBasePath basePath of the reference
@@ -37,7 +37,7 @@ interface Option {
*
* @example
*
- * const { loadedOnce, data, ids, referenceBasePath, currentSort } = useReferenceArray({
+ * const { loaded, data, ids, referenceBasePath, currentSort } = useReferenceArrayFieldController({
* basePath: 'resource';
* record: { referenceIds: ['id1', 'id2']};
* reference: 'reference';
@@ -56,7 +56,7 @@ interface Option {
*
* @returns {ReferenceProps} The reference props
*/
-const useReferenceArray = ({
+const useReferenceArrayFieldController = ({
resource,
reference,
basePath,
@@ -76,7 +76,7 @@ const useReferenceArray = ({
return {
// eslint-disable-next-line eqeqeq
- loadedOnce: data != undefined,
+ loaded: data != undefined,
ids,
data,
referenceBasePath,
@@ -93,4 +93,4 @@ const getReferenceArray = ({ record, source, reference }) => (
};
};
-export default useReferenceArray;
+export default useReferenceArrayFieldController;
diff --git a/packages/ra-core/src/controller/field/useReferenceMany.ts b/packages/ra-core/src/controller/field/useReferenceManyFieldController.ts
similarity index 93%
rename from packages/ra-core/src/controller/field/useReferenceMany.ts
rename to packages/ra-core/src/controller/field/useReferenceManyFieldController.ts
index f09fc1aa50d..27eb67a1dca 100644
--- a/packages/ra-core/src/controller/field/useReferenceMany.ts
+++ b/packages/ra-core/src/controller/field/useReferenceManyFieldController.ts
@@ -15,7 +15,7 @@ import { Record, Sort, RecordMap, Identifier } from '../../types';
interface ReferenceManyProps {
data: RecordMap;
ids: Identifier[];
- loadedOnce: boolean;
+ loaded: boolean;
referenceBasePath: string;
total: number;
}
@@ -25,7 +25,7 @@ interface Options {
data?: RecordMap;
filter?: any;
ids?: any[];
- loadedOnce?: boolean;
+ loaded?: boolean;
page: number;
perPage: number;
record?: Record;
@@ -44,7 +44,7 @@ const defaultFilter = {};
* @type {Object}
* @property {Object} data: the referenced records dictionary by their ids.
* @property {Object} ids: the list of referenced records ids.
- * @property {boolean} loadedOnce: boolean indicating if the references has already be loaded loaded
+ * @property {boolean} loaded: boolean indicating if the references has already be loaded loaded
* @property {string | false} referenceBasePath base path of the related record
*/
@@ -56,7 +56,7 @@ const defaultFilter = {};
*
* @example
*
- * const { isLoading, referenceRecord, resourceLinkPath } = useReferenceMany({
+ * const { isLoading, referenceRecord, resourceLinkPath } = useReferenceManyFieldController({
* resource
* reference: 'users',
* record: {
@@ -83,7 +83,7 @@ const defaultFilter = {};
*
* @returns {ReferenceManyProps} The reference many props
*/
-const useReferenceMany = ({
+const useReferenceManyFieldController = ({
resource,
reference,
record,
@@ -139,7 +139,7 @@ const useReferenceMany = ({
return {
data,
ids,
- loadedOnce: typeof ids !== 'undefined',
+ loaded: typeof ids !== 'undefined',
referenceBasePath,
total,
};
@@ -177,4 +177,4 @@ const selectData = (reference, relatedTo) => state =>
const selectIds = relatedTo => state => getIds(state, relatedTo);
const selectTotal = relatedTo => state => getTotal(state, relatedTo);
-export default useReferenceMany;
+export default useReferenceManyFieldController;
diff --git a/packages/ra-core/src/controller/input/ReferenceInputController.tsx b/packages/ra-core/src/controller/input/ReferenceInputController.tsx
index e343b3fb034..04042c2cca6 100644
--- a/packages/ra-core/src/controller/input/ReferenceInputController.tsx
+++ b/packages/ra-core/src/controller/input/ReferenceInputController.tsx
@@ -7,11 +7,9 @@ import {
import { WrappedFieldInputProps } from 'redux-form';
import { Sort, Record } from '../../types';
-import useReferenceInput, { ReferenceInputValue } from './useReferenceInput';
-import { filter } from 'async';
-
-const defaultReferenceSource = (resource: string, source: string) =>
- `${resource}@${source}`;
+import useReferenceInputController, {
+ ReferenceInputValue,
+} from './useReferenceInputController';
interface Props {
allowEmpty?: boolean;
@@ -23,7 +21,7 @@ interface Props {
perPage?: number;
record?: Record;
reference: string;
- referenceSource?: typeof defaultReferenceSource;
+ referenceSource?: (resource: string, source: string) => string;
resource: string;
sort?: Sort;
source: string;
@@ -31,107 +29,15 @@ interface Props {
}
/**
- * An Input component for choosing a reference record. Useful for foreign keys.
- *
- * This component fetches the possible values in the reference resource
- * (using the `CRUD_GET_MATCHING` REST method), then delegates rendering
- * to a subcomponent, to which it passes the possible choices
- * as the `choices` attribute.
- *
- * Use it with a selector component as child, like ``,
- * ``, or ``.
- *
- * @example
- * export const CommentEdit = (props) => (
- *
- *
- *
- *
- *
- *
- *
- * );
- *
- * @example
- * export const CommentEdit = (props) => (
- *
- *
- *
- *
- *
- *
- *
- * );
- *
- * By default, restricts the possible values to 25. You can extend this limit
- * by setting the `perPage` prop.
- *
- * @example
- *
- *
- *
- *
- * By default, orders the possible values by id desc. You can change this order
- * by setting the `sort` prop (an object with `field` and `order` properties).
- *
- * @example
- *
- *
- *
- *
- * Also, you can filter the query used to populate the possible values. Use the
- * `filter` prop for that.
- *
- * @example
- *
- *
- *
- *
- * The enclosed component may filter results. ReferenceInput passes a `setFilter`
- * function as prop to its child component. It uses the value to create a filter
- * for the query - by default { q: [searchText] }. You can customize the mapping
- * searchText => searchQuery by setting a custom `filterToQuery` function prop:
+ * Render prop version of the useReferenceInputController hook.
*
- * @example
- * ({ title: searchText })}>
- *
- *
+ * @see useReferenceInputController
*/
export const ReferenceInputController: FunctionComponent = ({
- input,
children,
- perPage = 25,
- filter: permanentFilter = {},
- reference,
- filterToQuery,
- referenceSource = defaultReferenceSource,
- resource,
- source,
+ ...props
}) => {
- return children(
- useReferenceInput({
- input,
- perPage,
- permanentFilter: filter,
- reference,
- filterToQuery,
- referenceSource,
- resource,
- source,
- })
- ) as ReactElement;
+ return children(useReferenceInputController(props)) as ReactElement;
};
export default ReferenceInputController as ComponentType;
diff --git a/packages/ra-core/src/controller/input/index.ts b/packages/ra-core/src/controller/input/index.ts
index 1f2dabd3ab0..2d84189d5da 100644
--- a/packages/ra-core/src/controller/input/index.ts
+++ b/packages/ra-core/src/controller/input/index.ts
@@ -1,4 +1,9 @@
import ReferenceArrayInputController from './ReferenceArrayInputController';
import ReferenceInputController from './ReferenceInputController';
+import useReferenceInputController from './useReferenceInputController';
-export { ReferenceArrayInputController, ReferenceInputController };
+export {
+ ReferenceArrayInputController,
+ ReferenceInputController,
+ useReferenceInputController,
+};
diff --git a/packages/ra-core/src/controller/input/useReferenceInput.ts b/packages/ra-core/src/controller/input/useReferenceInputController.ts
similarity index 90%
rename from packages/ra-core/src/controller/input/useReferenceInput.ts
rename to packages/ra-core/src/controller/input/useReferenceInputController.ts
index 7071737d9c5..09e79f2daf7 100644
--- a/packages/ra-core/src/controller/input/useReferenceInput.ts
+++ b/packages/ra-core/src/controller/input/useReferenceInputController.ts
@@ -11,6 +11,7 @@ import useFilterState from '../useFilterState';
const defaultReferenceSource = (resource: string, source: string) =>
`${resource}@${source}`;
+const defaultFilter = {};
export interface ReferenceInputValue {
choices: Record[];
@@ -27,7 +28,7 @@ export interface ReferenceInputValue {
interface Option {
allowEmpty?: boolean;
- permanentFilter?: any;
+ filter?: any;
filterToQuery?: (filter: string) => any;
input?: WrappedFieldInputProps;
perPage?: number;
@@ -49,7 +50,7 @@ interface Option {
* @example
* const {
* choices, // the available reference resource
- * } = useReferenceInput({
+ * } = useReferenceInputController({
* input, // the input props
* resource: 'comments',
* reference: 'posts',
@@ -66,7 +67,7 @@ interface Option {
* const {
* choices, // the available reference resource
* setFilter,
- * } = useReferenceInput({
+ * } = useReferenceInputController({
* input, // the input props
* resource: 'comments',
* reference: 'posts',
@@ -77,10 +78,10 @@ interface Option {
* filterToQuery: searchText => ({ title: searchText })
* });
*/
-export default ({
+const useReferenceInputController = ({
input,
perPage = 25,
- permanentFilter = {},
+ filter = defaultFilter,
reference,
filterToQuery,
referenceSource = defaultReferenceSource,
@@ -91,15 +92,15 @@ export default ({
const { pagination, setPagination } = usePaginationState({ perPage });
const { sort, setSort } = useSortState();
- const { filter, setFilter } = useFilterState({
- permanentFilter,
+ const { filter: filterValue, setFilter } = useFilterState({
+ permanentFilter: filter,
filterToQuery,
});
const { matchingReferences } = useGetMatchingReferences({
reference,
referenceSource,
- filter,
+ filter: filterValue,
pagination,
sort,
resource,
@@ -124,7 +125,7 @@ export default ({
choices: dataStatus.choices,
error: dataStatus.error,
loading: dataStatus.waiting,
- filter,
+ filter: filterValue,
setFilter,
pagination,
setPagination,
@@ -133,3 +134,5 @@ export default ({
warning: dataStatus.warning,
};
};
+
+export default useReferenceInputController;
diff --git a/packages/ra-core/src/controller/useListController.ts b/packages/ra-core/src/controller/useListController.ts
index 431ce4cac98..cd9063dea22 100644
--- a/packages/ra-core/src/controller/useListController.ts
+++ b/packages/ra-core/src/controller/useListController.ts
@@ -51,7 +51,7 @@ export interface ListControllerProps {
hideFilter: (filterName: string) => void;
ids: Identifier[];
isLoading: boolean;
- loadedOnce: boolean;
+ loaded: boolean;
onSelect: (ids: Identifier[]) => void;
onToggleItem: (id: Identifier) => void;
onUnselectItems: () => void;
@@ -175,7 +175,7 @@ const useListController = (props: ListProps): ListControllerProps => {
hasCreate,
ids,
isLoading: loading,
- loadedOnce: loaded,
+ loaded,
onSelect: selectionModifiers.select,
onToggleItem: selectionModifiers.toggle,
onUnselectItems: selectionModifiers.clearSelection,
@@ -205,7 +205,7 @@ export const injectedProps = [
'hideFilter',
'ids',
'isLoading',
- 'loadedOnce',
+ 'loaded',
'onSelect',
'onToggleItem',
'onUnselectItems',
diff --git a/packages/ra-ui-materialui/src/field/ReferenceArrayField.js b/packages/ra-ui-materialui/src/field/ReferenceArrayField.js
index 0fe53768033..df38144f4eb 100644
--- a/packages/ra-ui-materialui/src/field/ReferenceArrayField.js
+++ b/packages/ra-ui-materialui/src/field/ReferenceArrayField.js
@@ -1,50 +1,10 @@
-import React, { Children } from 'react';
+import React, { Children, cloneElement } from 'react';
import PropTypes from 'prop-types';
import LinearProgress from '@material-ui/core/LinearProgress';
-import { withStyles, createStyles } from '@material-ui/core/styles';
-import { useReferenceArray } from 'ra-core';
+import { makeStyles } from '@material-ui/core/styles';
+import { useReferenceArrayFieldController } from 'ra-core';
import { fieldPropTypes } from './types';
-const styles = createStyles({
- progress: { marginTop: '1em' },
-});
-
-export const ReferenceArrayFieldView = ({
- children,
- className,
- classes = {},
- data,
- ids,
- loadedOnce,
- reference,
- referenceBasePath,
-}) => {
- if (loadedOnce === false) {
- return ;
- }
-
- return React.cloneElement(Children.only(children), {
- className,
- resource: reference,
- ids,
- data,
- loadedOnce,
- basePath: referenceBasePath,
- currentSort: {},
- });
-};
-
-ReferenceArrayFieldView.propTypes = {
- classes: PropTypes.object,
- className: PropTypes.string,
- data: PropTypes.object,
- ids: PropTypes.array,
- loadedOnce: PropTypes.bool,
- children: PropTypes.element.isRequired,
- reference: PropTypes.string.isRequired,
- referenceBasePath: PropTypes.string,
-};
-
/**
* A container component that fetches records from another resource specified
* by an array of *ids* in current record.
@@ -87,38 +47,70 @@ export const ReferenceArrayField = ({ children, ...props }) => {
return (
);
};
ReferenceArrayField.propTypes = {
+ ...fieldPropTypes,
addLabel: PropTypes.bool,
- basePath: PropTypes.string.isRequired,
+ basePath: PropTypes.string,
classes: PropTypes.object,
className: PropTypes.string,
children: PropTypes.element.isRequired,
label: PropTypes.string,
- record: PropTypes.object.isRequired,
+ record: PropTypes.object,
reference: PropTypes.string.isRequired,
- resource: PropTypes.string.isRequired,
+ resource: PropTypes.string,
sortBy: PropTypes.string,
source: PropTypes.string.isRequired,
};
-const EnhancedReferenceArrayField = withStyles(styles)(ReferenceArrayField);
-
-EnhancedReferenceArrayField.defaultProps = {
+ReferenceArrayField.defaultProps = {
addLabel: true,
};
-EnhancedReferenceArrayField.propTypes = {
- ...fieldPropTypes,
- reference: PropTypes.string,
- children: PropTypes.element.isRequired,
+const useStyles = makeStyles(theme => ({
+ progress: { marginTop: theme.spacing(2) },
+}));
+
+export const ReferenceArrayFieldView = ({
+ children,
+ className,
+ classes: classesOverride,
+ data,
+ ids,
+ loaded,
+ reference,
+ referenceBasePath,
+}) => {
+ const classes = useStyles({ classes: classesOverride });
+ if (loaded === false) {
+ return ;
+ }
+
+ return cloneElement(Children.only(children), {
+ className,
+ resource: reference,
+ ids,
+ data,
+ loaded,
+ basePath: referenceBasePath,
+ currentSort: {},
+ });
};
-EnhancedReferenceArrayField.displayName = 'EnhancedReferenceArrayField';
+ReferenceArrayFieldView.propTypes = {
+ classes: PropTypes.object,
+ className: PropTypes.string,
+ data: PropTypes.object,
+ ids: PropTypes.array,
+ loaded: PropTypes.bool,
+ children: PropTypes.element.isRequired,
+ reference: PropTypes.string.isRequired,
+ referenceBasePath: PropTypes.string,
+};
-export default EnhancedReferenceArrayField;
+export default ReferenceArrayField;
diff --git a/packages/ra-ui-materialui/src/field/ReferenceArrayField.spec.js b/packages/ra-ui-materialui/src/field/ReferenceArrayField.spec.js
index d2fc261073c..9edae9b85e8 100644
--- a/packages/ra-ui-materialui/src/field/ReferenceArrayField.spec.js
+++ b/packages/ra-ui-materialui/src/field/ReferenceArrayField.spec.js
@@ -1,13 +1,16 @@
import React from 'react';
-import assert from 'assert';
-import { shallow } from 'enzyme';
+import expect from 'expect';
+import { render, cleanup } from 'react-testing-library';
+import { MemoryRouter } from 'react-router';
+
import { ReferenceArrayFieldView } from './ReferenceArrayField';
import TextField from './TextField';
import SingleFieldList from '../list/SingleFieldList';
describe('', () => {
+ afterEach(cleanup);
it('should render a loading indicator when related records are not yet fetched', () => {
- const wrapper = shallow(
+ const { queryAllByRole } = render(
', () => {
basePath=""
data={null}
ids={[1, 2]}
- loadedOnce={false}
+ loaded={false}
>
);
- const ProgressElements = wrapper.find(
- 'WithStyles(ForwardRef(LinearProgress))'
- );
- assert.equal(ProgressElements.length, 1);
- const SingleFieldListElement = wrapper.find('SingleFieldList');
- assert.equal(SingleFieldListElement.length, 0);
+ expect(queryAllByRole('progressbar')).toHaveLength(1);
});
it('should render a list of the child component', () => {
@@ -36,36 +34,32 @@ describe('', () => {
1: { id: 1, title: 'hello' },
2: { id: 2, title: 'world' },
};
- const wrapper = shallow(
-
-
-
-
-
- );
- const ProgressElements = wrapper.find(
- 'WithStyles(ForwardRef(LinearProgress))'
- );
- assert.equal(ProgressElements.length, 0);
- const SingleFieldListElement = wrapper.find(
- 'WithStyles(SingleFieldList)'
- );
- assert.equal(SingleFieldListElement.length, 1);
- assert.equal(SingleFieldListElement.at(0).prop('resource'), 'bar');
- assert.deepEqual(SingleFieldListElement.at(0).prop('data'), data);
- assert.deepEqual(SingleFieldListElement.at(0).prop('ids'), [1, 2]);
+ const { queryAllByRole, container, getByText } = render(
+
+
+
+
+
+
+
+ );
+ expect(queryAllByRole('progressbar')).toHaveLength(0);
+ expect(container.firstChild.textContent).not.toBeUndefined();
+ expect(getByText('hello')).toBeDefined();
+ expect(getByText('world')).toBeDefined();
});
it('should render nothing when there are no related records', () => {
- const wrapper = shallow(
+ const { queryAllByRole, container } = render(
', () => {
basePath=""
data={{}}
ids={[]}
+ loaded={true}
>
);
- const ProgressElements = wrapper.find(
- 'WithStyles(ForwardRef(LinearProgress))'
- );
- assert.equal(ProgressElements.length, 0);
- const SingleFieldListElement = wrapper.find(
- 'WithStyles(SingleFieldList)'
- );
- assert.equal(SingleFieldListElement.length, 1);
- assert.equal(SingleFieldListElement.at(0).prop('resource'), 'bar');
- assert.deepEqual(SingleFieldListElement.at(0).prop('data'), {});
- assert.deepEqual(SingleFieldListElement.at(0).prop('ids'), []);
+ expect(queryAllByRole('progressbar')).toHaveLength(0);
+ expect(container.firstChild.textContent).toBe('');
});
it('should support record with string identifier', () => {
@@ -98,35 +84,27 @@ describe('', () => {
'abc-1': { id: 'abc-1', title: 'hello' },
'abc-2': { id: 'abc-2', title: 'world' },
};
- const wrapper = shallow(
-
-
-
-
-
- );
- const ProgressElements = wrapper.find(
- 'WithStyles(ForwardRef(LinearProgress))'
- );
- assert.equal(ProgressElements.length, 0);
- const SingleFieldListElement = wrapper.find(
- 'WithStyles(SingleFieldList)'
- );
- assert.equal(SingleFieldListElement.length, 1);
- assert.equal(SingleFieldListElement.at(0).prop('resource'), 'bar');
- assert.deepEqual(SingleFieldListElement.at(0).prop('data'), data);
- assert.deepEqual(SingleFieldListElement.at(0).prop('ids'), [
- 'abc-1',
- 'abc-2',
- ]);
+ const { queryAllByRole, container, getByText } = render(
+
+
+
+
+
+
+
+ );
+ expect(queryAllByRole('progressbar')).toHaveLength(0);
+ expect(container.firstChild.textContent).not.toBeUndefined();
+ expect(getByText('hello')).toBeDefined();
+ expect(getByText('world')).toBeDefined();
});
it('should support record with number identifier', () => {
@@ -134,32 +112,27 @@ describe('', () => {
1: { id: 1, title: 'hello' },
2: { id: 2, title: 'world' },
};
- const wrapper = shallow(
-
-
-
-
-
- );
- const ProgressElements = wrapper.find(
- 'WithStyles(ForwardRef(LinearProgress))'
- );
- assert.equal(ProgressElements.length, 0);
- const SingleFieldListElement = wrapper.find(
- 'WithStyles(SingleFieldList)'
- );
- assert.equal(SingleFieldListElement.length, 1);
- assert.equal(SingleFieldListElement.at(0).prop('resource'), 'bar');
- assert.deepEqual(SingleFieldListElement.at(0).prop('data'), data);
- assert.deepEqual(SingleFieldListElement.at(0).prop('ids'), [1, 2]);
+ const { queryAllByRole, container, getByText } = render(
+
+
+
+
+
+
+
+ );
+ expect(queryAllByRole('progressbar')).toHaveLength(0);
+ expect(container.firstChild.textContent).not.toBeUndefined();
+ expect(getByText('hello')).toBeDefined();
+ expect(getByText('world')).toBeDefined();
});
it('should use custom className', () => {
@@ -167,29 +140,24 @@ describe('', () => {
1: { id: 1, title: 'hello' },
2: { id: 2, title: 'world' },
};
- const wrapper = shallow(
-
-
-
-
-
- );
- const ProgressElements = wrapper.find(
- 'WithStyles(ForwardRef(LinearProgress))'
- );
- assert.equal(ProgressElements.length, 0);
- const SingleFieldListElement = wrapper.find(
- 'WithStyles(SingleFieldList)'
- );
- assert.equal(SingleFieldListElement.at(0).prop('className'), 'myClass');
+ const { container } = render(
+
+
+
+
+
+
+
+ );
+ expect(container.getElementsByClassName('myClass')).toHaveLength(1);
});
});
diff --git a/packages/ra-ui-materialui/src/field/ReferenceField.js b/packages/ra-ui-materialui/src/field/ReferenceField.js
index 2c4b3ec1097..cf10e1329f8 100644
--- a/packages/ra-ui-materialui/src/field/ReferenceField.js
+++ b/packages/ra-ui-materialui/src/field/ReferenceField.js
@@ -1,92 +1,14 @@
-import React, { Children } from 'react';
+import React, { Children, cloneElement } from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
-import { withStyles, createStyles } from '@material-ui/core/styles';
+import get from 'lodash/get';
+import { makeStyles } from '@material-ui/core/styles';
import { useReference, getResourceLinkPath } from 'ra-core';
import LinearProgress from '../layout/LinearProgress';
import Link from '../Link';
import sanitizeRestProps from './sanitizeRestProps';
-const styles = theme =>
- createStyles({
- link: {
- color: theme.palette.primary.main,
- },
- });
-
-// useful to prevent click bubbling in a datagrid with rowClick
-const stopPropagation = e => e.stopPropagation();
-
-export const ReferenceFieldView = ({
- allowEmpty,
- basePath,
- children,
- className,
- classes = {},
- isLoading,
- record,
- reference,
- referenceRecord,
- resource,
- resourceLinkPath,
- source,
- translateChoice = false,
- ...rest
-}) => {
- if (isLoading) {
- return ;
- }
-
- if (resourceLinkPath) {
- return (
-
- {React.cloneElement(Children.only(children), {
- className: classnames(
- children.props.className,
- classes.link // force color override for Typography components
- ),
- record: referenceRecord,
- resource: reference,
- allowEmpty,
- basePath,
- translateChoice,
- ...sanitizeRestProps(rest),
- })}
-
- );
- }
-
- return React.cloneElement(Children.only(children), {
- record: referenceRecord,
- resource: reference,
- allowEmpty,
- basePath,
- translateChoice,
- ...sanitizeRestProps(rest),
- });
-};
-
-ReferenceFieldView.propTypes = {
- allowEmpty: PropTypes.bool,
- basePath: PropTypes.string,
- children: PropTypes.element,
- className: PropTypes.string,
- classes: PropTypes.object,
- isLoading: PropTypes.bool,
- record: PropTypes.object,
- reference: PropTypes.string,
- referenceRecord: PropTypes.object,
- resource: PropTypes.string,
- resourceLinkPath: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
- source: PropTypes.string,
- translateChoice: PropTypes.bool,
-};
-
/**
* Fetch reference record, and delegate rendering to child component.
*
@@ -132,19 +54,22 @@ ReferenceFieldView.propTypes = {
* backward-compatibility is still kept
*/
-const ReferenceField = ({ children, ...props }) => {
+const ReferenceField = ({ children, record, source, ...props }) => {
if (React.Children.count(children) !== 1) {
throw new Error(' only accepts a single child');
}
-
- const { isLoading, referenceRecord } = useReference(props);
+ const id = get(record, source);
+ const { loading, referenceRecord } = useReference({
+ id,
+ ...props,
+ });
const resourceLinkPath = getResourceLinkPath(props);
return (
@@ -180,18 +105,90 @@ ReferenceField.propTypes = {
};
ReferenceField.defaultProps = {
+ addLabel: true,
allowEmpty: false,
classes: {},
link: 'edit',
record: {},
};
-const EnhancedReferenceField = withStyles(styles)(ReferenceField);
+const useStyles = makeStyles(theme => ({
+ link: {
+ color: theme.palette.primary.main,
+ },
+}));
-EnhancedReferenceField.defaultProps = {
- addLabel: true,
+// useful to prevent click bubbling in a datagrid with rowClick
+const stopPropagation = e => e.stopPropagation();
+
+export const ReferenceFieldView = ({
+ allowEmpty,
+ basePath,
+ children,
+ className,
+ classes: classesOverride,
+ loading,
+ record,
+ reference,
+ referenceRecord,
+ resource,
+ resourceLinkPath,
+ source,
+ translateChoice = false,
+ ...rest
+}) => {
+ const classes = useStyles({ classes: classesOverride });
+ if (loading) {
+ return ;
+ }
+
+ if (resourceLinkPath) {
+ return (
+
+ {cloneElement(Children.only(children), {
+ className: classnames(
+ children.props.className,
+ classes.link // force color override for Typography components
+ ),
+ record: referenceRecord,
+ resource: reference,
+ allowEmpty,
+ basePath,
+ translateChoice,
+ ...sanitizeRestProps(rest),
+ })}
+
+ );
+ }
+
+ return cloneElement(Children.only(children), {
+ record: referenceRecord,
+ resource: reference,
+ allowEmpty,
+ basePath,
+ translateChoice,
+ ...sanitizeRestProps(rest),
+ });
};
-EnhancedReferenceField.displayName = 'EnhancedReferenceField';
+ReferenceFieldView.propTypes = {
+ allowEmpty: PropTypes.bool,
+ basePath: PropTypes.string,
+ children: PropTypes.element,
+ className: PropTypes.string,
+ classes: PropTypes.object,
+ loading: PropTypes.bool,
+ record: PropTypes.object,
+ reference: PropTypes.string,
+ referenceRecord: PropTypes.object,
+ resource: PropTypes.string,
+ resourceLinkPath: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
+ source: PropTypes.string,
+ translateChoice: PropTypes.bool,
+};
-export default EnhancedReferenceField;
+export default ReferenceField;
diff --git a/packages/ra-ui-materialui/src/field/ReferenceField.spec.js b/packages/ra-ui-materialui/src/field/ReferenceField.spec.js
index 2af289e8170..21b9cce0477 100644
--- a/packages/ra-ui-materialui/src/field/ReferenceField.spec.js
+++ b/packages/ra-ui-materialui/src/field/ReferenceField.spec.js
@@ -1,30 +1,35 @@
import React from 'react';
-import assert from 'assert';
-import { shallow } from 'enzyme';
+import expect from 'expect';
+import { render } from 'react-testing-library';
+import { MemoryRouter } from 'react-router';
import { ReferenceFieldView } from './ReferenceField';
import TextField from './TextField';
describe('', () => {
it('should render a link to specified resourceLinkPath', () => {
- const wrapper = shallow(
-
-
-
+ const { container } = render(
+
+
+
+
+
);
- const linkElement = wrapper.find('WithStyles(Link)');
- assert.equal(linkElement.prop('to'), '/posts/123');
+ const links = container.getElementsByTagName('a');
+ expect(links).toHaveLength(1);
+ expect(links.item(0).href).toBe('http://localhost/posts/123');
});
+
it('should render no link when resourceLinkPath is not specified', () => {
- const wrapper = shallow(
+ const { container } = render(
', () => {
);
- const linkElement = wrapper.find('WithStyles(Link)');
- assert.equal(linkElement.length, 0);
+ const links = container.getElementsByTagName('a');
+ expect(links).toHaveLength(0);
});
});
diff --git a/packages/ra-ui-materialui/src/field/ReferenceManyField.js b/packages/ra-ui-materialui/src/field/ReferenceManyField.js
index 1a02b542c0c..ff08ea0b87e 100644
--- a/packages/ra-ui-materialui/src/field/ReferenceManyField.js
+++ b/packages/ra-ui-materialui/src/field/ReferenceManyField.js
@@ -1,63 +1,10 @@
import React, { Fragment, cloneElement, Children } from 'react';
import PropTypes from 'prop-types';
-import { useSortState, usePaginationState, useReferenceMany } from 'ra-core';
-
-export const ReferenceManyFieldView = ({
- children,
- className,
- currentSort,
- data,
- ids,
- loadedOnce,
- page,
- pagination,
- perPage,
- reference,
- referenceBasePath,
- setPage,
- setPerPage,
- setSort,
- total,
-}) => (
-
- {cloneElement(Children.only(children), {
- className,
- resource: reference,
- ids,
- loadedOnce,
- data,
- basePath: referenceBasePath,
- currentSort,
- setSort,
- total,
- })}
- {pagination &&
- total !== undefined &&
- cloneElement(pagination, {
- page,
- perPage,
- setPage,
- setPerPage,
- total,
- })}
-
-);
-
-ReferenceManyFieldView.propTypes = {
- children: PropTypes.element,
- className: PropTypes.string,
- currentSort: PropTypes.shape({
- field: PropTypes.string,
- order: PropTypes.string,
- }),
- data: PropTypes.object,
- ids: PropTypes.array,
- loadedOnce: PropTypes.bool,
- pagination: PropTypes.element,
- reference: PropTypes.string,
- referenceBasePath: PropTypes.string,
- setSort: PropTypes.func,
-};
+import {
+ useSortState,
+ usePaginationState,
+ useReferenceManyFieldController,
+} from 'ra-core';
/**
* Render related records to the current one.
@@ -128,7 +75,7 @@ export const ReferenceManyField = props => {
perPage: initialPerPage,
});
- const useReferenceManyProps = useReferenceMany({
+ const controllerProps = useReferenceManyFieldController({
resource,
reference,
record,
@@ -151,7 +98,7 @@ export const ReferenceManyField = props => {
setPage,
setPerPage,
setSort,
- ...useReferenceManyProps,
+ ...controllerProps,
}}
/>
);
@@ -186,4 +133,61 @@ ReferenceManyField.defaultProps = {
addLabel: true,
};
+export const ReferenceManyFieldView = ({
+ children,
+ className,
+ currentSort,
+ data,
+ ids,
+ loaded,
+ page,
+ pagination,
+ perPage,
+ reference,
+ referenceBasePath,
+ setPage,
+ setPerPage,
+ setSort,
+ total,
+}) => (
+
+ {cloneElement(Children.only(children), {
+ className,
+ resource: reference,
+ ids,
+ loaded,
+ data,
+ basePath: referenceBasePath,
+ currentSort,
+ setSort,
+ total,
+ })}
+ {pagination &&
+ total !== undefined &&
+ cloneElement(pagination, {
+ page,
+ perPage,
+ setPage,
+ setPerPage,
+ total,
+ })}
+
+);
+
+ReferenceManyFieldView.propTypes = {
+ children: PropTypes.element,
+ className: PropTypes.string,
+ currentSort: PropTypes.shape({
+ field: PropTypes.string,
+ order: PropTypes.string,
+ }),
+ data: PropTypes.object,
+ ids: PropTypes.array,
+ loaded: PropTypes.bool,
+ pagination: PropTypes.element,
+ reference: PropTypes.string,
+ referenceBasePath: PropTypes.string,
+ setSort: PropTypes.func,
+};
+
export default ReferenceManyField;
diff --git a/packages/ra-ui-materialui/src/input/ReferenceInput.js b/packages/ra-ui-materialui/src/input/ReferenceInput.js
index 44e5d9aca19..b46bd68bb9c 100644
--- a/packages/ra-ui-materialui/src/input/ReferenceInput.js
+++ b/packages/ra-ui-materialui/src/input/ReferenceInput.js
@@ -1,12 +1,127 @@
-import React from 'react';
+import React, { Children, cloneElement } from 'react';
import PropTypes from 'prop-types';
-import compose from 'recompose/compose';
-import { addField, translate, ReferenceInputController } from 'ra-core';
+import { addField, useReferenceInputController } from 'ra-core';
import LinearProgress from '../layout/LinearProgress';
import Labeled from './Labeled';
import ReferenceError from './ReferenceError';
+/**
+ * An Input component for choosing a reference record. Useful for foreign keys.
+ *
+ * This component fetches the possible values in the reference resource
+ * (using the `CRUD_GET_MATCHING` REST method), then delegates rendering
+ * to a subcomponent, to which it passes the possible choices
+ * as the `choices` attribute.
+ *
+ * Use it with a selector component as child, like ``,
+ * ``, or ``.
+ *
+ * @example
+ * export const CommentEdit = (props) => (
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ * );
+ *
+ * @example
+ * export const CommentEdit = (props) => (
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ * );
+ *
+ * By default, restricts the possible values to 25. You can extend this limit
+ * by setting the `perPage` prop.
+ *
+ * @example
+ *
+ *
+ *
+ *
+ * By default, orders the possible values by id desc. You can change this order
+ * by setting the `sort` prop (an object with `field` and `order` properties).
+ *
+ * @example
+ *
+ *
+ *
+ *
+ * Also, you can filter the query used to populate the possible values. Use the
+ * `filter` prop for that.
+ *
+ * @example
+ *
+ *
+ *
+ *
+ * The enclosed component may filter results. ReferenceInput passes a `setFilter`
+ * function as prop to its child component. It uses the value to create a filter
+ * for the query - by default { q: [searchText] }. You can customize the mapping
+ * searchText => searchQuery by setting a custom `filterToQuery` function prop:
+ *
+ * @example
+ * ({ title: searchText })}>
+ *
+ *
+ */
+export const ReferenceInput = props => (
+
+);
+
+ReferenceInput.propTypes = {
+ allowEmpty: PropTypes.bool.isRequired,
+ basePath: PropTypes.string,
+ children: PropTypes.element.isRequired,
+ className: PropTypes.string,
+ classes: PropTypes.object,
+ filter: PropTypes.object,
+ filterToQuery: PropTypes.func.isRequired,
+ input: PropTypes.object.isRequired,
+ label: PropTypes.string,
+ meta: PropTypes.object,
+ onChange: PropTypes.func,
+ perPage: PropTypes.number,
+ record: PropTypes.object,
+ reference: PropTypes.string.isRequired,
+ resource: PropTypes.string.isRequired,
+ sort: PropTypes.shape({
+ field: PropTypes.string,
+ order: PropTypes.oneOf(['ASC', 'DESC']),
+ }),
+ source: PropTypes.string,
+};
+
+ReferenceInput.defaultProps = {
+ allowEmpty: false,
+ filter: {},
+ filterToQuery: searchText => ({ q: searchText }),
+ perPage: 25,
+ sort: { field: 'id', order: 'DESC' },
+};
+
+const EnhancedReferenceInput = addField(ReferenceInput);
+
const sanitizeRestProps = ({
allowEmpty,
basePath,
@@ -39,7 +154,6 @@ const sanitizeRestProps = ({
sort,
source,
textAlign,
- translate,
translateChoice,
validation,
...rest
@@ -64,10 +178,13 @@ export const ReferenceInputView = ({
setPagination,
setSort,
source,
- translate,
warning,
...rest
}) => {
+ if (Children.count(children) !== 1) {
+ throw new Error(' only accepts a single child');
+ }
+
if (loading) {
return (
;
}
- return React.cloneElement(children, {
+ return cloneElement(children, {
allowEmpty,
classes,
className,
@@ -128,141 +245,7 @@ ReferenceInputView.propTypes = {
setPagination: PropTypes.func,
setSort: PropTypes.func,
source: PropTypes.string,
- translate: PropTypes.func.isRequired,
warning: PropTypes.string,
};
-/**
- * An Input component for choosing a reference record. Useful for foreign keys.
- *
- * This component fetches the possible values in the reference resource
- * (using the `CRUD_GET_MATCHING` REST method), then delegates rendering
- * to a subcomponent, to which it passes the possible choices
- * as the `choices` attribute.
- *
- * Use it with a selector component as child, like ``,
- * ``, or ``.
- *
- * @example
- * export const CommentEdit = (props) => (
- *
- *
- *
- *
- *
- *
- *
- * );
- *
- * @example
- * export const CommentEdit = (props) => (
- *
- *
- *
- *
- *
- *
- *
- * );
- *
- * By default, restricts the possible values to 25. You can extend this limit
- * by setting the `perPage` prop.
- *
- * @example
- *
- *
- *
- *
- * By default, orders the possible values by id desc. You can change this order
- * by setting the `sort` prop (an object with `field` and `order` properties).
- *
- * @example
- *
- *
- *
- *
- * Also, you can filter the query used to populate the possible values. Use the
- * `filter` prop for that.
- *
- * @example
- *
- *
- *
- *
- * The enclosed component may filter results. ReferenceInput passes a `setFilter`
- * function as prop to its child component. It uses the value to create a filter
- * for the query - by default { q: [searchText] }. You can customize the mapping
- * searchText => searchQuery by setting a custom `filterToQuery` function prop:
- *
- * @example
- * ({ title: searchText })}>
- *
- *
- */
-export const ReferenceInput = ({ children, ...props }) => {
- if (React.Children.count(children) !== 1) {
- throw new Error(' only accepts a single child');
- }
-
- return (
-
- {controllerProps => (
-
- )}
-
- );
-};
-
-ReferenceInput.propTypes = {
- allowEmpty: PropTypes.bool.isRequired,
- basePath: PropTypes.string,
- children: PropTypes.element.isRequired,
- className: PropTypes.string,
- classes: PropTypes.object,
- filter: PropTypes.object,
- filterToQuery: PropTypes.func.isRequired,
- input: PropTypes.object.isRequired,
- label: PropTypes.string,
- meta: PropTypes.object,
- onChange: PropTypes.func,
- perPage: PropTypes.number,
- record: PropTypes.object,
- reference: PropTypes.string.isRequired,
- resource: PropTypes.string.isRequired,
- sort: PropTypes.shape({
- field: PropTypes.string,
- order: PropTypes.oneOf(['ASC', 'DESC']),
- }),
- source: PropTypes.string,
- translate: PropTypes.func.isRequired,
-};
-
-ReferenceInput.defaultProps = {
- allowEmpty: false,
- filter: {},
- filterToQuery: searchText => ({ q: searchText }),
- perPage: 25,
- sort: { field: 'id', order: 'DESC' },
-};
-
-const EnhancedReferenceInput = compose(
- addField,
- translate
-)(ReferenceInput);
-
export default EnhancedReferenceInput;
diff --git a/packages/ra-ui-materialui/src/input/ReferenceInput.spec.js b/packages/ra-ui-materialui/src/input/ReferenceInput.spec.js
index 1c155367959..d79c59911e8 100644
--- a/packages/ra-ui-materialui/src/input/ReferenceInput.spec.js
+++ b/packages/ra-ui-materialui/src/input/ReferenceInput.spec.js
@@ -12,7 +12,6 @@ describe('', () => {
reference: 'posts',
resource: 'comments',
source: 'post_id',
- translate: x => `*${x}*`,
};
const MyComponent = () => ;
diff --git a/packages/ra-ui-materialui/src/list/Datagrid.js b/packages/ra-ui-materialui/src/list/Datagrid.js
index 4fc93797cfc..9e92efa306b 100644
--- a/packages/ra-ui-materialui/src/list/Datagrid.js
+++ b/packages/ra-ui-materialui/src/list/Datagrid.js
@@ -133,7 +133,7 @@ class Datagrid extends Component {
hover,
ids,
isLoading,
- loadedOnce,
+ loaded,
onSelect,
onToggleItem,
resource,
@@ -147,11 +147,11 @@ class Datagrid extends Component {
} = this.props;
/**
- * if loadedOnce is false, the list displays for the first time, and the dataProvider hasn't answered yet
- * if loadedOnce is true, the data for the list has at least been returned once by the dataProvider
- * if loadedOnce is undefined, the Datagrid parent doesn't track loading state (e.g. ReferenceArrayField)
+ * if loaded is false, the list displays for the first time, and the dataProvider hasn't answered yet
+ * if loaded is true, the data for the list has at least been returned once by the dataProvider
+ * if loaded is undefined, the Datagrid parent doesn't track loading state (e.g. ReferenceArrayField)
*/
- if (loadedOnce === false) {
+ if (loaded === false) {
return (
props;
@@ -65,7 +65,7 @@ export class SingleFieldList extends Component {
className,
ids,
data,
- loadedOnce,
+ loaded,
resource,
basePath,
children,
@@ -73,7 +73,7 @@ export class SingleFieldList extends Component {
...rest
} = this.props;
- if (loadedOnce === false) {
+ if (loaded === false) {
return ;
}
@@ -90,7 +90,7 @@ export class SingleFieldList extends Component {
if (resourceLinkPath) {
return (