4

In react-admin I have a page that shows a list of balances, it looks like this:

// extra code not included
export const BalanceList = props => (
  <List filters={<BalanceFilter/>} actions={<BalanceActions/>} {...props} perPage={-1}>
    <Datagrid rowClick="edit">
      <TextField source="id" />
      <DateField source="date" />
      <ReferenceField source="account_id" reference="accounts">
        <TextField source="name"/>
      </ReferenceField>
      <TextField source="currency.name" label="Currency" />
      <TextField source="currency.symbol" label="Symbol" />
      <NumberField source="used" options={{ maximumFractionDigits: 4 }} />
      <NumberField source="free" options={{ maximumFractionDigits: 4 }} />
      <NumberField source="total" options={{ maximumFractionDigits: 4 }} />
      <NumberField source="total_value" options={{ maximumFractionDigits: 2 }} />
    </Datagrid>
  </List>
);

I would like to display a line in the end, between the list and the pagination. Or also inside the list component if it's easier to achieve.

That line should show the total of the used amount, fee amount etc. to calculate those, it should simply sum all the values of the relative column. E.g. total_value should be a sum of all "total_value" rows.

I'm new to react and react-admin and no idea how to achieve this. Please provide some code in your answer, thank you.

UPDATE: I tried to use the aside component:

const Aside = ({ data, ids })  => (
  <div style={{ width: 200, margin: '1em' }}>
    <Typography variant="title">Post details</Typography>
    <Typography variant="body1">
      Total value: {ids.map(id => data[id]).reduce((sum, balance) => sum + balance.total_value)}
    </Typography>
  </div>
);

export const BalanceList = props => (
  <List aside={<Aside />} filters={<BalanceFilter/>} actions={<BalanceActions/>} {...props} perPage={-1}>
    <Datagrid rowClick="edit">
      <TextField source="id" />
      <DateField source="date" />
      <ReferenceField source="account_id" reference="accounts">
        <TextField source="name"/>
      </ReferenceField>
      <TextField source="currency.name" label="Currency" />
      <TextField source="currency.symbol" label="Symbol" />
      <NumberField source="used" options={{ maximumFractionDigits: 4 }} />
      <NumberField source="free" options={{ maximumFractionDigits: 4 }} />
      <NumberField source="total" options={{ maximumFractionDigits: 4 }} />
      <NumberField source="total_value" options={{ maximumFractionDigits: 2 }} />
    </Datagrid>
  </List>
);

But for some unknown reason the reduce function complains that it can't be applied to an empty array. Why empty? data is supposed to be the same array passed to the DataGrid...

enter image description here

firepol
  • 1,731
  • 22
  • 39
  • 1
    No initial value was specified for the Reduce function: {ids.map(id => data[id]).reduce((sum, balance) => sum + balance.total_value, 0)} – MaxAlex Jul 05 '19 at 03:58
  • Nice, the initial value solved the issue. Funny that in the official docu they didn't do it right (I'll report the issue)! Now the question is, is this the ideal way to solve my problem? The aside component shows up at the top right, while my requirement was to show it in the bottom after the grid... can you please update your answer, if you find out a better way than the aside, or how to style it properly? Thank you – firepol Jul 05 '19 at 14:00
  • The pagination element gets the same props as aside when creating it, you can implement your extended component based on https://github.com/marmelab/react-admin/blob/master/packages/ra-ui-materialui/src/list/Pagination.js – MaxAlex Jul 06 '19 at 15:33
  • Maybe helpful, Simple table version with ReactJs https://stackoverflow.com/a/62727061/11302100 – Nijat Aliyev Jul 04 '20 at 08:53

1 Answers1

0

You can use the component FunctionField: https://marmelab.com/react-admin/Fields.html#functionfield

import { FunctionField } from 'react-admin'

<FunctionField
  label="Total Value"
  render={record => `${record.total_value + record.total_XXX + ...}`}
/>
MaxAlex
  • 2,919
  • 1
  • 14
  • 14
  • Thx, but as I said I don't need to calculate a total in the row/record, I need to calculate the total amount of all the "total_value" of all the rows/records and show this at the end of the grid (how at the bottom). Do you know how to achieve this and can update your answer? – firepol Jul 04 '19 at 09:19
  • All your records are placed on one page? react-admin only receives data for the current page. If you need to process all resource records, you need to create a separate request. – MaxAlex Jul 04 '19 at 12:47
  • Yes I have all the records in one page (I used the option `perPage={-1}`). I updated my question to show a possible way using `aside` but something to be added inside the DataGrid or in the List would be preferable. – firepol Jul 04 '19 at 22:09
  • it would be a must have feature. – indianwebdevil Sep 20 '22 at 16:44