import * as React from 'react'; import { useNavigate } from '../routing'; import type { RaRecord } from '../types'; import { useResourceContext } from '../core/useResourceContext'; import { useRecordContext } from '../controller/record/useRecordContext'; import { RecordContextProvider } from '../controller/record/RecordContext'; import { useListContext } from '../controller/list/useListContext'; import { useFieldValue } from '../util/useFieldValue'; import { useEvent } from '../util/useEvent'; import { useGetPathForRecordCallback } from '../routing/useGetPathForRecordCallback'; import { useDataTableSelectedIdsContext } from '../dataTable/DataTableSelectedIdsContext'; import { useDataTableRenderContext, DataTableRenderContext, } from '../dataTable/DataTableRenderContext'; import { useDataTableConfigContext } from '../dataTable/DataTableConfigContext'; import { useDataTableCallbacksContext } from '../dataTable/DataTableCallbacksContext'; import { DataTableBase, DataTableBaseProps } from '../dataTable/DataTableBase'; const DataTableCol = (props: { children?: React.ReactNode; render?: (record: RaRecord) => React.ReactNode; field?: React.ElementType; source?: string; label?: React.ReactNode; }) => { const renderContext = useDataTableRenderContext(); switch (renderContext) { case 'header': return ; case 'data': return ; } }; const DataTableHeadCell = (props: { label?: React.ReactNode; source?: string; }) => { return ( {props.label ?? ( <> {props.source?.substring(0, 1).toUpperCase()} {props.source?.substring(1)} )} ); }; const DataTableCell = (props: { children?: React.ReactNode; render?: (record: RaRecord | undefined) => React.ReactNode; field?: React.ElementType; source?: string; }) => { const record = useRecordContext(); if (props.render) { return {props.render(record)}; } if (props.children) { return {props.children}; } if (props.field) { return ( {React.createElement(props.field, { source: props.source })} ); } if (props.source) { return ( ); } }; const DataTableCellValue = (props: { source: string }) => { const value = useFieldValue(props); return <>{value?.toString()}; }; const DataTableRow = (props: { children: React.ReactNode; record?: RaRecord; resource?: string; }) => { const getPathForRecord = useGetPathForRecordCallback(); const navigate = useNavigate(); const record = useRecordContext(props); if (!record) { throw new Error( 'DataTableRow can only be used within a RecordContext or be passed a record prop' ); } const resource = useResourceContext(props); if (!resource) { throw new Error( 'DataTableRow can only be used within a ResourceContext or be passed a resource prop' ); } const { hasBulkActions = false } = useDataTableConfigContext(); const { handleToggleItem, rowClick } = useDataTableCallbacksContext(); const selectedIds = useDataTableSelectedIdsContext(); const handleClick = useEvent(async (event: React.MouseEvent) => { event.persist(); const temporaryLink = typeof rowClick === 'function' ? rowClick(record.id, resource, record) : rowClick; const link = isPromise(temporaryLink) ? await temporaryLink : temporaryLink; const path = await getPathForRecord({ record, resource, link, }); if (path === false || path == null) { return; } navigate(path, { state: { _scrollToTop: true }, }); }); return ( {hasBulkActions && ( handleToggleItem!(record.id, event)} /> )} {props.children} ); }; const isPromise = (value: any): value is Promise => value && typeof value.then === 'function'; export const DataTable = ( props: Omit & { hasBulkActions?: boolean; } ) => { const { data } = useListContext(); return ( {props.hasBulkActions ? : null} {props.children} {data?.map(record => ( {props.children} ))}
); }; DataTable.Col = DataTableCol;