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

[Canvas] Layout engine integration simplification #33702

Merged
merged 7 commits into from
Apr 11, 2019

Conversation

monfera
Copy link
Contributor

@monfera monfera commented Mar 22, 2019

Goals:

  • Minimize dependence on Redux (eg. by minimal or no layout middleware and by putting the layout state into Workpad or WorkpadPage component state) to allow alternative data flow concepts eg. Flux, Vuex, FRP, anything
  • Remove the awkwardness of the Redux Store - React WorkpadPage - Layout Engine association, eg. the Map in aeroelastic_kibana.js that herds a set of layout stores
  • General refactoring goals: more approachable, testable, TSable, regular code
  • Component event handlers should have minimal access to layout engine props (eg. to make @cqliu1's context menu, SavedObjects and further keyboard shortcut integration simpler)
  • Unblock progress on bug fixes and feature PRs eg. box select
  • More consistent naming (eg. *Elements -> *Nodes where appropriate; old PR feedback from @w33ble )

Side effects:

Non-goals for this specific PR:

  • fixing bugs (some arose due to convoluted code; others can be fixed with small PRs)
  • adding features (some seemingly simple features eg. box select were in effect blocked)
  • increasing speed, TS use and test coverage (doing code regularization first has some pros)
  • doing ALL the envisioned refactoring (further work can be done more incrementally)
  • refactoring or significantly touching the layout engine itself (there are no reported bugs or performance issues, but all contributors would benefit from code reduction)

Progress:

  • Bypass use the layout engine for non-interactive page rendering - old request from @rashidkpc
  • The aero.commit function no longer has the callback function arg and the meta arg
  • Plain functions got moved out of the layout middleware, temporarily into integration_utils.js
  • Stuff not belonging to the layout middleware got moved elsewhere (fetchAllRenderables)
  • Layout middleware logic (mw/aeroelastic.js and aeroelastic_kibana.js) got removed simplified, esp. the removal of the commit callback and the unification of the logic before next()
  • The layoutProps function is temporarily super verbose, got to do that stuff with a few calls to already existing functions, just copy-pasted initially
  • Verify there's no framerate regression
  • Verify there's no unnecessary persisting into global state
  • Remove the duplication, state synchronization and complexity around element/group selections and keyboard interactions
  • Fix: added image doesn't immediately appear on mini slide
  • Fix known regression: element selection and hover don't clear on page change
  • Fix collapsing mini slide (when slide has an image or table)
  • Fix: deleting the last existing page that has at least one element throws (cloneNode) - related to the aboveindependent issue, see [Canvas] Deleting the last extant page of a workbook throws #34458
  • Fix: grouping outside the Canvas page paper while holding the mouse button breaksindependent issue, see Fix: don't attempt grouping while mouse is down #34448

@monfera monfera added the WIP Work in progress label Mar 22, 2019
@monfera monfera self-assigned this Mar 22, 2019
@monfera monfera requested a review from a team as a code owner March 22, 2019 12:40
@monfera monfera added the Team:Presentation Presentation Team for Dashboard, Input Controls, and Canvas label Mar 22, 2019
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-canvas

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

@monfera monfera changed the title [Canvas][WIP] Layout state simplification [Canvas][WIP][skip ci] Layout state simplification Mar 22, 2019
@monfera monfera force-pushed the state-simplification branch from d9a1689 to bd3af51 Compare March 22, 2019 21:26
@monfera monfera force-pushed the state-simplification branch 2 times, most recently from ace6772 to 7d0f141 Compare March 31, 2019 08:34
@monfera monfera changed the title [Canvas][WIP][skip ci] Layout state simplification [Canvas][WIP] Layout state simplification Mar 31, 2019
@monfera monfera force-pushed the state-simplification branch 3 times, most recently from b41778e to a3688f3 Compare March 31, 2019 11:33
@elastic elastic deleted a comment from elasticmachine Mar 31, 2019
@elasticmachine
Copy link
Contributor

💚 Build Succeeded

@monfera monfera requested review from w33ble and cqliu1 March 31, 2019 12:38
@monfera monfera changed the title [Canvas][WIP] Layout state simplification [Canvas][WIP] Layout engine integration simplification Mar 31, 2019
@monfera monfera requested a review from clintandrewhall March 31, 2019 12:58
@monfera monfera force-pushed the state-simplification branch from a3688f3 to 1a4988c Compare April 8, 2019 13:30
@elasticmachine
Copy link
Contributor

💚 Build Succeeded

Copy link
Contributor

@w33ble w33ble left a comment

Choose a reason for hiding this comment

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

Initial feedback, have not run this yet.

nit: nitpicky stuff you can choose to ignore
Q: question
CR: change requested

also curious if you have plans to slim down the WorkpadPage component in the future, it's a beast now...

@@ -32,6 +33,7 @@ export const routes = [
dispatch(setAssets(assets));
dispatch(setWorkpad(workpad, { loadPages: false }));
dispatch(setPage(pageNumber - 1));
dispatch(selectToplevelNodes([]));
Copy link
Contributor

Choose a reason for hiding this comment

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

Q: Was this just an oversight in the old code, where selected elements were not cleared?

Copy link
Contributor Author

@monfera monfera Apr 8, 2019

Choose a reason for hiding this comment

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

In the old code, we cleared the selection via the middleware (I think circuitously, by clearing it in the aero store which then updated back redux) so it just used a different - and simpler - mechanism there. But glad you asked because:

I'm not proposing this for this PR, but adding this line (and similar ones) made me ponder if our currently fairly lean reducers should be able to do more. For example, here, we issue four dispatches. combineReducers is nice when state slices are truly independent, but it's not possible to implement a new version of setPage that would also vacate the transient.selectedToplevelNodes array. I'm biased toward one user action = one Redux action (sans async stuff like server response) and the Redux doc has a pertinent note on combineReducers.

Copy link
Contributor

Choose a reason for hiding this comment

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

I also prefer to lean towards the 1:1 user action to redux action route.

Would it make sense to update the transientReducer to be watching for any of these "page changed" type actions (add, set, delete, duplicate, etc) and set the selectedTopLevelNodes state to empty array? Rather than having to always dispatch this selectTopLevelNodes action when any kind of page change happens?

if (action is changePage or deletePage or addPage)
  selectedTopLevelElements = []

Copy link
Contributor

Choose a reason for hiding this comment

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

That's probably the better "redux" way, having the transient reducer update based on these actions. So that dispatching only setWorkpad or setPage does what you want without needing to dispatch other actions all the time.

There's a lot of other places we could clean up like that too.

@monfera
Copy link
Contributor Author

monfera commented Apr 8, 2019

also curious if you have plans to slim down the WorkpadPage component in the future, it's a beast now

Yes, agreed! Should I put the wrappers around the (already split) InteractiveWorkpadPage and StaticWorkpadPage in a separate component, in effect, splitting the workpad_page directory into three (one simple, one interactive and one for branching between the two)? As part of this PR? I haven't yet done it on the offchance that this kind of separation (to simple vs interactive) is frowned upon for some technical reason.

@w33ble
Copy link
Contributor

w33ble commented Apr 8, 2019

Should I put the wrappers around the (already split) InteractiveWorkpadPage and StaticWorkpadPage in a separate component, in effect, splitting the workpad_page directory into three (one simple, one interactive and one for branching between the two)? As part of this PR? I haven't yet done it on the offchance that this kind of separation (to simple vs interactive) is frowned upon for some technical reason.

I'm not sure the best way to spit it up, and personally would not do it in this PR anyway. Was just curious if you had future plans. Sounds like yes, which is good enough for me.

},
removePage: id => {
dispatch(pageActions.removePage(id));
dispatch(selectToplevelNodes([]));
Copy link
Contributor

Choose a reason for hiding this comment

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

Minor: If the page being removed is not the one that's currently the interactive one, then the selections are still reset.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch, thanks!

@monfera monfera force-pushed the state-simplification branch from 1a4988c to 49f95b4 Compare April 9, 2019 12:43
@elasticmachine
Copy link
Contributor

💚 Build Succeeded

Copy link
Contributor

@w33ble w33ble left a comment

Choose a reason for hiding this comment

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

LGTM. It would be nice if you removed all the added dispatch(selectToplevelNodes([])) and put that logic in the transient reducer, but I'm not going to block on that.

@snide snide removed v7.0.0 labels Apr 10, 2019
@w33ble w33ble added the v7.2.0 label Apr 11, 2019
@monfera monfera changed the title [Canvas][WIP] Layout engine integration simplification [Canvas] Layout engine integration simplification Apr 11, 2019
@elasticmachine
Copy link
Contributor

💚 Build Succeeded

@monfera monfera merged commit b7871a5 into elastic:master Apr 11, 2019
monfera added a commit to monfera/kibana that referenced this pull request Apr 11, 2019
monfera added a commit that referenced this pull request Apr 11, 2019
@elasticmachine
Copy link
Contributor

💚 Build Succeeded

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
review Team:Presentation Presentation Team for Dashboard, Input Controls, and Canvas v7.2.0 v8.0.0 WIP Work in progress
Projects
None yet
5 participants