-
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
[discuss] Global state & URLs in the New Platform #39855
Comments
Pinging @elastic/kibana-platform |
Pinging @elastic/kibana-app-arch |
I was wondering: what if each plugin had a namespace for its state in URL (in this example above:
From there, it would be the plugin's responsibility (here the Timepicker) to have the logic in place to read and subscribe to URL changes (through a HOC probably) and update its state. And all the other plugin (the consumers) would simply subscribe to the timepicker'state. So the HOC that would wrap the Timepicker plugin would
The consumer of the plugin would simply:
From what I understood, in your proposal if there are 2 or more timepicker consumer plugin on the page, they would all 3 read the URL and set the state on the Timepicker? @joshdover |
How can user copy URL now and do not lose the date value? |
I believe this discussion is complete now with the new State Sync service available. Closing, but feel free to reopen if there are unresolved issues. |
In this issue I want to describe how shared global state is consumed and modified by applications, and how that relates to any state present in the current URL.
Related:
Context
In the legacy platform, there is ever only 1 plugin "running" at a time. Yes, there are exceptions, such as the "hacks" uiExport which allows any plugin to run some code on any page. But in general, a single plugin has control of the entire browsing context at a time.
Additionally, each legacy plugin runs in the context of
ui/chrome
's global Angular.js application, along with all of the global behaviors and goodies. This includes a single global router.This design choice makes syncing UI state tricky:
href
in the navbar to have the same URL state.What's different now
In the New Platform:
This is all great, but at the end of the day, plugins still need to share UI state that is relevant to most plugins.
The proposal
Goals:
The basis of my proposal is that any "global state plugin", that is a plugin that manages state for other plugins (eg. timepicker), should expose functions for reading and writing state, but should never integrate automatically with any URL updates.
Data flow
Based on the Application RFC, the data flow of mounting an application looks like this:
http://localhost:5601/myBasePath/app/dashboard/dash/1234?timepicker=2019-01-01
/myBasePath/app/dashboard
"basename". (It's internal route would be/dash/1234?timepicker=2019-01-01
).<Dash />
component).<Dash />
component uses the current URL to update thetimepicker
plugin's state.<Dash />
component subscribes to future timepicker state updates.Timepicker Updates
2020-05-05
via the timepicker UI.history.push()
call on its router.Switching apps
Let's say the user navigates to
http://localhost:5601/myBasePath/app/apm
:/myBasePath/app/apm
"basename". (It's internal route would be/
).<Home />
component).<Home />
component doesn't see anytimepicker
query parameter, so it does not update the timepicker.<Home />
component subscribes to timepicker state updates, which will start with previous state:2020-05-05
.Full example
Here is a full example demonstrating the flow above. This example is the boilerplate-filled one without any of the ergonomics mentioned in the next section. This is meant to show explicitly how this all fits together.
The glue code for wiring up an application with a router:
The component that does the state syncing with the URL:
Making this easy
There's many different ways that consuming and combining these different states can be made easier. Below are just some ideas.
Plugins that expose global behavior should provide utilities for serializing and deserializing query param state. For instance, the timepicker plugin could expose:
One challenge with this is that multiple states need to be synced to the same query string. We could introduce an interface that plugins can implement to hook into a shared sync object:
To make this even simpler, hooks or a HOC can be used to handle this syncing of state to the URL bar. Though this may seem like global syncing, it is not because each application must opt in explicitly, which avoids some of the bad behaviors listed above.
The text was updated successfully, but these errors were encountered: