React-Admin - How to log record data to the console? - react-admin

I'd like to know what are the data I'm working with, when using react-admin. (see them in the console to help debug)
For instance, when I'm working with a List:
import React from 'react';
import { Datagrid, List, TextField } from 'react-admin';
import { ListProps } from '../../types/admin/ListProps';
const ProductList = (props: ListProps): JSX.Element => {
console.log('ProductList.props', props);
return (
<List
{...props}
sort={{
field: 'titleEN',
order: 'DESC',
}}
>
<Datagrid rowClick="edit">
<TextField source="title" />
<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" />
</Datagrid>
</List>
);
};
export default ProductList;
How can I do that? I haven't found anything in the official doc https://marmelab.com/react-admin/List.html

This kind of logging can be displayed through the Data Provider. See https://marmelab.com/react-admin/DataProviders.html
For instance, with https://github.com/marcantoine/ra-data-graphql-prisma data provider, one such implementation could be https://github.com/UnlyEd/ra-data-graphql-prisma/commit/4031c5c3f2e97c479a9714df56da06653a908444

Related

How to remove "No results found" label from the list when DataGrid has empty component

const TabbedDatagrid = (props: TabbedDatagridProps) => (
<Datagrid empty={<Empty />}>
<TextField source="id" />
<TextField source="createDate" />
</Datagrid>
);
const Empty = () => {
const { basePath } = useListContext();
return (
<Box textAlign="center" m={1}>
<Typography variant="h4" paragraph>
No products available
</Typography>
<Typography variant="body1">
Create one or import from a file
</Typography>
<CreateButton basePath={basePath} />
<Button>Import</Button>
</Box>
);
};
const MyList = (props: ListProps) => (
<List
{...props}
sort={{ field: 'createDate', order: 'DESC' }}
perPage={10}
filters={orderFilters}
pagination={<PostPagination />}
>
<TabbedDatagrid />
</List>
);
In the result both are displayed, 'No results found" and Empty component
How to display only Empty component?
The <Pagination> component takes a limit prop.
From the React-Admin docs
limit: An element that is displayed if there is no data to show (default: <PaginationLimit>)
You could try passing null <PostPagination limit={null} /> to hide that default "No results found" message.
You can replace these messages with your: Translating The Empty Page

React Admin - Button in the filter component displays twice?

I have implemented a clear button in the filter component. Clear button is working as expected but the button displays twice in the Page.
This is the code
import * as React from 'react';
import { List, Datagrid, TextField, ReferenceField, NumberField, DateField } from 'react-admin';
import { Filter, ReferenceInput, SelectInput, TextInput, DateInput } from 'react-admin';
import Button from '#material-ui/core/Button';
const FilterComponent = props => (
<div>
<Filter {...props} >
<TextInput
label="Search"
source="name"
alwaysOn
/>
<DateInput source="start_date" alwaysOn />
<DateInput source="end_date" alwaysOn />
</Filter>
<Button id="clearButton" variant="outlined" onClick={() => props.setFilters({})}>Clear fields</Button>
</div>
);
export const ProjectList = props => (
<List {...props} filters={<FilterComponent />}>
<Datagrid rowClick="edit">
// Here is the fields
</Datagrid>
</List>
);
But the problem is button displays twice in the filter component
Please share your answers. Thanks in advance
You shall have the Button hide when props.context === 'button'

Display Field in Edit Form

