-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
[browser] Application service #18843
Comments
The exploration below resulted in us deciding against using iframes. I've done some exploration on syncing the
One of the hairy parts of rendering inside iframes would be getting the actual application to load inside the iframe and still be able to access core services or plugin-specific code. One way I think of solving this would be to require that applications provide a separate entry file that the ApplicationService would load for them. This entry bundle could expose a // plugin.js
class Plugin {
setup(core) {
core.applicationService.registerApplication({
name: 'Dashboard',
route: '/dashboard',
icon: <EuiIcon type="dashboardApp" />,
entryPoint: './my_entry_point.js',
// Application service would call window.mount with this array
// as it's args.
mountArgs: [{
kfetch: core.kfetch,
myService: {
getObj() { ... },
}
}]
});
}
}
// my_entry_point.js
window.__kbnMount__ = (targetDomElement, { kfetch, myService }) => {
ReactDOM.mount(<MyApp />, targetDomElement);
return () => {
ReactDOM.unmountComponentAtNode(targetDomElement);
};
}; This would introduce an implicit contract where the app service executes This method would provide us more "sandboxing" which could be particularly useful for 3rd-party plugins. They may not know about our custom angular-route hacks to make Angular.js v1 work on new Kibana. Any other frameworks they use that do any global monkey-patching would be safe to use. The downside is that this solution is brittle, could break in some browsers (so far, I've only tested in Firefox), and may introduce security concerns that need to be handled. |
@eliperelman and I synced today and here is our tentative plan: Moved to description above |
After some investigations on (3) above, I've decided that completely moving the "lastSubUrl" feature into plugins is not feasible until plugins are on the new platform. The reason for this boils down to the fact that a legacy Angular app does not know when it is being "mounted" by Chrome vs. the user trying to get back to the root of the app. Without this, an individual plugin cannot make the decision of whether or not they should redirect to the last known location or render the root of the app. Instead, I will modify the existing lastSubUrl logic to manually modify navLinks in the new platform ChromeService. However, I will not expose this functionality to new platform plugins. New platform plugins will have to handle this feature themselves, by tracking route changes in their app and redirecting to the last location in their ApplicationService mount callback. |
Where I can find a discussion about introducing that approach and why we need to use it? |
@restrry It was being explored as an option when figuring out how best to support angular apps in the new platform. We have since decided against it and are moving forward with fixing Angular's URL encoding bugs instead. I apologize this wasn't recorded anywhere, happened in a flurry of video calls. |
Part of our plain entails building out in parallel a few of the pieces (shell AppService, moving Nav APIs to new platform, adding AppService routing). We don't want to merge an incomplete AppService that may confuse other developers. We've decided to open a branch for us to collaborate on together so we can make sure these pieces fit together well before merging to master. @eliperelman has opened the application-service branch on the root repo. We may still merge a feature-complete AppService to master before turning it on for routing and bootstrapping of legacy apps. |
One snag I've encountered when moving NavLinks to Core is Feature Controls. Feature controls currently rely on This is all done with server-side code in the plugin, which is incompatible with new platform plugins which can be client-only (a hard requirement). Additionally, we may want to allow plugins to conditionally register applications, or register them based on some data fetched from elsewhere, so a static spec solution here will not work (eg. adding a list of applications to kibana.json). I've talked this over with @kobelb and have come up with a PoC. In order to support Feature Controls and the design goals of the ApplicationService, I propose that:
Implementation DetailsIn the initial implementation of this, I believe we will have to use an Observable of registered applications since this list is not guaranteed to be "finalized" in any point during the "setup" lifecycle event. Once we have a "start" lifecycle event, we will be able to change this to a single fetch, without the complexities of an Observable. With the new dependencies between services (ApplicationService, Capabilities, ChromeService) I also plan to move Capabilities to be a sub-component of the ApplicationService. Reason being is that Capabilities depends on ApplicationService's |
The client-side application service handles registering new applications. It should expose a client for mounting and unmounting applications, which will ultimately be used as a sort of base router in the UI. It might also want to manage application state, like whether the application is disabled or not, or at least provide a mechanism to plugins to indicate state.
Routing RFC: #36477
Execution plan
Fix Angular's broken URL encoding/decoding (Handle encoding and decoding of angular route url components #34300). This is necessary because we want to avoid any problems with malformed URLs being created by any apps that choose to use Angular in the new platform. Malformed URLs would break any root-level routing done by the application service in some scenarios.We are not planning to do unless we know for a fact that support for Angular plugins is critical in the New Platform.kbn-chrome
directive for rendering legacy apps.legacy
property to NavLinks registered by legacy apps #41301). This is a small cleanup PR to make implementing AppService easier.The text was updated successfully, but these errors were encountered: