Skip to content

Commit e144cd1

Browse files
committed
ReferenceOneField accept sort & filter props
1 parent 74eff39 commit e144cd1

File tree

4 files changed

+55
-12
lines changed

4 files changed

+55
-12
lines changed

docs/ReferenceOneField.md

+29-5
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,37 @@ const BookShow = () => (
4747

4848
**Tip**: As with `<ReferenceField>`, you can call `<ReferenceOneField>` as many times as you need in the same component, react-admin will only make one call to `dataProvider.getManyReference()` per reference.
4949

50+
**Tip**: `<ReferenceOneField>` can also be used to display one record of a one-to-many relationship. Use `sort` and/or `filter` props to select the appropriate record to display. The first record will be displayed.
51+
52+
```jsx
53+
const BookShow = () => (
54+
<Show>
55+
<SimpleShowLayout>
56+
<TextField source="title" />
57+
<DateField source="published_at" />
58+
<ReferenceOneField
59+
label="Latest cool review"
60+
reference="book_reviews"
61+
target="book_id"
62+
sort={{ field: "createdAt", order: "DESC" }}
63+
filter={{ rating: 5 }}
64+
>
65+
<TextField source="title" />
66+
</ReferenceOneField>
67+
</SimpleShowLayout>
68+
</Show>
69+
);
70+
```
71+
5072
## Properties
5173

5274
| Prop | Required | Type | Default | Description |
53-
| ------------ | -------- | ------------------ | -------------------------------- | ----------------------------------------------------------------------------------- |
54-
| `children` | Optional | `Element` | - | The Field element used to render the referenced record |
55-
| `link` | Optional | `string | Function` | `edit` | Target of the link wrapping the rendered child. Set to `false` to disable the link. |
56-
| `reference` | Required | `string` | - | The name of the resource for the referenced records, e.g. 'book_details' |
57-
| `target` | Required | string | - | Target field carrying the relationship on the referenced resource, e.g. 'book_id' |
75+
| ------------ | -------- | ------------------------------------------- | -------------------------------- | ----------------------------------------------------------------------------------- |
76+
| `children` | Optional | `Element` | - | The Field element used to render the referenced record |
77+
| `link` | Optional | `string | Function` | `edit` | Target of the link wrapping the rendered child. Set to `false` to disable the link. |
78+
| `reference` | Required | `string` | - | The name of the resource for the referenced records, e.g. 'book_details' |
79+
| `target` | Required | string | - | Target field carrying the relationship on the referenced resource, e.g. 'book_id' |
80+
| `sort` | Optional | `{ field: String, order: 'ASC' or 'DESC' }` | `{ field: 'id', order: 'ASC' }` | Used to order referenced records |
81+
| `filter` | Optional | `Object` | `{}` | Used to filter referenced records |
5882

5983
`<ReferenceOneField>` also accepts the [common field props](./Fields.md#common-field-props), except `emptyText` (use the child `empty` prop instead).

packages/ra-core/src/controller/field/useReferenceOneFieldController.spec.tsx

+4-2
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ describe('useReferenceOneFieldController', () => {
9090
record={{ id: 123, name: 'James Joyce' }}
9191
reference="bios"
9292
target="author_id"
93+
sort={{ field: 'name', order: 'DESC' }}
94+
filter={{ gender: 'female' }}
9395
>
9496
{() => 'null'}
9597
</ReferenceOneFieldController>
@@ -101,8 +103,8 @@ describe('useReferenceOneFieldController', () => {
101103
target: 'author_id',
102104
id: 123,
103105
pagination: { page: 1, perPage: 1 },
104-
sort: { field: 'id', order: 'ASC' },
105-
filter: {},
106+
sort: { field: 'name', order: 'DESC' },
107+
filter: { gender: 'female' },
106108
});
107109
});
108110
});

packages/ra-core/src/controller/field/useReferenceOneFieldController.tsx

+15-5
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,16 @@ import get from 'lodash/get';
22

33
import { useGetManyReference } from '../../dataProvider';
44
import { useNotify } from '../../notification';
5-
import { RaRecord } from '../../types';
5+
import { RaRecord, SortPayload } from '../../types';
66
import { UseReferenceResult } from '../useReference';
77

88
export interface UseReferenceOneFieldControllerParams {
99
record?: RaRecord;
1010
reference: string;
1111
source?: string;
1212
target: string;
13+
sort?: SortPayload;
14+
filter?: any;
1315
}
1416

1517
/**
@@ -31,13 +33,21 @@ export interface UseReferenceOneFieldControllerParams {
3133
* @prop {string} props.reference The linked resource name
3234
* @prop {string} props.target The target resource key
3335
* @prop {string} props.source The key current record identifier ('id' by default)
34-
*
36+
* @prop {Object} props.sort The sort to apply to the referenced records
37+
* @prop {Object} props.filter The filter to apply to the referenced records
3538
* @returns {UseReferenceResult} The request state. Destructure as { referenceRecord, isLoading, error }.
3639
*/
3740
export const useReferenceOneFieldController = (
3841
props: UseReferenceOneFieldControllerParams
3942
): UseReferenceResult => {
40-
const { reference, record, target, source = 'id' } = props;
43+
const {
44+
reference,
45+
record,
46+
target,
47+
source = 'id',
48+
sort = { field: 'id', order: 'ASC' },
49+
filter = {},
50+
} = props;
4151
const notify = useNotify();
4252

4353
const { data, error, isFetching, isLoading, refetch } = useGetManyReference(
@@ -46,8 +56,8 @@ export const useReferenceOneFieldController = (
4656
target,
4757
id: get(record, source),
4858
pagination: { page: 1, perPage: 1 },
49-
sort: { field: 'id', order: 'ASC' },
50-
filter: {},
59+
sort,
60+
filter,
5161
},
5262
{
5363
enabled: !!record,

packages/ra-ui-materialui/src/field/ReferenceOneField.tsx

+7
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
LinkToType,
99
useCreatePath,
1010
useTranslate,
11+
SortPayload,
1112
} from 'ra-core';
1213

1314
import { PublicFieldProps, fieldPropTypes, InjectedFieldProps } from './types';
@@ -30,6 +31,8 @@ export const ReferenceOneField = (props: ReferenceOneFieldProps) => {
3031
source,
3132
target,
3233
emptyText,
34+
sort,
35+
filter,
3336
link = false,
3437
} = props;
3538
const record = useRecordContext(props);
@@ -47,6 +50,8 @@ export const ReferenceOneField = (props: ReferenceOneFieldProps) => {
4750
reference,
4851
source,
4952
target,
53+
sort,
54+
filter,
5055
});
5156

5257
const resourceLinkPath =
@@ -90,6 +95,8 @@ export interface ReferenceOneFieldProps
9095
children?: ReactNode;
9196
reference: string;
9297
target: string;
98+
sort?: SortPayload;
99+
filter?: any;
93100
link?: LinkToType;
94101
}
95102

0 commit comments

Comments
 (0)