React-admin: Add Bulk Actions to Lists

Created on 3 Oct 2016  Â·  30Comments  Â·  Source: marmelab/react-admin

We can make items in list selectable.. But there is no way to manipulate those selected items.. It would be great to have an ability to add bulk actions component as well as filter.

Thank you for your awesome work!

enhancement

Most helpful comment

All 30 comments

+1

@fzaninotto Some ideas about the implementation of this feature ? Gonna try to implement it on a project.

I'd advise to wait until material ui 1.0 is released. At that point we'll switch back from real tables to MUI tables.

@fzaninotto
It seems that you switch backed to real tables with the responsive ui PR.
But you didn't reenabled the checkbox.
How do you imagine this feature. You check the boxes, and when you click a bulk action, you send all ids to the action ? Or Should we try to implement the rest call to get last status for all items selected and send objects to the action ?
What is the best way to get all checked boxes ?

I haven't thought about it yet. Give it a try!

@fzaninotto @wadjeroudi - hi guys, how far have you got ?

I've been speaking to a friend and he was struggling to work out the best way to implement this.

Presumably, we'd have modify our UserList component for instance to take an actions={}

I'm thinking then that bulk actions live at bottom of list (in datagrid) to distinguish between Add Filter/Create (non-bulk) actions at the top ?

Actions would then be a dropdown initially - a bit like filters work?

Once selected, pass in selectedRecords from the datagrid as a parameter.

I'm anticipating 2-3 types of actions:

a) action where it would immediately do a REST API post request
b) action that throws up a dialog box
c) presumably a 3rd type where action could modify page (e.g. as filters do)

@mantis didn't do it.
I think that for now, we should just aim one type of action a function that receives selected records. and it's up to the user to do whatever he wants ?

I haven't given it time, but you can look at how ng-admin handles it - it's probably a good inspiration.

Have just implemented this using Material UI components following are the steps I took.

1) Create custom Datagrid using material UI (pretty straightforward) and basically copypasting AOR code and enabling checkboxes
2) adding Custom Action to the List component. In my case this was an 'Assign All' button. That maps to the following action. This is documented in the below link.

https://marmelab.com/admin-on-rest/List.html#actions

export const AssignAllToSelf = (selection, basePath) => {
    return {
    type: ASSIGN_ALL_TO_SELF,
    payload: {selection: selection},
    meta: { resource: 'tales/assignEditor', fetch: UPDATE, cancelPrevious: false }
  }
};

3) adding a custom wrapper on the rest client that intercepts UPDATE calls to 'tales/assignEditor'
(AOR does not have bulk update feature just yet. )

if (type === 'UPDATE'  &&  resource === 'tales/assignEditor') {
    let url = config.host + '/' + 'tales/assignEditor'
    options.method = 'PUT';
    options.body = JSON.stringify(params)
    return handleRequestAndResponse(url, options)
  } else {
    return requestHandler(type, resource, params);
}


Working just fine! :)

@kodepareek how do you get the selection ? After you turn on the displayRowCheckbox, how do you link the custom(s) action(s) with the selected checkboxes ?

Update: it seems that we need to use the onRowSelection event to get the selected rows.

I write the selection into state as state.selection which is then picked up by the Assign Button action component.

I have made the outer List component into a connected component. You can also make the customData grid below connected.

