Bulk action in admin-on-rest - reactjs

I used bulkActions props for Admin-on-rest List but don't show anything when I select rows. How to can I use the bulk action?
const AccountingBulkActions = props => (
<BulkActions {...props}>
<BulkDeleteAction />
</BulkActions>
);
export const AccountingList = (props) => (
<List
{...props}
bulkActions={<AccountingBulkActions />}
title="Accounting">
<Datagrid
headerOptions={{ adjustForCheckbox: true, displaySelectAll: true }}
bodyOptions={{ displayRowCheckbox: true }}
rowOptions={{ selectable: true }}
options={{ multiSelectable: true }}>
<DateField source="createdAt" />
<TypeLabel source="type" />
<GenderLabel source="gender" />
<NumberField source="paymentPrice" />
<NumberField source="totalPrice" />
</Datagrid>
</List>
);

Bulk actions are a new feature only available on react-admin. You'll have to upgrade your admin-in-rest app.

Related

Show issue on React-admin, row is unclickable

Hello i'm hiring for a solution my show doesn't work on the row of my table. The cursor doesn't change to let me click on a row and even if i click nothing happened. That's my code
//in App.tsx
<Admin dataProvider={DataProvider} authProvider={authProvider}>
<Resource name="users" list={UsersList} show={UserShow}/>
</Admin>
// in users.tsx
export const UsersList = () => {
// const isSmall = useMediaQuery((theme : any) => theme.breakpoints.down("sm"));
return (
<List filters={userFilters}>
<Datagrid>
<TextField source="id" />
<TextField source="firstname" />
<TextField source="lastname" />
<EmailField source="email" />
<TextField source="phone" />
<TextField source="candidatureStatus" />
<TextField source="created_at" />
</Datagrid>
</List>
);
};
export const UserShow = () => (
<Show>
<SimpleShowLayout>
<TextField label="test" source="email" />
<TextField source="firstname" />
<TextField source="lastname" />
</SimpleShowLayout>
</Show>
)
Even if i followed the tutorial on react admin i can't display a showScreen
If you want to open the Show form when clicking on a row in the List, you need to add:
<Datagrid rowClick="show">
https://marmelab.com/react-admin/Datagrid.html#rowclick

How to get rid of shadows in the Material-UI theme

