-
Notifications
You must be signed in to change notification settings - Fork 8.2k
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
Replace gridster with react-grid-layout #13853
Replace gridster with react-grid-layout #13853
Conversation
98f72bc
to
e3925d1
Compare
7c7923f
to
8571931
Compare
s3 upload error Jenkins, test this |
b794cf5
to
ac601d9
Compare
s3 error again, technically all the tests passed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is great work, all of the additional tests are just great.
The following error is being logged in the Browser console:
warning.js:36 Warning: Failed prop type: The prop `onPanelUpdated` is marked as required in `DashboardGrid`, but its value is `undefined`.
in DashboardGrid
angular.js:14642 TypeError: onPanelUpdated is not a function
at dashboard_grid.js:103
at Array.forEach (<anonymous>)
at Object.DashboardGrid._this.onLayoutChange (dashboard_grid.js:91)
at ReactGridLayout.onLayoutMaybeChanged (ReactGridLayout.js:204)
at ReactGridLayout.componentDidMount (ReactGridLayout.js:66)
at ReactCompositeComponent.js:264
at measureLifeCyclePerf (ReactCompositeComponent.js:75)
at ReactCompositeComponent.js:263
at CallbackQueue.notifyAll (CallbackQueue.js:76)
at ReactReconcileTransaction.close (ReactReconcileTransaction.js:80)
Apparently unrelated, the batched requests that courier does are behaving weirdly on master
and I'm seeing 2 _msearch
calls for a dashboard with 2 of the same visualization. I noticed the behavior initially with this PR and thought that the asynchronous manner that we were called this.embeddableHandler.render
was the culprit, but the behavior is present before these changes. Definitely something we should keep an eye on, to ensure this PR doesn't have any impact as well.
|
||
this.containerApi = getContainerApi(); | ||
this.embeddableHandler = getEmbeddableHandler(panel.type); | ||
const editUrl = await this.embeddableHandler.getEditPath(panel.id); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we were to change this code to:
this.embeddableHandler.getEditPath(panel.id).then(editUrl => this.setState({ editUrl }));
this.embeddableHandler.getTitleFor(panel.id).then(title => this.setState({ title }));
it'd be roughly in-line with the first "not a warning" case outline here, with the sole difference being they're using callbacks instead of Promise.
Even with Redux, we'll still be using actions to queue off async actions in ComponentDidMount, but the updated data will be coming through via our props
as opposed to the state.
/* eslint-disable react/no-did-mount-set-state */ | ||
this.setState({ editUrl, title }); | ||
|
||
this.destroyEmbeddable = await this.embeddableHandler.render( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are we waiting for the title/editUrl to be available before calling this.embeddableHandler.render
they don't seem to be dependent on each other? If we did the above suggestion, and queued off this async request immediately, I'm not seeing the reason for us to track the _isMounted
, but we could just use the this.destroyEmbeddable !== null)
check directly in the componentDidUnmount
call.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I need isMounted check before the setStates or I can get:
Warning: setState(...): Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component. This is a no-op. Please check the code for the DashboardPanel component.
I can still use your above suggestion but I don't think I can get rid of isMounted. Instead it will look like this:
this.embeddableHandler.getEditPath(panel.id).then(editUrl => {
if (this._isMounted) { this.setState({ editUrl }); }
});
/* eslint-disable react/no-did-mount-set-state */
this.embeddableHandler.getTitleFor(panel.id).then(title => {
if (this._isMounted) { this.setState({ title }); }
});
this.destroyEmbeddable = await this.embeddableHandler.render(
this.panelElement,
panel,
this.containerApi);
fwiw, the redux variation gets rid of all this. I actually changed this.embeddableHandler.render to return an Embeddable, which contains state for the rendered embeddable, including title and editUrl - so there is only one async call, not three - https://github.com/elastic/kibana/pull/14103/files#diff-a18d16d17e2c646a166a4d5523608fbfR86/
Why are we waiting for the title/editUrl to be available before calling this.embeddableHandler.render
Wasn't intentional, I just liked the await syntax. Updated to your suggestion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, gotcha. Pretty excited about the redux changes coming, that makes sense.
Code from the redux PR snuck into this one.
…t on the return value of one before starting the others.
All my concerns have been addressed, once CI goes green you'll have my LGTM! |
…/replace-dashboard-grid
…g to be true when it shouldn't be
I discovered an issue with the panels being unmounted/mounted too frequently and causing slow dashboard refreshes on edit/view mode change, due to this bug: react-grid-layout/react-grid-layout#240. Found another bug where the grid was being rendered with width 0, then not rerendered, showing all the panels shoved to one side. |
…ed while a panel is expanded.
…include them in the chain for Dash only mode but not in that file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
* Initial check-in to replace gridster with react-grid-layout and reactify panels * # This is a combination of 3 commits. # This is the 1st commit message: Add margin of error to test determining panel widths # This is the commit message #2: use real kibana version when creating panel data. Will make future conversions easier. # This is the commit message #3: Fix lint errors * Add margin of error to test determining panel widths use real kibana version when creating panel data. Will make future conversions easier. Move default height and width to dashboard_constants so those that need it don't end up including extra stuff like ui/chrome * Remove unnecessary _.once when creating react directives in dashboard.js * Remove unnecessary constructors * Use componentDidMount instead of componentWillMount bc of async calls, and handle case where destroyEmbeddable is not defined. * Remove unnecessary null in classNames * Use loads defaultsDeep instead of Object.assign * use render* instead of get* for functions returning an element * use relative css paths * Use local import path * Switch to local imports and remove need for plugins path in jest tests * Improve accessibility of max/min panel toggle icon * remove unused css Had to implement this via code * disable eslint rule for setState in componentDidMount Am not aware of a better way to handle this, aside from switching to redux, since it’s recommended not to put async calls in componentWillMount. Since I plan to investigate redux next, disabling for now. Open to other’s opinions on the matter. * Use native map instead of lodash * Have the grid handle setting the z-indexes of the right reactgriditem * Make the draggable handle the title, not the whole heading Otherwise the drag event often takes over click events when trying to open the panel options menu and it gets really annoying. * Change from click to mouse down detector in KuiOutsideClickDector so drags also close pop ups. * Fix mistaken commit Code from the redux PR snuck into this one. * Run getEditPath and getTitle async calls in parallel - no need to wait on the return value of one before starting the others. * Fix tests: update snapshots, add promise returns. * version being added to panelData in the wrong spot caused isDirty flag to be true when it shouldn't be * Fix unmounting/mounting problem with panels due to view/edit mode switch * Fix bug where panels get squashed to one side when view mode is changed while a panel is expanded. * Update snapshots to match wrong view mode comparison * Improve naming of a variable * Fix issue with pop over hiding behind tile maps * Previous panel.js included ui/doc_table and ui/visualize - needed to include them in the chain for Dash only mode but not in that file. * Fix bad merge: remove baseline screenshots
* Initial check-in to replace gridster with react-grid-layout and reactify panels * # This is a combination of 3 commits. # This is the 1st commit message: Add margin of error to test determining panel widths # This is the commit message #2: use real kibana version when creating panel data. Will make future conversions easier. # This is the commit message #3: Fix lint errors * Add margin of error to test determining panel widths use real kibana version when creating panel data. Will make future conversions easier. Move default height and width to dashboard_constants so those that need it don't end up including extra stuff like ui/chrome * Remove unnecessary _.once when creating react directives in dashboard.js * Remove unnecessary constructors * Use componentDidMount instead of componentWillMount bc of async calls, and handle case where destroyEmbeddable is not defined. * Remove unnecessary null in classNames * Use loads defaultsDeep instead of Object.assign * use render* instead of get* for functions returning an element * use relative css paths * Use local import path * Switch to local imports and remove need for plugins path in jest tests * Improve accessibility of max/min panel toggle icon * remove unused css Had to implement this via code * disable eslint rule for setState in componentDidMount Am not aware of a better way to handle this, aside from switching to redux, since it’s recommended not to put async calls in componentWillMount. Since I plan to investigate redux next, disabling for now. Open to other’s opinions on the matter. * Use native map instead of lodash * Have the grid handle setting the z-indexes of the right reactgriditem * Make the draggable handle the title, not the whole heading Otherwise the drag event often takes over click events when trying to open the panel options menu and it gets really annoying. * Change from click to mouse down detector in KuiOutsideClickDector so drags also close pop ups. * Fix mistaken commit Code from the redux PR snuck into this one. * Run getEditPath and getTitle async calls in parallel - no need to wait on the return value of one before starting the others. * Fix tests: update snapshots, add promise returns. * version being added to panelData in the wrong spot caused isDirty flag to be true when it shouldn't be * Fix unmounting/mounting problem with panels due to view/edit mode switch * Fix bug where panels get squashed to one side when view mode is changed while a panel is expanded. * Update snapshots to match wrong view mode comparison * Improve naming of a variable * Fix issue with pop over hiding behind tile maps * Previous panel.js included ui/doc_table and ui/visualize - needed to include them in the chain for Dash only mode but not in that file. * Fix bad merge: remove baseline screenshots
Replaces gridster with react-grid-layout and and reactifies the dashboard panels and headers.
Makes some UI changes that are nearer inline with k7:
Also allows moving the panel on the entire panel header, no longer just on a move icon, which has been something requested for awhile (#7927)
As for placing panels, I had to manually come up with an algorithm to find the best spot because the default that react-grid-layout gives isn't great, and doesn't match prior functionality. It will find the first spot that fits the new panel with first the lowest y value then the lowest x.