Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[data grid] Tree view not loading server side data correctly #14241

Closed
daviesgeek opened this issue Aug 16, 2024 · 8 comments
Closed

[data grid] Tree view not loading server side data correctly #14241

daviesgeek opened this issue Aug 16, 2024 · 8 comments
Labels
bug 🐛 Something doesn't work component: data grid This is the name of the generic UI component, not the React module! support: premium standard Support request from a Premium standard plan user. https://mui.com/legal/technical-support-sla/

Comments

@daviesgeek
Copy link

daviesgeek commented Aug 16, 2024

Steps to reproduce

Link to live example: https://codesandbox.io/p/sandbox/data-grid-tree-view-8yddmw

Steps:

  1. Open the first row
  2. Attempt to close the first row, it won't close
  3. Open the second (newly loaded) row

All I've done to reproduce this issue is fork the sandbox on the React Server-side tree data page and attempt to integrate in my own dataset.

Current behavior

First of all, the rows are not closing, but the open/collapse arrows are moving as expected.
Secondly, the newly loaded data is loading at the bottom of the grid, not where it's supposed to be inserted.

Expected behavior

I would expect that rows that are opened can be closed, collapsing the data that it just loaded.
I would also expect, just like the demo, that rows would be inserted directly below the row that was just opened.

Context

I am just trying to get our custom dataset hooked up to the data grid tree view. I am assuming I have something wrong in the grouping key but there's little to no information about what that key is actually supposed to be.

Your environment

npx @mui/envinfo
  Brave 1.68.141 Chromium: 127.0.6533.120 on macOS Version 14.5 (Build 23F79)
  Google Chrome 127.0.6533.120 on macOS Version 14.5 (Build 23F79)
  Google Chrome 127.0.6533.119 on Windows 11 Version 23H2 (Build 22631.3880)
  
  System:
    OS: macOS 14.5
  Binaries:
    Node: 18.16.0 - ~/.nvm/versions/node/v18.16.0/bin/node
    npm: 9.5.1 - ~/.nvm/versions/node/v18.16.0/bin/npm
    pnpm: Not Found
  Browsers:
    Chrome: 127.0.6533.120
    Edge: 127.0.2651.105
    Safari: 17.5
  npmPackages:
    @emotion/react: ^11.10.6 => 11.11.1 
    @emotion/styled: ^11.10.6 => 11.11.5 
    @mui/base:  5.0.0-beta.24 
    @mui/core-downloads-tracker:  5.16.6 
    @mui/icons-material: ^5.8.2 => 5.14.18 
    @mui/lab: ^5.0.0-alpha.84 => 5.0.0-alpha.153 
    @mui/material: ^5.15.20 => 5.16.6 
    @mui/private-theming:  5.14.18 
    @mui/styled-engine:  5.14.18 
    @mui/styles: ^5.15.20 => 5.15.20 
    @mui/system: ^5.15.20 => 5.16.6 
    @mui/types:  7.2.9 
    @mui/utils:  5.16.6 
    @mui/x-data-grid:  7.12.1 
    @mui/x-data-grid-generator: ^7.12.1 => 7.12.1 
    @mui/x-data-grid-premium: 7.12.1 => 7.12.1 
    @mui/x-data-grid-pro:  7.12.1 
    @mui/x-date-pickers:  6.18.1 
    @mui/x-date-pickers-pro: 6.18.1 => 6.18.1 
    @mui/x-internals:  7.12.0 
    @mui/x-license:  7.12.0 
    @mui/x-license-pro:  6.10.2 
    @types/react: ^18.0.10 => 18.2.38 
    react: ^18.1.0 => 18.2.0 
    react-dom: ^18.1.0 => 18.2.0 
    typescript: ^4.7.2 => 4.9.5 

Search keywords: data grid, tree view, server side data
Order ID: 87473