I need to get rid of shadows in MuiPaper component.
I found some solution:
for example
but they didn't work.
I can override only root component (MuiPaper) but the shadow is set by the class MuiPaper-elevation1-24.
code that render component
const List = props => (
<List {...props} title="lists" filters={<Filter />} sort={{ field: 'timestamps.createdAt', order: 'DESC' }}>
<Datagrid rowClick="show" expand={<Edit />} >
<TextField source="attributes.campaignUuid" label="Campaign Uuid" />
<TextField source="attributes.affiliateId" label="Affiliate Id" />
<DateField source="attributes.createdAt" label="Created At" showTime locales="ru-RU" sortBy="timestamps.createdAt" />
<DateField source="attributes.updatedAt" label="Updated At" showTime locales="ru-RU" sortBy="timestamps.updatedAt" />
<DeleteButton />
</Datagrid>
</List>
);
And HTML that I receive:
<div class="list-page Component-root-904">
<div class="MuiPaper-root-21 MuiPaper-elevation1-24 MuiPaper-rounded-22 MuiCard-root-740 Component-card-905"></div>
</div>
Try this:
import { withStyles, createStyles } from '#material-ui/core/styles';
const listStyles = theme => createStyles({
card: {
boxShadow: 'none',
},
});
const List = withStyles(listStyles)(({ classes, ...props }) => (
<List classes={classes} title="lists" filters={<Filter />} sort={{ field: 'timestamps.createdAt', order: 'DESC' }} {...props}>
...
</List>
);

React-admin: permissions not accessible in react.component

I am using react-admin and have incorporated the advanced tutorial "Creating and Editing a Record From the List Page". This tutorial uses react.component instead of constants. I now need to display fields based of my values in the permissions object passed by authorization. I can do this fine in constants and in the admin component but permissions is always null if I try to access it in the react.component.
class InviteCodeList extends React.Component {
render() {
const { permissions,push, classes, ...props } = this.props;
console.log('permissions');
console.log(permissions);
return (
<Fragment>
<List
{...props}
filters={<CustomFilter />}
actions={<CustomActions />}
sort={{ field: 'title', order: 'ASC' }}
>
<Datagrid>
<TextField source="id" />
<TextField source="title" />
<WithPermissions
render={({ permissions }) => (
permissions.find(f => f.resource === 'admin') !== undefined
? <TextField source="invite_code" />
: null
)}
/>
<ReferenceField source="price_list_id" reference="pricelists">
<TextField source="price_list_name" />
</ReferenceField>
<TextField source="effective_dt" />
<DateField source="expiration_dt" />
<EditButton />
</Datagrid>
</List>
Here is the new code segment. I did not check for null which is returned before the API call returns the actual data.
<Fragment>
<List
{...props}
filters={<CustomFilter />}
actions={<CustomActions />}
sort={{ field: 'title', order: 'ASC' }}
>
<Datagrid>
<TextField source="id" />
<TextField source="title" />
permissions !== null ? permissions.find(f => f.resource === 'admin') !== undefined
? <TextField source="invite_code" />
: null : null
<DateField source="expiration_dt" />
<EditButton />
</Datagrid>
</List>

Cutomize Delete button react-admin

Is there any way to customise DeleteButton button in react-admin to add a confirmation message like 'Do you want to delete item?'. Currently on clicking on DeleteButton it directly deletes the item without asking for a confirmation. I tried adding title attribute to delete button but it does not get fired.
Here is my code
//This worked with admin-on-rest, but not working with react-admin
const CategoryDeleteTitle = translate(({ record, translate }) => <span>
{translate('Delete')}
{record && `${record.code} ${record.name}`}
</span>);
const EditActions = ({ basePath, data, resource }) => (
<CardActions>
<ShowButton basePath={basePath} record={data} />
<ListButton basePath={basePath} />
<DeleteButton title={<CategoryTitle />} basePath={basePath} record={data} resource={resource} />
</CardActions>
);
export const CategoryEdit = (props) => (
<Edit actions={<EditActions />} title={<CategoryTitle />} {...props}>
<SimpleForm>
<DisabledInput source="id" />
<TextInput source="name" />
</SimpleForm>
</Edit>
);
We now handle deletions in an optimistic way, providing an undo mechanism instead of a confirmation dialog.
If this doesn't suit you, you can follow the UPGRADE GUIDE which leads to this page of the documentation: https://marmelab.com/react-admin/CreateEdit.html#actions
Note that you'll have to create and handle your confirmation dialog using something like react-modals and dispatch the DELETE action yourself.
You can use this gist with custom actions like:
const UserEditActions = ({ basePath, data, resource }) => (
<CardActions>
<ListButton basePath={basePath} />
<DeleteButtonWithConfirmation basePath={basePath} record={data} resource={resource} undoable={false} />
<RefreshButton />
</CardActions>
);
export const UserEdit = ({ ...props }) => (
<Edit {...props} actions={<UserEditActions />} >
<CreateEditForm title={<EntityTitle label="User" />} />
</Edit>
);
In react-admin v3, there is now a DeleteWithConfirmButton :-)
According to the documentation "https://marmelab.com/react-admin/CreateEdit.html" create:
const CustomToolbar = props => (
<Toolbar {...props} classes={useStyles()}>
<SaveButton />
<DeleteButton undoable={false} />
</Toolbar>
);
import from react-admin button you need like this:
import {
Toolbar,
SaveButton,
DeleteWithConfirmButton
} from 'react-admin';
see all available names here https://github.com/marmelab/react-admin/tree/master/packages/ra-ui-materialui/src/button, and change DeleteButton on ImportedButton like this:
export const CustomToolbar = props => (
<Toolbar {...props} classes={useStyles()}>
<SaveButton/>
<DeleteWithConfirmButton/>
</Toolbar>
);
And change in the code, where you need <SimpleForm toolbar={<CustomToolbar />}>.

Is it possible to have conditional columns in a List/DataGrid in Admin on REST?

If I apply a filter in a List component in Admin on REST, I want to only show the filtered column (TextField) once this specific filter is selected, because the filter is fuzzy and I want to see the different results at a glance. But when no filter is set, the column is supposed to be hidden.
I implemented it like this so far.
const ConditionalFilterTextField = (props) => {
const show = ... // if filter is set in URL
return (show) ? <TextField {...props} /> : null
}
...
<List {...props} filters={<MyFilter />}>
<Datagrid>
...
<ConditionalFilterTextField sortable={false} source="filter_field" label="My Label" />
...
</Datagrid>
</List>
This does work in a way, but then again not really. It shows the label of the column and an empty space when I return null (when the filter is not set and the column is supposed to be hidden).
How can I control visibility of a TextField depending on whether a filter is set or not? How can I force a rerender of the List when I want to add a column?
Edit:
This is similar to your answer, #Gildas, but doesn't work for me. Some detail might be wrong?
in itemList.js
class ItemList extends Component {
render() {
const props = this.props
// Find out if current filter is source of field.
const filter = props.itemsFilters
const showFieldA = (filter && filter.fieldA) ? true : false
return <List {...props} filters={<ItemsFilter />} perPage={50}>
<Datagrid>
<ReferenceField sortable={false} source="id" reference="items" linkType="show">
<TextField source="fieldB" />
</ReferenceField>
<TextField sortable={false} source="fieldC" />
<TextField sortable={false} source="fieldD" />
<DateField sortable={false} source="fieldE" />
{ (showFieldA === true) ? <TextField sortable={false} source="fieldA" /> : null }
<ShowButton />
<EditButton />
</Datagrid>
</List>
}
}
const ItemsFilter = (props) => (
<Filter {...props}>
<TextInput label="FilterSearch" source="q" />
<TextInput label="FilterA" source="fieldA" />
</Filter>
)
function mapStateToProps(state) {
return {
itemsFilters: state.admin.resources.items.list.params.filter
}
}
export default connect(mapStateToProps)(ItemList)
...
in App.js
<Resource name="items" list={ItemList} show={ItemShow} edit={ItemEdit} />
const MyList = (props) => {
const show = ... // if filter is set in URL
return (
<List {...props} filters={<MyFilter />}>
<Datagrid>
...
{show ? <TextField {...props} /> : null}
...
</Datagrid>
</List>
);
}

Resources