From ccf11ecb365cc26399b06ddc36918e24fe7137e5 Mon Sep 17 00:00:00 2001 From: Corey Robertson Date: Wed, 11 Mar 2020 11:27:57 -0400 Subject: [PATCH] Move canvas setup into app mount --- .../plugins/canvas/public/application.tsx | 73 +++++++++++- .../canvas/public/lib/run_interpreter.ts | 6 +- .../legacy/plugins/canvas/public/plugin.tsx | 107 ++---------------- .../plugins/canvas/public/registries.ts | 44 +------ 4 files changed, 94 insertions(+), 136 deletions(-) diff --git a/x-pack/legacy/plugins/canvas/public/application.tsx b/x-pack/legacy/plugins/canvas/public/application.tsx index 15b5d2543fbc6..e26157aadebcb 100644 --- a/x-pack/legacy/plugins/canvas/public/application.tsx +++ b/x-pack/legacy/plugins/canvas/public/application.tsx @@ -8,14 +8,26 @@ import React from 'react'; import { Store } from 'redux'; import ReactDOM from 'react-dom'; import { I18nProvider } from '@kbn/i18n/react'; +import { i18n } from '@kbn/i18n'; import { Provider } from 'react-redux'; -import { AppMountParameters, CoreStart } from 'kibana/public'; +import { AppMountParameters, CoreStart, CoreSetup } from 'kibana/public'; -import { CanvasStartDeps } from './plugin'; +import { CanvasStartDeps, CanvasSetupDeps } from './plugin'; // @ts-ignore Untyped local import { App } from './components/app'; import { KibanaContextProvider } from '../../../../../src/plugins/kibana_react/public'; +import { initInterpreter, resetInterpreter } from './lib/run_interpreter'; +import { registerLanguage } from './lib/monaco_language_def'; +import { SetupRegistries } from './plugin_api'; +import { initRegistries, populateRegistries, destroyRegistries } from './registries'; +import { getDocumentationLinks } from './lib/documentation_links'; +// @ts-ignore untyped component +import { HelpMenu } from './components/help_menu/help_menu'; +import { createStore } from './store'; + +import { CapabilitiesStrings } from '../i18n'; +const { ReadOnlyBadge: strings } = CapabilitiesStrings; export const renderApp = ( coreStart: CoreStart, @@ -35,3 +47,60 @@ export const renderApp = ( ); return () => ReactDOM.unmountComponentAtNode(element); }; + +export const initializeCanvas = async ( + coreSetup: CoreSetup, + coreStart: CoreStart, + setupPlugins: CanvasSetupDeps, + startPlugins: CanvasStartDeps, + registries: SetupRegistries +) => { + // Create Store + const canvasStore = await createStore(coreSetup, setupPlugins); + + // Init Interpreter + initInterpreter(startPlugins.expressions, setupPlugins.expressions).then(() => { + registerLanguage(Object.values(startPlugins.expressions.getFunctions())); + }); + + // Init Registries + initRegistries(); + populateRegistries(registries); + + // Set Badge + coreStart.chrome.setBadge( + coreStart.application.capabilities.canvas && coreStart.application.capabilities.canvas.save + ? undefined + : { + text: strings.getText(), + tooltip: strings.getTooltip(), + iconType: 'glasses', + } + ); + + // Set help extensions + coreStart.chrome.setHelpExtension({ + appName: i18n.translate('xpack.canvas.helpMenu.appName', { + defaultMessage: 'Canvas', + }), + links: [ + { + linkType: 'documentation', + href: getDocumentationLinks().canvas, + }, + ], + content: domNode => () => { + ReactDOM.render(, domNode); + }, + }); + + return canvasStore; +}; + +export const teardownCanvas = (coreStart: CoreStart) => { + destroyRegistries(); + resetInterpreter(); + + coreStart.chrome.setBadge(undefined); + coreStart.chrome.setHelpExtension(undefined); +}; diff --git a/x-pack/legacy/plugins/canvas/public/lib/run_interpreter.ts b/x-pack/legacy/plugins/canvas/public/lib/run_interpreter.ts index d2f4cca8fe97d..fbbaf0ccf280e 100644 --- a/x-pack/legacy/plugins/canvas/public/lib/run_interpreter.ts +++ b/x-pack/legacy/plugins/canvas/public/lib/run_interpreter.ts @@ -11,7 +11,7 @@ import { notify } from './notify'; import { CanvasStartDeps, CanvasSetupDeps } from '../plugin'; -let expressionsStarting: Promise; +let expressionsStarting: Promise | undefined; export const initInterpreter = function( expressionsStart: CanvasStartDeps['expressions'], @@ -30,6 +30,10 @@ async function startExpressions( return expressionsStart; } +export const resetInterpreter = function() { + expressionsStarting = undefined; +}; + interface Options { castToRender?: boolean; } diff --git a/x-pack/legacy/plugins/canvas/public/plugin.tsx b/x-pack/legacy/plugins/canvas/public/plugin.tsx index 6644b927dd884..0a3faca1a2522 100644 --- a/x-pack/legacy/plugins/canvas/public/plugin.tsx +++ b/x-pack/legacy/plugins/canvas/public/plugin.tsx @@ -4,29 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ -import React from 'react'; -import ReactDOM from 'react-dom'; import { Chrome } from 'ui/chrome'; -import { i18n } from '@kbn/i18n'; import { CoreSetup, CoreStart, Plugin } from '../../../../../src/core/public'; import { HomePublicPluginSetup } from '../../../../../src/plugins/home/public'; -// @ts-ignore: Untyped Local -import { CapabilitiesStrings } from '../i18n'; -const { ReadOnlyBadge: strings } = CapabilitiesStrings; - -import { createStore } from './store'; - -// @ts-ignore: untyped local component -import { HelpMenu } from './components/help_menu/help_menu'; -// @ts-ignore: untyped local -import { loadExpressionTypes } from './lib/load_expression_types'; -// @ts-ignore: untyped local -import { loadTransitions } from './lib/load_transitions'; import { initLoadingIndicator } from './lib/loading_indicator'; -import { getDocumentationLinks } from './lib/documentation_links'; - -// @ts-ignore: untyped local -import { initClipboard } from './lib/clipboard'; import { featureCatalogueEntry } from './feature_catalogue_entry'; import { ExpressionsSetup, ExpressionsStart } from '../../../../../src/plugins/expressions/public'; // @ts-ignore untyped local @@ -34,29 +15,12 @@ import { datasourceSpecs } from './expression_types/datasources'; // @ts-ignore untyped local import { argTypeSpecs } from './expression_types/arg_types'; import { transitions } from './transitions'; -import { registerLanguage } from './lib/monaco_language_def'; - -import { initInterpreter } from './lib/run_interpreter'; import { legacyRegistries } from './legacy_plugin_support'; -import { getPluginApi, CanvasApi, SetupRegistries } from './plugin_api'; -import { - initRegistries, - addElements, - addTransformUIs, - addDatasourceUIs, - addModelUIs, - addViewUIs, - addArgumentUIs, - addTagUIs, - addTemplates, - addTransitions, -} from './registries'; - +import { getPluginApi, CanvasApi } from './plugin_api'; import { initFunctions } from './functions'; - import { CanvasSrcPlugin } from '../canvas_plugin_src/plugin'; - export { CoreStart }; + /** * These are the private interfaces for the services your plugin depends on. * @internal @@ -89,36 +53,36 @@ export interface CanvasStart {} // eslint-disable-line @typescript-eslint/no-emp /** @internal */ export class CanvasPlugin implements Plugin { - private expressionSetup: CanvasSetupDeps['expressions'] | undefined; - private registries: SetupRegistries | undefined; - public setup(core: CoreSetup, plugins: CanvasSetupDeps) { const { api: canvasApi, registries } = getPluginApi(plugins.expressions); - this.registries = registries; core.application.register({ id: 'canvas', title: 'Canvas App', async mount(context, params) { // Load application bundle - const { renderApp } = await import('./application'); - - // Setup our store - const canvasStore = await createStore(core, plugins); + const { renderApp, initializeCanvas, teardownCanvas } = await import('./application'); // Get start services const [coreStart, depsStart] = await core.getStartServices(); - return renderApp(coreStart, depsStart, params, canvasStore); + const canvasStore = await initializeCanvas(core, coreStart, plugins, depsStart, registries); + + const unmount = renderApp(coreStart, depsStart, params, canvasStore); + + return () => { + unmount(); + teardownCanvas(coreStart); + }; }, }); plugins.home.featureCatalogue.register(featureCatalogueEntry); - this.expressionSetup = plugins.expressions; // Register Legacy plugin stuff canvasApi.addFunctions(legacyRegistries.browserFunctions.getOriginalFns()); canvasApi.addElements(legacyRegistries.elements.getOriginalFns()); + canvasApi.addTypes(legacyRegistries.types.getOriginalFns()); // TODO: Do we want to completely move canvas_plugin_src into it's own plugin? const srcPlugin = new CanvasSrcPlugin(); @@ -137,53 +101,6 @@ export class CanvasPlugin public start(core: CoreStart, plugins: CanvasStartDeps) { initLoadingIndicator(core.http.addLoadingCountSource); - initRegistries(); - - if (this.expressionSetup) { - const expressionSetup = this.expressionSetup; - initInterpreter(plugins.expressions, expressionSetup).then(() => { - registerLanguage(Object.values(plugins.expressions.getFunctions())); - }); - } - - if (this.registries) { - addElements(this.registries.elements); - addTransformUIs(this.registries.transformUIs); - addDatasourceUIs(this.registries.datasourceUIs); - addModelUIs(this.registries.modelUIs); - addViewUIs(this.registries.viewUIs); - addArgumentUIs(this.registries.argumentUIs); - addTemplates(this.registries.templates); - addTagUIs(this.registries.tagUIs); - addTransitions(this.registries.transitions); - } else { - throw new Error('Unable to initialize Canvas registries'); - } - - core.chrome.setBadge( - core.application.capabilities.canvas && core.application.capabilities.canvas.save - ? undefined - : { - text: strings.getText(), - tooltip: strings.getTooltip(), - iconType: 'glasses', - } - ); - - core.chrome.setHelpExtension({ - appName: i18n.translate('xpack.canvas.helpMenu.appName', { - defaultMessage: 'Canvas', - }), - links: [ - { - linkType: 'documentation', - href: getDocumentationLinks().canvas, - }, - ], - content: domNode => () => { - ReactDOM.render(, domNode); - }, - }); return {}; } diff --git a/x-pack/legacy/plugins/canvas/public/registries.ts b/x-pack/legacy/plugins/canvas/public/registries.ts index d175ab3934eed..99f309a917329 100644 --- a/x-pack/legacy/plugins/canvas/public/registries.ts +++ b/x-pack/legacy/plugins/canvas/public/registries.ts @@ -11,7 +11,6 @@ import { elementsRegistry } from './lib/elements_registry'; // @ts-ignore untyped local import { templatesRegistry } from './lib/templates_registry'; import { tagsRegistry } from './lib/tags_registry'; -import { ElementFactory } from '../types'; // @ts-ignore untyped local import { transitionsRegistry } from './lib/transitions_registry'; @@ -23,8 +22,9 @@ import { viewRegistry, // @ts-ignore untyped local } from './expression_types'; +import { SetupRegistries } from './plugin_api'; -export const registries = {}; +export let registries = {}; export function initRegistries() { addRegistries(registries, { @@ -40,42 +40,10 @@ export function initRegistries() { }); } -export function addElements(elements: ElementFactory[]) { - register(registries, { elements }); +export function populateRegistries(setupRegistries: SetupRegistries) { + register(registries, setupRegistries); } -export function addTransformUIs(transformUIs: any[]) { - register(registries, { transformUIs }); -} - -export function addDatasourceUIs(datasourceUIs: any[]) { - register(registries, { datasourceUIs }); -} - -export function addModelUIs(modelUIs: any[]) { - register(registries, { modelUIs }); -} - -export function addViewUIs(viewUIs: any[]) { - register(registries, { viewUIs }); -} - -export function addArgumentUIs(argumentUIs: any[]) { - register(registries, { argumentUIs }); -} - -export function addTemplates(templates: any[]) { - register(registries, { templates }); -} - -export function addTagUIs(tagUIs: any[]) { - register(registries, { tagUIs }); -} - -export function addTransitions(transitions: any[]) { - register(registries, { transitions }); -} - -export function addBrowserFunctions(browserFunctions: any[]) { - register(registries, { browserFunctions }); +export function destroyRegistries() { + registries = {}; }