Skip to content

Commit

Permalink
fix routing and mounting inner-kibana-app pseudo applications
Browse files Browse the repository at this point in the history
  • Loading branch information
flash1293 committed Oct 16, 2019
1 parent 7ba0352 commit 06146f2
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,8 @@ uiRoutes
template: indexTemplate,
reloadOnSearch: false,
resolve: {
ip: function (Promise, indexPatterns, config, Private) {
ip: function (Promise, /*indexPatterns, config,*/ Private) {
return null;
const State = Private(StateProvider);
return indexPatterns.getCache().then((savedObjects)=> {
/**
Expand All @@ -142,7 +143,8 @@ uiRoutes
});
});
},
savedSearch: function (redirectWhenMissing, savedSearches, $route) {
savedSearch: function (/*redirectWhenMissing, savedSearches,*/ $route) {
return null;
const savedSearchId = $route.current.params.id;
return savedSearches.get(savedSearchId)
.then((savedSearch) => {
Expand Down
3 changes: 2 additions & 1 deletion src/legacy/core_plugins/kibana/public/discover/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import { PluginInitializer, PluginInitializerContext } from 'kibana/public';
import { npSetup, npStart } from 'ui/new_platform';
import { DiscoverPlugin, DiscoverSetup, DiscoverStart } from './plugin';
import { localApplicationService } from '../local_application_service';
import { start as data } from '../../../../../../src/legacy/core_plugins/data/public/legacy';
// Core will be looking for this when loading our plugin in the new platform
export const plugin: PluginInitializer<DiscoverSetup, DiscoverStart> = (
Expand All @@ -28,5 +29,5 @@ export const plugin: PluginInitializer<DiscoverSetup, DiscoverStart> = (
};

const pluginInstance = plugin({} as PluginInitializerContext);
export const setup = pluginInstance.setup(npSetup.core, { data, npData: npStart.plugins.data });
export const setup = pluginInstance.setup(npSetup.core, { data, npData: npStart.plugins.data, localApplicationService });
export const start = pluginInstance.start(npStart.core, { data, npData: npStart.plugins.data });
10 changes: 7 additions & 3 deletions src/legacy/core_plugins/kibana/public/discover/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import { CoreSetup, CoreStart, Plugin, PluginInitializerContext } from 'kibana/public';
import { i18n } from '@kbn/i18n';
import { LocalApplicationService } from '../local_application_service';

import {
FeatureCatalogueRegistryProvider,
Expand Down Expand Up @@ -52,16 +53,19 @@ function registerFeature() {
export type DiscoverSetup = {};
// eslint-disable-next-line @typescript-eslint/prefer-interface
export type DiscoverStart = {};
// eslint-disable-next-line @typescript-eslint/prefer-interface
export type DiscoverSetupDeps = {};
export interface DiscoverSetupDeps {
localApplicationService: LocalApplicationService;
};
// eslint-disable-next-line @typescript-eslint/prefer-interface
export type DiscoverStartDeps = {};

export class DiscoverPlugin implements Plugin<DiscoverSetup, DiscoverStart> {
constructor(initializerContext: PluginInitializerContext) {}
setup(core: CoreSetup, plugins: DiscoverSetupDeps): DiscoverSetup {
registerFeature();
core.application.register({
// TODO once there is a central platform router in place,
// switch this back to core.application.register
plugins.localApplicationService.register({
id: 'discover',
title: 'Discover',
order: -1004,
Expand Down
4 changes: 2 additions & 2 deletions src/legacy/core_plugins/kibana/public/discover/render_app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,8 @@ export async function renderApp(
};
*/

getDiscoverModule();
await import('./angular');
const app = getDiscoverModule();
require('./angular');
const $injector = mountDiscoverApp(appBasePath, element);
return () => $injector.get('$rootScope').$destroy();
}
Expand Down
4 changes: 4 additions & 0 deletions src/legacy/core_plugins/kibana/public/kibana.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ import 'ui/agg_types';
import { showAppRedirectNotification } from 'ui/notify';
import 'leaflet';

import { localApplicationService } from './local_application_service';

localApplicationService.registerWithAngularRouter(routes);

routes.enable();


Expand Down
89 changes: 89 additions & 0 deletions src/legacy/core_plugins/kibana/public/local_application_service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import { ApplicationSetup, App, AppUnmount } from 'kibana/public';
import { UIRoutes } from 'ui/routes';
import { IScope } from 'angular';
import { npStart } from 'ui/new_platform';
import { htmlIdGenerator } from '@elastic/eui';

/**
* To be able to migrate and shim parts of the Kibana app plugin
* while still running some parts of it in the legacy world, this
* service emulates the core application service while using the global
* angular router to switch between apps without page reload.
*
* The id of the apps is used as prefix of the route - when switching between
* to apps, the current application is torn down.
*
* This service becomes unnecessary once the platform provides a central
* router that handles switching between applications without page reload.
*/
export interface LocalApplicationService {
register: ApplicationSetup['register'];
registerWithAngularRouter: (routeManager: UIRoutes) => void;
}

const apps: App[] = [];
const idGenerator = htmlIdGenerator('kibanaAppLocalApp');

let currentlyActiveApp: string | null = null;
let currentlyActiveMountpoint: Element | null = null;

export const localApplicationService: LocalApplicationService = {
register(app) {
apps.push(app);
},
registerWithAngularRouter(angularRouteManager: UIRoutes) {
apps.forEach(app => {
const wrapperElementId = idGenerator();
const routeConfig = {
// marker for stuff operating on the route data.
// This can be used to not execute some operations because
// the route is not actually doing something besides serving
// as a wrapper for the actual inner-angular routes
outerAngularWrapperRoute: true,
template: `<div style="height:100%" id="${wrapperElementId}"></div>`,
controller($scope: IScope) {
const element = document.getElementById(wrapperElementId)!;
if (currentlyActiveMountpoint) {
// re-append the element containing the active app to the DOM
// because the route change causes angular to throw away the current
// template
element.appendChild(currentlyActiveMountpoint);
}
// do not bootstrap the app again if just the tail changed
if (currentlyActiveApp === app.id) {
return;
}
currentlyActiveApp = app.id;
// controller itself is not allowed to be async, use inner IIFE
(async () => {
const onUnmount = await app.mount({ core: npStart.core }, { element, appBasePath: '' });
currentlyActiveMountpoint = element.firstElementChild;
$scope.$on('$destroy', () => {
onUnmount();
});
})();
},
};
angularRouteManager.when(`/${app.id}/:tail*?`, routeConfig);
});
},
};

0 comments on commit 06146f2

Please sign in to comment.