@daviesgeek daviesgeek added bug 🐛 Something doesn't work status: waiting for maintainer These issues haven't been looked at yet by a maintainer labels Aug 16, 2024
@github-actions github-actions bot added component: data grid This is the name of the generic UI component, not the React module! support: premium standard Support request from a Premium standard plan user. https://mui.com/legal/technical-support-sla/ labels Aug 16, 2024
@michelengelen michelengelen changed the title Data grid tree view not loading server side data correctly [data grid] Tree view not loading server side data correctly Aug 19, 2024
@michelengelen
Copy link
Member

Hey @daviesgeek ...
As you already guessed there are some issues with your data.

  1. The groupingKey is the value of the field the data is being grouped by. From the example in the docs:
const dataSetOptions = {
  dataSet: 'Employee' as const,
  rowLength: 1000,
  treeData: { maxDepth: 3, groupingField: 'name', averageChildren: 5 },
};
...
getGroupKey: (row) => row[dataSetOptions.treeData.groupingField]
  1. The issue with the rows being added at the bottom and the toggle not behaving as expected is coming from that same problem. The grid determines these things based on the row id. And if that row id is used as the grouping key the grid cannot handle that correctly.

@michelengelen michelengelen added status: waiting for author Issue with insufficient information and removed status: waiting for maintainer These issues haven't been looked at yet by a maintainer labels Aug 19, 2024
@daviesgeek
Copy link
Author

daviesgeek commented Aug 19, 2024

@michelengelen thanks for your response. I did see this in the docs example, I'm still pretty unclear about what the key exactly should be, since dataSetOptions.treeData.groupingField is set to name. I was thinking that group key should be the key the row should be grouped under, but it seems like that might not be the case?

Two questions that should hopefully clear this up:

What is the definition of the grouping key? Should it be the key of what the row supposed to be grouped under, i.e., a "parent" field? Or is it supposed to be the key that defines the group of the current row, i.e., this row group and it's children are keyed off the group key?

Put slightly differently, if I have data like this:

             one
           /    \
         two   three
       /     \ 
     four    five        

For the row "two", what is the groupKey? Is it "two" or "one"?

Secondly (which may be answered by the first, but just to clarify), what is the top level grouping key supposed to be? In the example above, what is the grouping key for "one"?

@github-actions github-actions bot added status: waiting for maintainer These issues haven't been looked at yet by a maintainer and removed status: waiting for author Issue with insufficient information labels Aug 19, 2024
@michelengelen
Copy link
Member

Hey @daviesgeek ... maybe groupKey as a term is misleading a bit. Think about it as the grouping value instead. The important part is that the groupKey is used in the query to fetch new rows from the API on toggling a group.

From your question, consider this example:

Alice
├── Bob
│   ├── Carol
│   └── David
├── Eve
├── Frank
│   ├── Grace
│   └── Heidi
└── Michael

groupingkey for Alice would be 'Alice', for Bob it would be 'Bob', etc

Does that make it more clear?

@michelengelen michelengelen added status: waiting for author Issue with insufficient information and removed status: waiting for maintainer These issues haven't been looked at yet by a maintainer labels Aug 20, 2024
@daviesgeek
Copy link
Author

Yes that makes it clear. I did try doing this earlier both in my application and in the sandbox.

If you look at this updated sandbox, you can see I set the groupKey to row.id, but it's still working as I reported in the original post (open works, close doesn't, rows are appended to the end of the grid). As I understand it, this should work correctly, since it's providing a unique key for the individual row that's used to fetch data later. Any suggestions for what's happening?

@github-actions github-actions bot added status: waiting for maintainer These issues haven't been looked at yet by a maintainer and removed status: waiting for author Issue with insufficient information labels Aug 20, 2024
@michelengelen
Copy link
Member

@MBilalShafi could you take a look?

@MBilalShafi
Copy link
Member

MBilalShafi commented Aug 20, 2024

Hey @daviesgeek,

