ra-core
Version:
Core components of react-admin, a frontend Framework for building admin applications on top of REST services, using ES6, React
120 lines • 5.47 kB
JavaScript
import * as React from 'react';
import { useRecordContext } from '../record';
import { useReferenceArrayFieldController } from './useReferenceArrayFieldController';
import { ResourceContextProvider } from '../../core';
import { ListContextProvider } from '../list';
/**
* 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 var ReferenceArrayFieldBase = function (props) {
var children = props.children, render = props.render, error = props.error, loading = props.loading, empty = props.empty, filter = props.filter, offline = props.offline, _a = props.page, page = _a === void 0 ? 1 : _a, perPage = props.perPage, reference = props.reference, resource = props.resource, sort = props.sort, source = props.source, queryOptions = props.queryOptions;
var record = useRecordContext(props);
var controllerProps = useReferenceArrayFieldController({
filter: filter,
page: page,
perPage: perPage,
record: record,
reference: reference,
resource: resource,
sort: sort,
source: source,
queryOptions: queryOptions,
});
if (!render && !children) {
throw new Error("<ReferenceArrayFieldBase> requires either a 'render' prop or 'children' prop");
}
var controllerError = controllerProps.error, isPending = controllerProps.isPending, isPaused = controllerProps.isPaused, isPlaceholderData = controllerProps.isPlaceholderData;
var shouldRenderLoading = isPending && !isPaused && loading !== undefined && loading !== false;
var shouldRenderOffline = isPaused &&
(isPending || isPlaceholderData) &&
offline !== undefined &&
offline !== false;
var shouldRenderError = !isPending &&
!isPaused &&
controllerError &&
error !== undefined &&
error !== false;
var 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