mui / mui-x

MUI X: Build complex and data-rich applications using a growing list of advanced React components, like the Data Grid, Date and Time Pickers, Charts, and more!
https://mui.com/x/
4.13k stars 1.28k forks source link

[datagrid] Row grouping object field values #10729

Open cstephens-cni opened 11 months ago

cstephens-cni commented 11 months ago

The problem in depth πŸ”

I'm having a problem being able to fully use the MUIX grid with object data.

The point: I seem to be running into a wall because of the way that groups auto-generate their keys. If you have a value that is an object the group key is "autogenerategroupORwhatever-[Object Object]". Is there a way to change how this is generated? (I've looked into api and source code pretty closely)

I have tried multiple ways of looking at the issue and trying to figure out if i should be approaching object grid data from a different angle. However I keep running into walls and it feels like there is a contradiction occuring when trying to use all the grids capabilities when it comes to object values.

The closest I had gotten to a holistic approach breaks down because of the auto generated id for groups.

Other ways I'm come at like only producing a primitive from value getter, break other capabilities like aggregation or sorting because I need info on the object. The row data isn't always present with other capabilities.

Anyways I'm thinking this probably already a known things however I haven't been able to find information on it or perhaps I just didn't understand.

example data:

{
   ticketNumber: string,
   assigned: {firstName:string, lastName:string, email:string},
   tag: string
}

The idea is I want to be able to

I think that is all of them, I believe I have all of these working except for group

Your environment 🌎

System: OS: macOS 14.0 Binaries: Node: 18.17.1 - ~/.nvm/versions/node/v18.17.1/bin/node Yarn: 1.22.19 - ~/.yarn/bin/yarn npm: 9.6.7 - ~/.nvm/versions/node/v18.17.1/bin/npm Browsers: Chrome: 118.0.5993.88 Edge: 118.0.2088.57 Safari: 17.0 npmPackages: @emotion/react: 11.11.1 => 11.11.1 @emotion/styled: 11.11.0 => 11.11.0 @mui/base: 5.0.0-beta.17 @mui/core-downloads-tracker: 5.14.14 @mui/icons-material: ^5.14.14 => 5.14.14 @mui/lab: ^5.0.0-alpha.146 => 5.0.0-alpha.146 @mui/material: ^5.14.14 => 5.14.14 @mui/private-theming: 5.14.14 @mui/styled-engine: 5.14.14 @mui/system: ^5.14.14 => 5.14.14 @mui/types: 7.2.4 @mui/utils: 5.14.11 @mui/x-data-grid: 6.16.0 @mui/x-data-grid-premium: ^6.16.0 => 6.16.0 @mui/x-data-grid-pro: 6.16.0 @mui/x-date-pickers: ^6.16.0 => 6.16.0 @mui/x-license-pro: 6.10.2 @types/react: 18.2.13 => 18.2.13 react: 18.2.0 => 18.2.0 react-dom: 18.2.0 => 18.2.0 typescript: 5.1.6 => 5.1.6

Search keywords: grouping key for object values Order ID: 70572

cherniavskii commented 11 months ago

Hi @cstephens-cni It looks like groupingValueGetter is what you're looking for. I'll try to set up a quick demo πŸ™‚

cherniavskii commented 11 months ago

Here you go: https://codesandbox.io/s/dreamy-shape-ydkdtq?file=/src/Demo.tsx Is this what you're looking for?

cstephens-cni commented 11 months ago

@cherniavskii must return a string right? when you try to render the group it won't have the data I need. Group become only strings then. Is that a limit to grouping maybe? I've already implemented this as a work around :(

cherniavskii commented 11 months ago

Group become only strings then. Is that a limit to grouping maybe?

Yes, I believe this is the limitation of row grouping for now. We can convert this issue into a feature though.

What would be the ideal behavior for objects in your opinion?

cstephens-cni commented 11 months ago

@cherniavskii so here is what i came up with to have my cake and eat it too

    groupingValueGetter: ({ value }) => {
      value.toString = () => `${value.firstName}${value.lastName}`;
      return value;
    }

https://codesandbox.io/s/tostring-group-id-cjf367?file=/src/Demo.tsx

The Id is generated by the toString and the value is passed to the cell renderer.

I guess, what I'm looking for, is there a different way to approach using objects like this? basically every feature is much more complicated to use so perhaps there is a different direction I should be coming at it with?

cherniavskii commented 11 months ago

The Id is generated by the toString and the value is passed to the cell renderer.

That's actually a pretty good solution. I don't have a better one to suggest for now, but I will get back to this issue if I think of one πŸ‘πŸ»

cstephens-cni commented 11 months ago

@cherniavskii yeah perhaps if it's noted in documentation, I think a bit more hand holding with object data would be great in the documentation. Perhaps even a straight forward section for it.

Currently we have to dig through each feature and piece together how best to handle them. The grid has a ton of features and each has to be handles to work with object data otherwise we get errors. Honestly, while I think I've got a handle on them now, I still have that feeling like I missed something.

pszemang commented 6 months ago

@cherniavskii so here is what i came up with to have my cake and eat it too

    groupingValueGetter: ({ value }) => {
      value.toString = () => `${value.firstName}${value.lastName}`;
      return value;
    }

https://codesandbox.io/s/tostring-group-id-cjf367?file=/src/Demo.tsx

The Id is generated by the toString and the value is passed to the cell renderer.

I guess, what I'm looking for, is there a different way to approach using objects like this? basically every feature is much more complicated to use so perhaps there is a different direction I should be coming at it with?

Thanks, this is the solution I've been looking for two days. It's hacky but the only one working. I had a similar issue. I had an object like:

{
  fleet: {
    id: 123,
    name: 'some name',
  }
}

I wanted to group the rows using id but display name as a header for the group using renderCell method. After trying literally everything, I almost gave up, but then I found your solution. I need to admit that the support for objects when grouping the columns is really poor 😒

PierreGuillaumeIngeno commented 5 months ago

Hi @cherniavskii, I have a similar use case as @pszemang, but encounter a typing issue which might require a modification in the declaration file (I might be mistaken of course). Here is the code and an excerpt from the error:

const withNameAsRenderValue = (value: { name: string; id: string }) =>
  value === undefined ? { toString: () => undefined } : { ...value, toString: () => value.name };

const COLUMNS = {
 {
    field: 'myColumn',
    headerName: 'My Column',
    valueGetter: withNameAsRenderValue,
    groupingValueGetter: withNameAsRenderValue,
    renderCell: (params) => params.value.toString(),
    width: 300,
  }
}

Type { toString: () => undefined; } is not assignable to type GridKeyValue | null | undefined

Instead of an object, groupingValueGetter expects a function returning string | number | boolean | null | undefined (as seen in gridGroupingValueGetter.d.ts).

Note that the type works for valueGetter since it expects a function returning a generic V type, as seen in gridColDef.d.ts. The typing issue only occurs for groupingValueGetter.

If @cstephens-cni solution is considered as the correct one and my above analysis is correct, should the typing should be revised to accept more generic values than string | number | boolean | null | undefined? Thanks!