As @michelengelen mentioned, the getGroupKey function expects the value that should be rendered on the current tree level under the Group column.

Each tree data request has a groupKeys parameter representing the nested level of data needed to be fetched.

In the beginning (the first call that fetches the root rows), the value of groupKeys is [].
Let's say the first call returns the following data:

{
  rows: [
    { name: 'Alice', age: 15, childrenCount: 5 },
    { name: 'Adam', age: 20, childrenCount: 2 },
    { name: 'Elizabeth', age: 25, childrenCount: 0 },
  ],
  rowCount: 3, // Always the root level row count
}

Now the Data Grid doesn't have children's information at this point, it relies on the developer to let it know:

  1. Which value should be shown in the Group column for each row? (Using dataSource.getGroupKey)
    • In the above example, it could be: getGroupKey: (row) => row.name
  2. Which row has children on the server and what is each of their count, if known? (Using dataSource.getChildrenCount)
    • In the above example, it will be: getChildrenCount: (row) => row.childrenCount

Now, the getGroupKeys is important in a way that whatever value you provide to it will become the params.groupKeys when the next call is sent to fetch children of a specific row. That is the motivation behind calling it getGroupKeys too because the Data Grid uses it to extract the keys that the server uses for providing further data.

So, in the above example, when the user clicks on the row Alice the dataSource.getRows will be called with params.groupKeys=['Alice'], and the server will then extract the children of group key Alice and provide them as a response, which Data Grid will render as the children of Alice, and the cycle repeats.

Important

In every response of the getRows call, the response.rowCount must represent the root level row count, not the length of the rows in the current slice. The Data Grid uses this information to compute the pagination row count.

Based on the above information, I made some changes in your codesandbox example to make it work, here's the updated version: https://codesandbox.io/p/sandbox/data-grid-tree-view-forked-7y8j7x

A summary of the changes

  1. Data cleanup: Modified the dataset to a more tree-like structure to easily access the data following a constraint that row.manages is always an array to make accessing it easier.
  2. Mock server improvements:
    • Updated the Backend simulator function getData in a way to receive groupKeys and return:
      1. The chunk of data on each requested level
      2. The root level row count
    • Added some delay to simulate server load.
  3. Updated the dataSource.getGroupKey to use row.name value as a group key.
  4. Nitpick, but as the dataSource object doesn't depend on a variable inside the component scope, I moved it outside the component and removed React.useMemo from around it.
  5. Since your backend logic doesn't take into account the pagination params, I increased the pageSize to contain all the rows, that's something you need to be aware of while implementing the actual backend logic.

Let me know if it solves your concerns or if you have further questions.

Thank you!

@MBilalShafi MBilalShafi added status: waiting for author Issue with insufficient information and removed status: waiting for maintainer These issues haven't been looked at yet by a maintainer labels Aug 20, 2024
@daviesgeek
Copy link
Author

@MBilalShafi this makes a lot of sense, thanks for the example. I was able to track down my issue in my code. When I use .pop() for the groupKeys, it's modifying the original array and it seems like that causes the grid to lose track of what's going on. I switched it to reference the element, rather than .pop() it off the end and all is good!

Thank you both for your help @MBilalShafi @michelengelen

@github-actions github-actions bot removed the status: waiting for author Issue with insufficient information label Aug 27, 2024
Copy link

⚠️ This issue has been closed. If you have a similar problem but not exactly the same, please open a new issue.
Now, if you have additional information related to this issue or things that could help future readers, feel free to leave a comment.

@daviesgeek: How did we do? Your experience with our support team matters to us. If you have a moment, please share your thoughts in this short Support Satisfaction survey.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 🐛 Something doesn't work component: data grid This is the name of the generic UI component, not the React module! support: premium standard Support request from a Premium standard plan user. https://mui.com/legal/technical-support-sla/
Projects
None yet
Development

No branches or pull requests

3 participants