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.52k stars 1.31k forks source link

[QUESTION] - What is the proper way to display and filter a timer in mui data grid #13739

Closed TeoAvignon closed 4 months ago

TeoAvignon commented 4 months ago

The problem in depth

  1. I would like to know the proper way to display a timer in mui data grid
  2. I would like to know the proper way to filter this timer in mui data grid

What I have done is using an interval in renderCell to display the current duration between the currentDate and a date stored (createdAt in my exemple). My value getter is also getting the duration. Then, in the filter part, I enter a duration that is compared to the valueGetter value.

Here is a reproduction link of my solution (which is not working). timerFilteringIssue https://stackblitz.com/edit/react-wvtumk?file=Demo.tsx,durationInput.tsx

To test as in the gif, you have to:

  1. add a filter a few seconds '>' than the duration of a row (for instance 20 since the duration starts at 0 when you open the link)
  2. The filtering is first good and when the row duration is greater than the filter value, the row does not appear.

The filtering is only good when applying it. After that, it is not working by itself Would you please have a proper way to create a dynamic filter for dynamic values (such as timer)?

Maybe the way I render the timer is not good neither, in this case, could you please give me the way to do it. I already try to set a value for the duration every second, but when trying with more than 1k row, my component was laggy.

Here is my current column definition image

Your environment

`npx @mui/envinfo` ``` Don't forget to mention which browser you used. Output from `npx @mui/envinfo` goes here. ```

Search keywords: timer datetime Order ID: 92504

TeoAvignon commented 4 months ago

A solution that would not lag is to update the duration value like this:

useEffect(() => {
    const intervalId = setInterval(() => {
      const newRows = rows.map((row) => ({
        ...row,
        duration: Date.now() - row.createdAt.getTime(),
      }));

     // This is laggy

      // newRows.forEach((nr) => {
       //  apiRef.current.updateRows([nr]);
      // });

     // This is not laggy, but is it the proper way to manager timers?
      apiRef.current.updateRows(newRows);
    }, 1000);

    return () => {
      clearInterval(intervalId);
    };
  }, []);

However, I have the feeling it is not the better way to handle this.

cherniavskii commented 4 months ago

Hi @TeoAvignon This is a very interesting use case!

What you've done in the demo is correct. The filters are not reapplied unless the rows are updated or the filters change. You can manually trigger the filtering using apiRef though:

const filterModel = gridFilterModelSelector(apiRef);
if (filterModel.items?.length > 0) {
  apiRef.current.setFilterModel({ ...filterModel });
}

Here's the updated version of your demo: https://stackblitz.com/edit/react-wvtumk-a5btg8 Is this what you're looking for?

TeoAvignon commented 4 months ago

Hi @cherniavskii,

Thank you very much for your response and your demo! I think it is more optimized than my current implementation.

What I was looking for is to know if there is a 'built-in' way to manage this case from the column definition. I do not think it exists yet. Maybe it can be a nice feature in the future!

For now, I will work with your solution ! :)

github-actions[bot] commented 4 months ago

:warning: 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.

@TeoAvignon: 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.