react-admin icon indicating copy to clipboard operation
react-admin copied to clipboard

<ExportButton> doesn't work in any `ListContext`

Open fzaninotto opened this issue 2 years ago • 0 comments

What you were expecting

<ExportButton> should just work when used as a child of <ArrayField>, <ReferenceManyField>, or <ReferenceArrayField>

What happened instead

The button is rendered, it calls dataProvider.getList(), but does not trigger a file download on the client.

Steps to reproduce:

https://stackblitz.com/edit/github-juchmy?file=src%2Fposts%2FPostEdit.tsx

In the simple example, in the PostEdit.tsx, add an <ExportButton> as child of <ReferenceManyField>:

          <ReferenceManyField reference="comments" target="post_id" fullWidth>
            <ExportButton />
            <Datagrid>
              <DateField source="created_at" />
              <TextField source="author.name" />
              <TextField source="body" />
              <EditButton />
            </Datagrid>
          </ReferenceManyField>

Then browse to a post detail (e.g. https://githubjuchmy-lbmb--8080--9c8944bc.local-credentialless.webcontainer.io/#/posts/1/3) and click on the export button.

image

Analysis

There are 2 problems:

  1. Components that implement a ListContext don't include a default exporter like useListController does.
  2. <ExportButton> starts by calling dataProvider.getList(), which is wrong in many situations. For instance, when used as a child of <ReferenceArrayField>, the entire data is already fetched and should not be refetched.

Solution

  1. Add support for an exporter prop in <ArrayField>, <ReferenceArrayField> and <ReferenceManyField>, and pass it down to the controller
  2. Add a default exporter to useReferenceArrayFieldController, useReferenceManyFieldController, and useList
  3. Add a new field in ListContext: async getData() => Record[], that each controller must define according to its internal logic. It should return the entire list data regardless of pagination.
  4. Update <ExportButton> to use this getData if present in the context instead of dataProvider.getList

Note that this change should also allow a "Select All" feature (cf #9043)

Environment

  • React-admin version: 4.11
  • Last version that did not exhibit the issue (if applicable): N/A
  • React version: 17
  • Browser: Chrome

fzaninotto avatar May 21 '23 16:05 fzaninotto