UNPKG

ra-core

Version:

Core components of react-admin, a frontend Framework for building admin applications on top of REST services, using ES6, React

142 lines 6.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.useReferenceArrayInputController = void 0; const react_1 = require("react"); const react_hook_form_1 = require("react-hook-form"); const dataProvider_1 = require("../../dataProvider/index.cjs"); const useReferenceParams_1 = require("./useReferenceParams.cjs"); const core_1 = require("../../core/index.cjs"); /** * Prepare data for the ReferenceArrayInput components * * @example * * const { allChoices, availableChoices, selectedChoices, error, isFetching, isLoading, isPending } = useReferenceArrayInputController({ * 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 * * @return {Object} controllerProps Fetched data and callbacks for the ReferenceArrayInput components */ const useReferenceArrayInputController = (props) => { const { debounce, enableGetChoices, filter, page: initialPage = 1, perPage: initialPerPage = 25, sort: initialSort = { field: 'id', order: 'DESC' }, queryOptions = {}, reference, source, } = props; const { getValues } = (0, react_hook_form_1.useFormContext)(); const finalSource = (0, core_1.useWrappedSource)(source); // When we change the defaultValue of the child input using react-hook-form resetField function, // useWatch does not seem to get the new value. We fallback to getValues to get it. const value = (0, react_hook_form_1.useWatch)({ name: finalSource }) ?? getValues(finalSource); const { meta, ...otherQueryOptions } = queryOptions; /** * Get the records related to the current value (with getMany) */ const { data: referenceRecords, error: errorGetMany, isLoading: isLoadingGetMany, isFetching: isFetchingGetMany, isPaused: isPausedGetMany, isPending: isPendingGetMany, isPlaceholderData: isPlaceholderDataGetMany, refetch: refetchGetMany, } = (0, dataProvider_1.useGetManyAggregate)(reference, { ids: value || EmptyArray, meta, }, { enabled: value != null && value.length > 0, }); const [params, paramsModifiers] = (0, useReferenceParams_1.useReferenceParams)({ resource: reference, page: initialPage, perPage: initialPerPage, sort: initialSort, debounce, filter, }); // filter out not found references - happens when the dataProvider doesn't guarantee referential integrity const finalReferenceRecords = referenceRecords ? referenceRecords.filter(Boolean) : []; const isGetMatchingEnabled = enableGetChoices ? enableGetChoices(params.filterValues) : true; const { data: matchingReferences, total, pageInfo, error: errorGetList, isLoading: isLoadingGetList, isFetching: isFetchingGetList, isPaused: isPausedGetList, isPending: isPendingGetList, isPlaceholderData: isPlaceholderDataGetList, refetch: refetchGetMatching, } = (0, dataProvider_1.useGetList)(reference, { pagination: { page: params.page, perPage: params.perPage, }, sort: { field: params.sort, order: params.order }, filter: { ...params.filter, ...filter }, meta, }, { retry: false, enabled: isGetMatchingEnabled, placeholderData: previousData => previousData, ...otherQueryOptions, }); // We merge the currently selected records with the matching ones, otherwise // the component displaying the currently selected records may fail const finalMatchingReferences = matchingReferences && matchingReferences.length > 0 ? mergeReferences(matchingReferences, finalReferenceRecords) : finalReferenceRecords.length > 0 ? finalReferenceRecords : matchingReferences; const refetch = (0, react_1.useCallback)(() => { refetchGetMany(); refetchGetMatching(); }, [refetchGetMany, refetchGetMatching]); const currentSort = (0, react_1.useMemo)(() => ({ field: params.sort, order: params.order, }), [params.sort, params.order]); return { sort: currentSort, allChoices: finalMatchingReferences, availableChoices: matchingReferences, selectedChoices: finalReferenceRecords, displayedFilters: params.displayedFilters, error: errorGetMany || errorGetList, filter, filterValues: params.filterValues, hideFilter: paramsModifiers.hideFilter, isFetching: isFetchingGetMany || isFetchingGetList, isLoading: isLoadingGetMany || isLoadingGetList, isPaused: isPausedGetMany || isPausedGetList, isPending: isPendingGetMany || isPendingGetList, isPlaceholderData: isPlaceholderDataGetMany || isPlaceholderDataGetList, page: params.page, perPage: params.perPage, refetch, resource: reference, setFilters: paramsModifiers.setFilters, setPage: paramsModifiers.setPage, setPerPage: paramsModifiers.setPerPage, setSort: paramsModifiers.setSort, showFilter: paramsModifiers.showFilter, // we return source and not finalSource because child inputs (e.g. AutocompleteArrayInput) already call useInput and compute the final source source, total: total, hasNextPage: pageInfo ? pageInfo.hasNextPage : total != null ? params.page * params.perPage < total : undefined, hasPreviousPage: pageInfo ? pageInfo.hasPreviousPage : params.page > 1, isFromReference: true, }; }; exports.useReferenceArrayInputController = useReferenceArrayInputController; const EmptyArray = []; // concatenate and deduplicate two lists of records const mergeReferences = (ref1, ref2) => { const res = [...ref1]; const ids = ref1.map(ref => ref.id); ref2.forEach(ref => { if (!ids.includes(ref.id)) { ids.push(ref.id); res.push(ref); } }); return res; }; //# sourceMappingURL=useReferenceArrayInputController.js.map