Reputation: 17997
I'm trying to conditionally display a ChipField
component in a react-admin
List view. It's similar to How do you conditionally show fields in "Show" component in react-admin? but for list, and I haven't found a working way when using a list.
import React from 'react';
import { ChipField, Datagrid, ImageField, List, ListController, TextField } from 'react-admin';
import { ListProps } from '../../types/admin/ListProps';
import ProductBulkActionButtons from './ProductBulkActionButtons';
const ProductList = (props: ListProps): JSX.Element => {
console.debug('ProductList.props', props);
return (
<ListController {...props}>
{(controllerProps) => {
console.debug('ProductList.controllerProps', controllerProps);
return (
<List
{...props}
{...controllerProps}
sort={{
field: 'titleEN',
order: 'DESC',
}}
bulkActionButtons={<ProductBulkActionButtons />}
>
<Datagrid rowClick="edit">
<ImageField source={'images[0].url'} title={'images[0]title'} label={'Image'} />
<TextField source="titleEN" label={'Title (EN)'} />
<TextField source="titleFR" label={'Title (FR)'} />
{/*<ArrayField source="images"><SingleFieldList><ChipField source="id" /></SingleFieldList></ArrayField>*/}
{/*<ReferenceArrayField source="imagesIds" reference="images"><TextField source="id" /></ReferenceArrayField>*/}
<TextField source="customer.label" label={'Customer'} />
<TextField source="price" />
<ChipField source="status" color={'primary'} />
</Datagrid>
</List>
);
}}
</ListController>
);
};
export default ProductList;
What I'd like to do, is to use another color
when the status
is DRAFT
. Currently, it uses the primary
color for all records.
<ChipField source="status" color={'primary'} />
I tried using a similar method to https://stackoverflow.com/a/51068735/2391795, but I could only access the whole data
and not control per-row rendering.
Interactive demo at https://nrn-admin-display-product-status.now.sh/#/Product
Upvotes: 3
Views: 1755
Reputation: 731
A late joiner to the party, but this is an example TypeScript (in my case, a component StatusChip.tsx), which I then refer to with import { StatusChip } from './components/StatusChip';
and then have <StatusChip source="status" label="Status" />
in my BookingList.
import { ChipField, ChipFieldProps, useRecordContext } from 'react-admin';
interface StatusChipProps extends ChipFieldProps {
record?: { status: string };
}
const statusColours: Record<string, string> = {
confirmed: '#a5d6a7', // Soft green
pending: '#ffcc80', // Soft orange
cancelled: '#ef9a9a', // Soft red
other: '#e0e0e0', // Light grey for any unspecified status
}
export const StatusChip = (props: StatusChipProps) => {
const record = useRecordContext<{ status?: string }>();
const colour = record && record.status && statusColours[record.status] ? statusColours[record.status] : statusColours['other'];
return (
<ChipField
{...props}
source="status"
sx={{
backgroundColor: colour,
color: 'black',
}}
/>
);
};
Upvotes: 0
Reputation: 37318
According to Conditional Formatting, you have to create a component to replace the field component and pass the props
to it. Then you can control the source
and the record
props.
You can change the color of the ChipField
by creating a class with backgroundColor
to the color you want and apply it to the className
prop.
<ChipField>
the DRAFT
status:import { makeStyles } from '@material-ui/core/styles';
import classnames from 'classnames';
const useStyles = makeStyles({
draft: { backgroundColor: '#74fd74' },
});
const ColoredChipField = props => {
const classes = useStyles();
const isDraft = v => v.toUpperCase() === 'DRAFT';
return (
<ChipField
className={classnames({
[classes.draft]: isDraft(props.record[props.source]),
})}
{...props}
/>
);
};
and then use it like this:
(
<List {...props}>
<Datagrid rowClick="edit">
<TextField source="titleEN" label="Title (EN)"/>
<TextField source="titleFR" label="Title (FR)"/>
<ColoredChipField source="status" color="primary"/>
</Datagrid>
</List>
);
Please check this working Stackblitz:
Upvotes: 4