UNPKG

ra-core

Version:

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

121 lines 5.15 kB
import * as React from 'react'; import { useRecordContext } from "../record/index.js"; import { useReferenceArrayFieldController } from "./useReferenceArrayFieldController.js"; import { ResourceContextProvider } from "../../core/index.js"; import { ListContextProvider } from "../list/index.js"; /** * 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], * // } * <ReferenceArrayFieldBase label="Products" reference="products" source="product_ids"> * <Datagrid> * <TextField source="id" /> * <TextField source="description" /> * <NumberField source="price" options={{ style: 'currency', currency: 'USD' }} /> * <EditButton /> * </Datagrid> * </ReferenceArrayFieldBase> * * @example Display all the categories of the current product as a list of chips * // product = { * // id: 456, * // category_ids: [11, 22, 33], * // } * <ReferenceArrayFieldBase label="Categories" reference="categories" source="category_ids"> * <SingleFieldList> * <ChipField source="name" /> * </SingleFieldList> * </ReferenceArrayFieldBase> * * By default, restricts the displayed values to 1000. You can extend this limit * by setting the `perPage` prop. * * @example * <ReferenceArrayFieldBase perPage={10} reference="categories" source="category_ids"> * ... * </ReferenceArrayFieldBase> * * By default, the field displays the results in the order in which they are referenced * (i.e. in the order of the list of ids). You can change this order * by setting the `sort` prop (an object with `field` and `order` properties). * * @example * <ReferenceArrayFieldBase sort={{ field: 'name', order: 'ASC' }} reference="categories" source="category_ids"> * ... * </ReferenceArrayFieldBase> * * Also, you can filter the results to display only a subset of values. Use the * `filter` prop for that. * * @example * <ReferenceArrayFieldBase filter={{ is_published: true }} reference="categories" source="category_ids"> * ... * </ReferenceArrayFieldBase> */ export const ReferenceArrayFieldBase = (props) => { const { children, render, error, loading, empty, filter, exporter, offline, page = 1, perPage, reference, resource, sort, source, queryOptions, } = props; const record = useRecordContext(props); const controllerProps = useReferenceArrayFieldController({ filter, exporter, page, perPage, record, reference, resource, sort, source, queryOptions, }); if (!render && !children) { throw new Error("<ReferenceArrayFieldBase> requires either a 'render' prop or 'children' prop"); } const { error: controllerError, isPending, isPaused, isPlaceholderData, } = controllerProps; const shouldRenderLoading = isPending && !isPaused && loading !== undefined && loading !== false; const shouldRenderOffline = isPaused && (isPending || isPlaceholderData) && offline !== undefined && offline !== false; const shouldRenderError = !isPending && !isPaused && controllerError && error !== undefined && error !== false; const shouldRenderEmpty = // there is an empty page component empty && // there is no error !controllerProps.error && // the list is not loading data for the first time !controllerProps.isPending && // the API returned no data (using either normal or partial pagination) (controllerProps.total === 0 || (controllerProps.total == null && // @ts-ignore FIXME total may be undefined when using partial pagination but the ListControllerResult type is wrong about it controllerProps.hasPreviousPage === false && // @ts-ignore FIXME total may be undefined when using partial pagination but the ListControllerResult type is wrong about it controllerProps.hasNextPage === false && // @ts-ignore FIXME total may be undefined when using partial pagination but the ListControllerResult type is wrong about it controllerProps.data.length === 0)) && // the user didn't set any filters !Object.keys(controllerProps.filterValues).length; return (React.createElement(ResourceContextProvider, { value: reference }, React.createElement(ListContextProvider, { value: controllerProps }, shouldRenderLoading ? loading : shouldRenderOffline ? offline : shouldRenderError ? error : shouldRenderEmpty ? empty : render ? render(controllerProps) : children))); }; //# sourceMappingURL=ReferenceArrayFieldBase.js.map