-
-
Notifications
You must be signed in to change notification settings - Fork 5.3k
/
Copy pathuseReferenceArrayFieldController.ts
124 lines (118 loc) · 3.62 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
116
117
118
119
120
121
122
123
124
import get from 'lodash/get';
import { RaRecord, SortPayload } from '../../types';
import { useGetManyAggregate } from '../../dataProvider';
import { ListControllerResult, useList } from '../list';
import { useNotify } from '../../notification';
import { UseQueryOptions } from '@tanstack/react-query';
export interface UseReferenceArrayFieldControllerParams<
RecordType extends RaRecord = RaRecord,
ReferenceRecordType extends RaRecord = RaRecord,
ErrorType = Error,
> {
filter?: any;
page?: number;
perPage?: number;
record?: RecordType;
reference: string;
resource?: string;
sort?: SortPayload;
source: string;
queryOptions?: Omit<
UseQueryOptions<ReferenceRecordType[], ErrorType>,
'queryFn' | 'queryKey'
>;
}
const emptyArray = [];
const defaultFilter = {};
/**
* Hook that fetches records from another resource specified
* by an array of *ids* in current record.
*
* @example
*
* const { data, error, isFetching, isPending } = 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,
ErrorType = Error,
>(
props: UseReferenceArrayFieldControllerParams<
RecordType,
ReferenceRecordType,
ErrorType
>
): ListControllerResult<ReferenceRecordType, ErrorType> => {
const {
filter = defaultFilter,
page = 1,
perPage = 1000,
record,
reference,
sort,
source,
queryOptions = {},
} = props;
const notify = useNotify();
const value = get(record, source);
const { meta, ...otherQueryOptions } = queryOptions;
const ids = Array.isArray(value) ? value : emptyArray;
const { data, error, isLoading, isFetching, isPending, refetch } =
useGetManyAggregate<ReferenceRecordType, ErrorType>(
reference,
{ ids, meta },
{
onError: error =>
notify(
typeof error === 'string'
? error
: (error as Error)?.message ||
'ra.notification.http_error',
{
type: 'error',
messageArgs: {
_:
typeof error === 'string'
? error
: (error as Error)?.message
? (error as Error).message
: undefined,
},
}
),
...otherQueryOptions,
}
);
const listProps = useList<ReferenceRecordType, ErrorType>({
data,
error,
filter,
isFetching,
isLoading,
isPending,
page,
perPage,
sort,
});
return {
...listProps,
defaultTitle: undefined,
refetch,
resource: reference,
};
};