Currently, if I try to place a Field into an Edit form, the field doesn't display at all. There is no errors in the console or the terminal about why it wont.
Example:
<Edit undoable={false} {...props}>
<SimpleForm>
<FormRow>
<TextField source="id"/>
<TextField source="name"/>
</FormRow>
</SimpleForm>
</Edit>
will not display either of these on the page load, it will simply be blank.
Is there any way to use fields in the Edit form?
You need to pass in the record prop (and basePath if its a reference).
The Edit component does not get the record prop so create a form component and it will get passed the record as a prop
eg.
const ProjectEdit: FC<EditComponentProps> = props => {
const classes = useStyles();
return (
<RA.Edit {...props} title={<ProjectTitle />}>
<RA.SimpleForm>
<ProjectForm />
</RA.SimpleForm>
</RA.Edit>
);
};
export const ProjectForm = (props: any) => {
return (
<Box flex={1} mr={{ md: 0, lg: '1em' }}>
<RA.TextInput source="name" fullWidth={true} />
<Typography variant="h6" gutterBottom>
Tasks
</Typography>
<RA.TextField
source="name"
fullWidth={true}
record={props.record}
/>
<RA.ReferenceManyField
label="Tasks"
reference="Task"
target="projectId"
fullWidth={true}
record={props.record}
basePath="/Task"
>
<RA.SingleFieldList fullWidth={true}>
<RA.ChipField source="name" fullWidth={true} />
</RA.SingleFieldList>
</RA.ReferenceManyField>
</Box>
);
};

Cannot style header row for custom field components inside Datagrid

When using a custom field as a child of Datagrid, there appears to be no way to style the column header.
Specifically, I would like to add a left margin to the column header text.
The docs say to use headerClassName, but this has no effect when used with a custom component.
import React from 'react';
import { List, Datagrid, TextField } from 'react-admin';
const TextField = ({ source, record = {} }) => <span>{record[source]}</span>;
export const UserList = (props) => (
<List {...props}>
<Datagrid>
<TextField source="lastName" label="Last Name" />
</Datagrid>
</List>
);
In the code sample, how can I add style to the Last Name column header?
You can use CSS API: https://marmelab.com/react-admin/List.html#the-datagrid-component
Tip: If you want to override the header and cell styles independently for each column, use the headerClassName and cellClassName props in components. For instance, to hide a certain column on small screens:
Example from documentation:
import { withStyles } from '#material-ui/core/styles';
const styles = theme => ({
hiddenOnSmallScreens: {
[theme.breakpoints.down('md')]: {
display: 'none',
},
},
});
const PostList = ({ classes, ...props }) => (
<List {...props}>
<Datagrid>
<TextField source="id" />
<TextField source="title" />
<TextField
source="views"
headerClassName={classes.hiddenOnSmallScreens}
cellClassName={classes.hiddenOnSmallScreens}
/>
</Datagrid>
</List>
);
export default withStyles(styles)(PostList);

How do you conditionally show fields in "Show" component in react-admin?

Some fields I want to only show if they have a value. I would expect to do this like so:
<Show {...props} >
<SimpleShowLayout>
{ props.record.id ? <TextField source="id" />: null }
</SimpleShowLayout>
</Show>
But that doesn't work. I can make it somewhat work by making each field a higher order component, but I wanted to do something cleaner. Here's the HOC method I have:
const exists = WrappedComponent => props => props.record[props.source] ?
<WrappedComponent {...props} />: null;
const ExistsTextField = exists(TextField);
// then in the component:
<Show {...props} >
<SimpleShowLayout>
<ExistsTextField source="id" />
</SimpleShowLayout>
</Show>
This correctly shows the value, but strips the label.
We need to update our documentation about this. In the mean time, you can find informations about how to achieve that in the upgrade guide: https://github.com/marmelab/react-admin/blob/master/UPGRADE.md#aor-dependent-input-was-removed
Here's an example:
import { ShowController, ShowView, SimpleShowLayout, TextField } from 'react-admin';
const UserShow = props => (
<ShowController {...props}>
{controllerProps =>
<ShowView {...props} {...controllerProps}>
<SimpleShowLayout>
<TextField source="username" />
{controllerProps.record && controllerProps.record.hasEmail &&
<TextField source="email" />
}
</SimpleShowLayout>
</ShowView>
}
</ShowController>
);
Maybe this way can be useful
import { FormDataConsumer } from 'react-admin'
<FormDataConsumer>
{
({ formData, ...rest}) => formData.id &&
<>
<ExistsTextField source="id" />
</>
}
</FormDataConsumer>