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

[State Management] - Remove GlobalState from dashboard #55158

Merged

Conversation

Dosant
Copy link
Contributor

@Dosant Dosant commented Jan 17, 2020

Summary

Part of #44151
Removes GlobalState from dashboard app
depends on #54105

Open for discussion: #55339 where to put and how to abstract syncing filters & time - https://github.com/elastic/kibana/pull/55158/files#diff-5e89f9f26cbd7f233495a2e97789a306R51
And how to make syncing of not "pinned" filters not an application concern - https://github.com/elastic/kibana/pull/55158/files#diff-47ad20cc6caa58a3e9c204106013514fR151

Checklist

Use strikethroughs to remove checklist items you don't feel are applicable to this PR.

For maintainers

@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-app-arch (Team:AppArch)

@Dosant Dosant added v8.0.0 v7.7.0 Feature:Dashboard Dashboard related features release_note:skip Skip the PR/issue when compiling release notes labels Jan 21, 2020
@Dosant Dosant marked this pull request as ready for review January 21, 2020 12:27
@Dosant Dosant requested review from a team, flash1293, ppisljar and lizozom January 21, 2020 12:27
@Dosant Dosant changed the title [wip][State Management] - Remove GlobalState from dashboard [State Management] - Remove GlobalState from dashboard Jan 21, 2020
@Dosant Dosant force-pushed the dev/state-management/global-state-dashboard branch from 51043ea to c567e32 Compare January 21, 2020 14:40
@Dosant Dosant force-pushed the dev/state-management/global-state-dashboard branch from b60cad0 to 79850bf Compare January 22, 2020 10:28
Copy link
Contributor

@flash1293 flash1293 left a comment

Choose a reason for hiding this comment

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

It seems like the browser history isn't written correctly in all cases when filters get pinned.

To reproduce:

  • Create filter pill
  • Pin the filter
  • Change something in the pilled filter (e.g. invert)
  • Press back button (action gets undone correctly)
  • Press back button again (I would expect the filter to become unpinned) -> nothing happens
  • Press back button again -> filter disappears completely and I can't go forward anymore (history is lost)

src/plugins/data/public/query/state_sync/sync_filters.ts Outdated Show resolved Hide resolved
Copy link
Contributor

@lizozom lizozom left a comment

Choose a reason for hiding this comment

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

Overall looks good.
Added another minor comment.

Copy link
Contributor

@flash1293 flash1293 left a comment

Choose a reason for hiding this comment

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

Tested and everything works fine for me, thanks for this! I left one comment suggesting light restructuring that would make the code safer and easier to get IMHO, but I don't consider it a blocker because I will continue working on that area of the code soon.


export const renderApp = (element: HTMLElement, appBasePath: string, deps: RenderDeps) => {
const history = createHashHistory();
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: We could put that part into a function initGlobalStateHandling that is called in the dashboard controller in src/legacy/core_plugins/kibana/public/dashboard/np_ready/dashboard_app_controller.tsx and in the listing controller in src/legacy/core_plugins/kibana/public/dashboard/np_ready/legacy_app.js - initGlobalStateHandling would return a function that stops the syncing and can be registered within the controller using $scope.$on('$destroy', () => {. Then we don't need a reference on the application level and don't need to overwrite typescripts type checks

Copy link
Contributor Author

@Dosant Dosant Jan 24, 2020

Choose a reason for hiding this comment

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

thanks, looks better 👍
Hope I got it right.
3a51104

@@ -76,7 +76,7 @@ export class ReplacePanelFlyout extends React.Component<Props> {
// add the new view
const newObj = await this.props.container.addSavedObjectEmbeddable(type, id);

const finalPanels = this.props.container.getInput().panels;
const finalPanels = _.cloneDeep(this.props.container.getInput().panels);
Copy link
Contributor

Choose a reason for hiding this comment

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

What changed here, that made you clone the panels?

Copy link
Contributor Author

@Dosant Dosant Jan 27, 2020

Choose a reason for hiding this comment

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

State containers deeply freeze the object in dev mode, which allows to find places where we unintentionally mutate objects passed into services. The freezing pointed me to this replace_panel_flyout:

  1. Tweaked the code to not directly mutate original panels
  2. Fixed the call container.updateInput(finalPanels) -> container.updateInput({panels: finalPanels). Typescript didn't complain because updates

We discussed it with @streamich.
And in the end I decided that it would be easier to fix this piece of code in replace_panel_flyout then making sure that all places where data is passed from state container into embeddable container is cloneDeeped

public static setFiltersStore(
filters: esFilters.Filter[],
store: esFilters.FilterStateStore,
shouldOverrideStore = false
Copy link
Contributor

Choose a reason for hiding this comment

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

Why did you have to add this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

These make sense to me in case of setGlobalFilters and setAppFilters.
This what I was thinking:

  1. In both of those methods we need to handle the case, when filters with incorrect "$store" value are passed in
  2. We have couple options then:
  • Just ignore such and do nothing
  • Throw an error
  • Override - I went with this one.

@lizozom
Copy link
Contributor

lizozom commented Jan 26, 2020

@elasticmachine merge upstream

@kibanamachine
Copy link
Contributor

💚 Build Succeeded

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

Copy link
Contributor

@lizozom lizozom left a comment

Choose a reason for hiding this comment

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

Tested and seems to be working.

I think the external APIs for syncing can be improved, but for now, this is a good step forward.
However, I wouldn't implement this solution in other plugins before improving the interfaces in a follow up PR.
I'll create an issue to discuss this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature:Dashboard Dashboard related features release_note:skip Skip the PR/issue when compiling release notes review v7.7.0 v8.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants