import type { ReactNode } from "react";
import type {
RaRecord,
UseReferenceManyFieldControllerParams,
ListControllerResult,
} from "ra-core";
import { ReferenceManyFieldBase, useListContext } from "ra-core";
/**
* Displays multiple related records that reference the current record via a foreign key.
*
* This field fetches records from a related resource where the foreign key points to the current record.
* It provides a ListContext to its children, enabling list rendering with DataTable or custom components.
*
* @see {@link https://marmelab.com/shadcn-admin-kit/docs/referencemanyfield/ ReferenceManyField documentation}
*
* @example
* import { Show, ReferenceManyField, DataTable, DateField, RecordField } from '@/components/admin';
*
* const AuthorShow = () => (
*
*
*
*
*
*
*
*
*
*
*
*
*
*
* );
*/
export const ReferenceManyField = <
RecordType extends RaRecord = RaRecord,
ReferenceRecordType extends RaRecord = RaRecord,
>(
props: ReferenceManyFieldProps,
) => {
const { children, empty, error, loading, pagination, render, ...rest } =
props;
return (
empty={empty}
error={error}
loading={loading}
pagination={pagination}
render={render}
>
{children}
);
};
export interface ReferenceManyFieldProps<
RecordType extends RaRecord = RaRecord,
ReferenceRecordType extends RaRecord = RaRecord,
> extends UseReferenceManyFieldControllerParams<
RecordType,
ReferenceRecordType
>,
ReferenceManyFieldViewProps {}
const ReferenceManyFieldView = <
ReferenceRecordType extends RaRecord = RaRecord,
>(
props: ReferenceManyFieldViewProps,
) => {
const {
children,
empty,
error: errorElement,
loading,
pagination,
render,
} = props;
const listContext = useListContext();
const {
isPending,
error,
total,
hasPreviousPage,
hasNextPage,
data,
filterValues,
} = listContext;
if (isPending && loading !== false) {
return loading;
}
if (error && errorElement !== false) {
return errorElement;
}
if (
(total === 0 ||
(total == null &&
hasPreviousPage === false &&
hasNextPage === false &&
// @ts-expect-error FIXME total may be undefined when using partial pagination but the ListControllerResult type is wrong about it
data.length === 0 &&
// the user didn't set any filters
!Object.keys(filterValues).length)) &&
empty !== false
) {
return empty;
}
return (
<>
{render && render(listContext)}
{children}
{pagination}
>
);
};
export interface ReferenceManyFieldViewProps<
ReferenceRecordType extends RaRecord = RaRecord,
> {
children?: ReactNode;
empty?: ReactNode;
error?: ReactNode;
loading?: ReactNode;
pagination?: ReactNode;
render?: (props: ListControllerResult) => ReactNode;
}