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

[DataGrid] Data source with editing #16045

Draft
wants to merge 31 commits into
base: master
Choose a base branch
from

Conversation

MBilalShafi
Copy link
Member

@MBilalShafi MBilalShafi commented Dec 31, 2024

Resolves #13261

Preview


In progress items:

Future improvements:

  • Performance: Move computation of rowIdToGetRowsParams to useTransition or similar delayed computation mechanism (Should we ?)

@MBilalShafi MBilalShafi added component: data grid This is the name of the generic UI component, not the React module! new feature New feature or request feature: Server integration Better integration with backends, e.g. data source labels Dec 31, 2024
@mui-bot
Copy link

mui-bot commented Dec 31, 2024

@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged label Jan 9, 2025

This comment was marked as outdated.

@github-actions github-actions bot removed the PR: out-of-date The pull request has merge conflicts and can't be merged label Jan 13, 2025

This comment was marked as outdated.

@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged label Jan 24, 2025
@github-actions github-actions bot added PR: out-of-date The pull request has merge conflicts and can't be merged and removed PR: out-of-date The pull request has merge conflicts and can't be merged labels Jan 27, 2025

This comment was marked as outdated.

@github-actions github-actions bot removed the PR: out-of-date The pull request has merge conflicts and can't be merged label Feb 10, 2025
@MBilalShafi MBilalShafi marked this pull request as ready for review February 17, 2025 14:09
return;
}
updatedRows[rowIndex] = rowUpdate;
cache.set(getRowsParams, { ...cachedData, rows: updatedRows });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is way more complicated than this 😬

This only works if sorting and/or filtering is not applied. Otherwise, you need to have this row in some other place or not in this cache key at all anymore. Not only that, but it affects other cache keys as well.

I am not event sure if we can do anything to keep the cache once sort/filter is there unless we don't change the current cache structure completely.

Copy link
Member Author

@MBilalShafi MBilalShafi Feb 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A composite key may be?

Instead of 'row.id' only, we create a key for all the differentiating factors e.g.

const key = JSON.stringify([row.id, filterModel, sortModel, groupKeys])

const value = getRowParams

Then, when searching for a specific row, we generate that composite key again based on the current model values.

I'll give it a try.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem is the position
If you sort by certain column and you change the value of that column, you need to update all chunks in between and move one record up and then inject updated record in the chunk which holds the position that the new value occupies.

Copy link
Contributor

@arminmeh arminmeh Feb 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Depending on how complex you want to go I see two possibilities with the current cache structure.

  1. You only keep cache chunks with the pagination param only (since it doesn't affect position or other data) and clear all others
  2. You track which columns have changed and you update all cache chunks that have sort/filter/group/aggregation params that are not related to the updated columns and clear the rest

As mentioned above, updating cache for the columns that are updated is pretty hard. Problem mentioned for sorting applies for other operations that we cache - you need new aggregation amount or you need to remove the row completely for some filter param because it becomes filtered out (which means you have to adjust some other chunks related to that filter param), etc.

Copy link
Member Author

@MBilalShafi MBilalShafi Feb 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You track which columns have changed and you update all cache chunks that have sort/filter/group/aggregation params that are not related to the updated columns and clear the rest

@arminmeh You made some great points. I agree that delving deeper into this approach could be highly complex and performance-intensive. More importantly, Data Grid cache should not handle business logic owned by the server, such as server-side sorting, especially since it also lacks access to all the data.

If we extract the models which might affect the visibility or positioning of rows when an edit is made, they would be:

Model Reasoning
sortModel Determines row positions; an edit might cause a row to move, requiring a refetch to maintain correct order. The edited row could literally be anywhere, even in the un-fetched chunks.
filterModel Controls row visibility; an edited row may no longer match the filter criteria and needs to be removed or added dynamically.
aggregationModel Affects aggregated values; editing a row could change totals, averages, or other computed metrics, necessitating a refresh.

If any of these models are active, the Data Grid cannot accurately determine the edited row’s position (or what other rows will be impacted with this change) without access to server-side business logic and data, which it does not have. Additionally, it cannot predict which row, if any, should replace a removed one in the current chunk.

The best option I see here is a hybrid approach where we partially reap the benefits of caching with editing.

  • ✅ On every edit operation, if no sorting, filtering, or aggregation is active → Mutate cache entry
    The users fully enjoy the client-side caching benefits in this case

  • ❌ On every edit operation, if any of those models are active → Invalidate cache and refetch the current viewport
    This case would be one of the limitations of the client-side cache, i.e. as soon as an edit is made, the cache has to be cleared.

  • 💡 As an alternative, we could urge the users to consider server-side caching in cases where editing has to be used with one or more of sorting, filtering, and aggregation models, since the server has access to all the data and could provide a more reliable caching.

Lmk how you feel about this approach?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Our cache entries are separated by the sort/filter/aggregation model states so I think that the options that you have listed should always be applied to the entries for those states regardless of the current active state.

So this

✅ On every edit operation, if no sorting, filtering, or aggregation is active → Mutate cache entry
The users fully enjoy the client-side caching benefits in this case

❌ On every edit operation, if any of those models are active → Invalidate cache and refetch the current viewport
This case would be one of the limitations of the client-side cache, i.e. as soon as an edit is made, the cache has to be cleared.

Becomes

On every edit operation → Mutate cache entries without sorting, filtering, or aggregation params in the key and remove other cache entries.

I am not sure if refetch the current viewport is needed. If you don't do it, current page is potentially not cached, but it will be cached next time.
Maybe you will not get to it anymore at all, which will save one request if you don't refetch automatically.

💡 As an alternative, we could urge the users to consider server-side caching in cases where editing has to be used with one or more of sorting, filtering, and aggregation models, since the server has access to all the data and could provide a more reliable caching.

Agree - and pointing to the section with the custom cache feature.

@@ -125,6 +132,9 @@ export const useGridDataSourceBase = <Api extends GridPrivateApiCommunity>(
const cacheResponses = cacheChunkManager.splitResponse(fetchParams, getRowsResponse);
cacheResponses.forEach((response, key) => {
cache.set(key, response);
response.rows.forEach((row) => {
rowIdToGetRowsParams.current[row.id] = fetchParams;
Copy link
Contributor

@arminmeh arminmeh Feb 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

one row will be present in multiple cache keys when sorting/filtering/grouping is applied

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Linked with #16045 (comment), this dictionary will only be used if no such model is active which alters rows' positions or visibility.

@MBilalShafi MBilalShafi marked this pull request as draft February 19, 2025 16:28
MBilalShafi and others added 3 commits February 20, 2025 16:35
Co-authored-by: Armin Mehinovic <4390250+arminmeh@users.noreply.github.com>
Signed-off-by: Bilal Shafi <bilalshafidev@gmail.com>
@MBilalShafi MBilalShafi marked this pull request as ready for review February 24, 2025 10:14
@MBilalShafi MBilalShafi marked this pull request as draft February 24, 2025 10:14

This comment was marked as outdated.

@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged label Feb 24, 2025
@github-actions github-actions bot removed the PR: out-of-date The pull request has merge conflicts and can't be merged label Feb 24, 2025
@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged label Feb 24, 2025

This comment was marked as outdated.

@github-actions github-actions bot removed the PR: out-of-date The pull request has merge conflicts and can't be merged label Feb 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: data grid This is the name of the generic UI component, not the React module! feature: Server integration Better integration with backends, e.g. data source new feature New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[data grid] Support edit functionality with server-side data source
5 participants