-
-
Notifications
You must be signed in to change notification settings - Fork 5.3k
/
Copy pathuseReferenceArrayFieldController.ts
115 lines (108 loc) · 3.17 KB
/
useReferenceArrayFieldController.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import get from 'lodash/get';
import { useMemo } from 'react';
import { RaRecord, SortPayload } from '../../types';
import { useGetManyAggregate } from '../../dataProvider';
import { ListControllerResult, useList } from '../list';
import { useNotify } from '../../notification';
export interface UseReferenceArrayFieldControllerParams<
RecordType extends RaRecord = RaRecord
> {
filter?: any;
page?: number;
perPage?: number;
record?: RecordType;
reference: string;
resource: string;
sort?: SortPayload;
source: string;
}
const emptyArray = [];
const defaultFilter = {};
const defaultSort = { field: null, order: null };
/**
* Hook that fetches records from another resource specified
* by an array of *ids* in current record.
*
* @example
*
* const { data, error, isFetching, isLoading } = useReferenceArrayFieldController({
* record: { referenceIds: ['id1', 'id2']};
* reference: 'reference';
* resource: 'resource';
* source: 'referenceIds';
* });
*
* @param {Object} props
* @param {Object} props.record The current resource record
* @param {string} props.reference The linked resource name
* @param {string} props.resource The current resource name
* @param {string} props.source The key of the linked resource identifier
*
* @param {Props} props
*
* @returns {ListControllerResult} The reference props
*/
export const useReferenceArrayFieldController = <
RecordType extends RaRecord = RaRecord,
ReferenceRecordType extends RaRecord = RaRecord
>(
props: UseReferenceArrayFieldControllerParams<RecordType>
): ListControllerResult => {
const {
filter = defaultFilter,
page = 1,
perPage = 1000,
record,
reference,
sort = defaultSort,
source,
} = props;
const notify = useNotify();
const value = get(record, source);
const ids = useMemo(() => {
if (Array.isArray(value)) return value;
console.warn(`Value of field '${source}' is not an array.`, value);
return emptyArray;
}, [value, source]);
const { data, error, isLoading, isFetching, refetch } = useGetManyAggregate<
ReferenceRecordType
>(
reference,
{ ids },
{
onError: error =>
notify(
typeof error === 'string'
? error
: error.message || 'ra.notification.http_error',
{
type: 'error',
messageArgs: {
_:
typeof error === 'string'
? error
: error && error.message
? error.message
: undefined,
},
}
),
}
);
const listProps = useList<ReferenceRecordType>({
data,
error,
filter,
isFetching,
isLoading,
page,
perPage,
sort,
});
return {
...listProps,
defaultTitle: null,
refetch,
resource: reference,
};
};