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.
Analysis
There are 2 problems:
- Components that implement a
ListContext don't include a default exporter like useListController does.
<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
- Add support for an
exporter prop in <ArrayField>, <ReferenceArrayField> and <ReferenceManyField>, and pass it down to the controller
- Add a default
exporter to useReferenceArrayFieldController, useReferenceManyFieldController, and useList
- 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.
- 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
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>: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.
Analysis
There are 2 problems:
ListContextdon't include a defaultexporterlikeuseListControllerdoes.<ExportButton>starts by callingdataProvider.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
exporterprop in<ArrayField>,<ReferenceArrayField>and<ReferenceManyField>, and pass it down to the controllerexportertouseReferenceArrayFieldController,useReferenceManyFieldController, anduseListListContext:async getData() => Record[], that each controller must define according to its internal logic. It should return the entire list data regardless of pagination.<ExportButton>to use thisgetDataif present in the context instead ofdataProvider.getListNote that this change should also allow a "Select All" feature (cf #9043)
Environment