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

Only update dashboard positions when necessary #4530

Merged
merged 3 commits into from
Feb 23, 2018
Merged

Only update dashboard positions when necessary #4530

merged 3 commits into from
Feb 23, 2018

Conversation

edmundoa
Copy link
Contributor

This PR makes some modifications in the web interface to be smarter calculating and updating dashboard positions:

  1. Avoid callbacks when clicking on an action button in a widget. This is what made Concurrent requests when removing widget may persist it again #4525 too likely to happen
  2. Only compute layout when positions change, instead of doing it on every render
  3. Ensure there are layout changes before calling the onLayoutChange callback, avoiding doing unnecessary updates in the server

In order to fix the issue in 2.4, I think we should only backport change number 1, avoiding to introduce any other potential issues in the stable release. I can take care of that once this PR is reviewed.

Before a solution for #4527 lands, these changes fix #4525.

Edmundo Alvarez added 3 commits January 25, 2018 12:09
Clicking anywhere on an unlocked widget generates a drag event, which in
our case ends up sending a request to the server to update widgets
positions.
Use React Grid Layout `draggableCancel` prop, to avoid calling drag
callbacks when a user clicks on the edit or delete buttons for a widget.
Optimize the number of times we compute and update the layout of a
ReactGridContainer component:
- Compute ReactGridContainer when the `positions` prop changes
- Compare layout changes with the current computed layout to only call
  `onPositionsChange` when the layout did actually change

This will reduce the number of times the layout of a ReactGridContainer
component is computed and, more importantly, the number of update
positions requests we send to the server.
@edmundoa edmundoa added the bug label Jan 25, 2018
@edmundoa edmundoa added this to the 3.0.0 milestone Jan 25, 2018
@ghost ghost assigned edmundoa Jan 25, 2018
@ghost ghost added the in progress label Jan 25, 2018
@edmundoa
Copy link
Contributor Author

Oh, I forgot: I tried to write some tests to check how well the changes worked but it end up being too complicated. To test the functionality we need that react-grid-layout works but with enzyme it can only go to a point. I gave up after I needed to stub a couple of HTMLElement properties that do not seem to be implemented in the DOM implementation used for the tests.

// `onLayoutChange` may be triggered when clicking somewhere in a widget, check before propagating the change.
// Filter out additional Object properties in nextLayout, as it comes directly from react-grid-layout
const filteredNewLayout = newLayout.map(item => ({ i: item.i, x: item.x, y: item.y, h: item.h, w: item.w }));
if (lodash.isEqual(this.state.layout, filteredNewLayout)) {
Copy link
Member

Choose a reason for hiding this comment

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

Would it make sense to move this kind of check into shouldComponentUpdate and keep the component stateless?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think so, as this callback is used by react-grid-layout to notify when a widget is dragged or resized and it's not modifying the state or deciding if the component should re-render. The check it's avoiding to call a prop when the layout didn't change.

@edmundoa
Copy link
Contributor Author

edmundoa commented Feb 5, 2018

@dennisoelkers do you have any other comments on this? :)

@edmundoa
Copy link
Contributor Author

@dennisoelkers did you find any time to look at this? I'm afraid more changes will come soon in these components and we will have to solve conflicts in them.

Copy link
Member

@kmerz kmerz left a comment

Choose a reason for hiding this comment

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

LGTM
I checked out and tested the code after a rebase with master and it worked just fine 👍

@kmerz kmerz merged commit 9488608 into master Feb 23, 2018
@edmundoa edmundoa deleted the issue-4525 branch February 23, 2018 11:44
edmundoa pushed a commit that referenced this pull request May 28, 2018
Clicking anywhere on an unlocked widget generates a drag event, which in
our case ends up sending a request to the server to update widgets
positions.
Use React Grid Layout `draggableCancel` prop, to avoid calling drag
callbacks when a user clicks on the edit or delete buttons for a widget.

Partial backport of 9488608 (#4530).
Mitigates #4525
bernd pushed a commit that referenced this pull request May 28, 2018
Clicking anywhere on an unlocked widget generates a drag event, which in
our case ends up sending a request to the server to update widgets
positions.
Use React Grid Layout `draggableCancel` prop, to avoid calling drag
callbacks when a user clicks on the edit or delete buttons for a widget.

Partial backport of 9488608 (#4530).
Mitigates #4525
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Concurrent requests when removing widget may persist it again
3 participants