class CustomDatagrid extends Component {
  handleRowClick = (rowArr) => {
    const {ids, handleSelection} = this.props
    if (Array.isArray(rowArr)) {
      handleSelection(rowArr.map(row => ids[row]))
    } else {
      handleSelection(ids)
    }
  }
  render() {
    const { resource, children, ids, isLoading, data, currentSort, basePath, styles = defaultStyles, muiTheme, rowStyle, options, headerOptions, bodyOptions, rowOptions } = this.props;
      render() {
    const { resource, children, ids, isLoading, data, currentSort, basePath, styles = defaultStyles, muiTheme, rowStyle, options, headerOptions, bodyOptions, rowOptions } = this.props;
    return (
      <Table style={options && options.fixedHeader ? null : styles.table}
             fixedHeader={false}
             selectable={true}
             multiSelectable={true}
             onRowSelection={this.handleRowClick}
             {...options}
             >
             .......................................................................

onRowSelection just returns the row number that was clicked need to map that into the ids of the record which is tales in my case.

Inside the outer List component of CustomDatagrid, in my case EditorAssignView

class EditorAssignView extends Component {
  handleSelection = (selection) => {
    const { AddSelectionToState } = this.props
    AddSelectionToState(selection)
  }
  render() {
    const props = this.props
    return (
      <List {...props} actions={<TaleAssignListActions />} title="Fresh Tales" >
         <CustomDatagrid handleSelection={this.handleSelection}>
     .............................................................

The add selection to state action

export const ADD_SELECTION_TO_STATE = 'ADD_SELECTION_TO_STATE';
export const AddSelectionToState = (selection, basePath) => {
    return {
    type: ADD_SELECTION_TO_STATE,
    payload: {selection: selection},
  }
};

Thx @kodepareek.
FYI, you don't need to rewrite the table part in your CustomDatagrid, you just can do that :

 <Datagrid headerOptions={{ adjustForCheckbox: true }} bodyOptions={{ displayRowCheckbox: true }} rowOptions={{ selectable: true }} options={{ multiSelectable: true, onRowSelection: {this.handleRowClick} }}>

It should be cleaner to maintain.

Oh That must be new. In my aor version selectable = false has been hard coded in.

It is hardcoded but you can override them.

Oh that's super. Will try it out tomorrow. Will definitely make things cleaner.

@kodepareek sorry to bother, but when I click on my button, the selection is resetted immediatly because the checkboxes are unchecked if you click outside, do you have the problem ?

Edit: Ok it was because of the material UI option, you have to set deselectOnClickaway to false.

What is the status of this feature? The project I'm currently working on requires bulk deletion, so I have to implement it in the nearest future. I'd like to know where to start: should I start from scratch or there is some existing project/codebase available that I could join or reuse?

Lists accept actions as props now.

https://marmelab.com/admin-on-rest/List.html#actions

@djhi I think we can close this issue.

No, actions (the list of buttons on the top of the screen) and list actions (actions you can execute on a selection of rows) are different.

This feature is not started. If you want to give it a try, you're welcome!

I think I can do it. I will get back here a plan about how I am going to execute this feature. Have done something similar. Will think about generalizing.

what news about feature?

Sorry guys. My app has been in some kind of production hell here at work.

I should start work on this by this weekend.

@kodepareek Could you, please, say what are you going to do? There is already a pull request with this feature: https://github.com/marmelab/admin-on-rest/pull/1013, or am I wrong? I'm waiting there for some feedback from... anyone.

Sorry my bad. I haven't been keeping track. Seems you guys have pretty much
banged out this feature. Will try and tackle some other issue when I get
free.

On Tue, Oct 10, 2017 at 2:03 PM, Alexey notifications@github.com wrote:

@kodepareek https://github.com/kodepareek Could you, please, say what
are you going to do? There is already a pull request with this feature:

1013 https://github.com/marmelab/admin-on-rest/pull/1013, or am I

wrong? I'm waiting there for some feedback from... anyone.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/marmelab/admin-on-rest/issues/65#issuecomment-335401127,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ARqnqolx_GoqZMRdmWRXlb0NwMZErKXEks5sqyvygaJpZM4KMgH9
.

@kodepareek Did you use @alexeyoganezov changes or did you try a custom solution?

I made a custom solution. I think I have documented it somewhere on Github
or Stackoverflow. Will check and share.

On Wed, Nov 1, 2017 at 7:37 AM, Preston Tighe notifications@github.com
wrote:

@kodepareek https://github.com/kodepareek Did you use @alexeyoganezov
https://github.com/alexeyoganezov changes or did you try a custom
solution?

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/marmelab/admin-on-rest/issues/65#issuecomment-340957703,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ARqnqh3Fg_azH4nWI8FLv_6LUDmcv_L9ks5sx9JsgaJpZM4KMgH9
.

@kodepareek Oh I think it's in this thread correct?

Aah yes it right here above.

I big change would be that one does not need to create a custom DataGrid
component to make the checkboxes show. The rest is quite straightforward I
think.

On Wed, Nov 1, 2017 at 12:43 PM, Preston Tighe notifications@github.com
wrote:

Oh I think it's in this thread correct?

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/marmelab/admin-on-rest/issues/65#issuecomment-341012554,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ARqnqnaqi8uUWbXK4w3BpiNM4Ppu_GzSks5syBoegaJpZM4KMgH9
.

Implemented in #1521

Was this page helpful?
0 / 5 - 0 ratings

Related issues

kikill95 picture kikill95  Â·  3Comments

kopax picture kopax  Â·  3Comments

Dragomir-Ivanov picture Dragomir-Ivanov  Â·  3Comments

aserrallerios picture aserrallerios  Â·  3Comments

phacks picture phacks  Â·  3Comments