From f32c52a04bdb7cee0c0acd3b539b555a806f0d02 Mon Sep 17 00:00:00 2001 From: Nathan L Smith Date: Thu, 12 Dec 2019 17:19:48 -0600 Subject: [PATCH] [APM] Start moving to renderApp Extract app rendering to a renderApp method. Use start core and plugins in context to be ready for getStartServices API. --- .../apm/public/context/ApmPluginContext.tsx | 8 +- .../public/new-platform/application/index.tsx | 78 ++++++++++++ .../apm/public/new-platform/plugin.tsx | 112 +++++------------- 3 files changed, 112 insertions(+), 86 deletions(-) create mode 100644 x-pack/legacy/plugins/apm/public/new-platform/application/index.tsx diff --git a/x-pack/legacy/plugins/apm/public/context/ApmPluginContext.tsx b/x-pack/legacy/plugins/apm/public/context/ApmPluginContext.tsx index 86efd9b31974e..4dbb6d218c0e0 100644 --- a/x-pack/legacy/plugins/apm/public/context/ApmPluginContext.tsx +++ b/x-pack/legacy/plugins/apm/public/context/ApmPluginContext.tsx @@ -4,15 +4,15 @@ * you may not use this file except in compliance with the Elastic License. */ +import { CoreStart, PackageInfo } from 'kibana/public'; import { createContext } from 'react'; -import { AppMountContext, PackageInfo } from 'kibana/public'; -import { ApmPluginSetupDeps, ConfigSchema } from '../new-platform/plugin'; +import { ApmPluginStartDeps, ConfigSchema } from '../new-platform/plugin'; export interface ApmPluginContextValue { config: ConfigSchema; - core: AppMountContext['core']; + core: CoreStart; packageInfo: PackageInfo; - plugins: ApmPluginSetupDeps; + plugins: ApmPluginStartDeps; } export const ApmPluginContext = createContext({} as ApmPluginContextValue); diff --git a/x-pack/legacy/plugins/apm/public/new-platform/application/index.tsx b/x-pack/legacy/plugins/apm/public/new-platform/application/index.tsx new file mode 100644 index 0000000000000..3dd49491ffc5b --- /dev/null +++ b/x-pack/legacy/plugins/apm/public/new-platform/application/index.tsx @@ -0,0 +1,78 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { AppMountParameters } from 'kibana/public'; +import React from 'react'; +import ReactDOM from 'react-dom'; +import { Route, Router, Switch } from 'react-router-dom'; +import styled from 'styled-components'; +import { routes } from '../../components/app/Main/route_config'; +import { ScrollToTopOnPathChange } from '../../components/app/Main/ScrollToTopOnPathChange'; +import { UpdateBreadcrumbs } from '../../components/app/Main/UpdateBreadcrumbs'; +import { + ApmPluginContext, + ApmPluginContextValue +} from '../../context/ApmPluginContext'; +import { LicenseProvider } from '../../context/LicenseContext'; +import { LoadingIndicatorProvider } from '../../context/LoadingIndicatorContext'; +import { LocationProvider } from '../../context/LocationContext'; +import { MatchedRouteProvider } from '../../context/MatchedRouteContext'; +import { UrlParamsProvider } from '../../context/UrlParamsContext'; +import { px, unit, units } from '../../style/variables'; +import { history } from '../../utils/history'; + +const MainContainer = styled.main` + min-width: ${px(unit * 50)}; + padding: ${px(units.plus)}; + height: 100%; +`; + +const App = ({ + apmPluginContextValue +}: { + apmPluginContextValue: ApmPluginContextValue; +}) => { + const i18nCore = apmPluginContextValue.core.i18n; + + return ( + + + + + + + + + + + + + {routes.map((route, i) => ( + + ))} + + + + + + + + + + + ); +}; + +export function renderApp( + apmPluginContextValue: ApmPluginContextValue, + params: AppMountParameters +) { + ReactDOM.render( + , + params.element + ); + return () => ReactDOM.unmountComponentAtNode(params.element); +} diff --git a/x-pack/legacy/plugins/apm/public/new-platform/plugin.tsx b/x-pack/legacy/plugins/apm/public/new-platform/plugin.tsx index 216af91fbb591..435638623a824 100644 --- a/x-pack/legacy/plugins/apm/public/new-platform/plugin.tsx +++ b/x-pack/legacy/plugins/apm/public/new-platform/plugin.tsx @@ -4,34 +4,21 @@ * you may not use this file except in compliance with the Elastic License. */ -import React from 'react'; -import ReactDOM from 'react-dom'; -import { Route, Router, Switch } from 'react-router-dom'; -import { ApmRoute } from '@elastic/apm-rum-react'; -import styled from 'styled-components'; import { metadata } from 'ui/metadata'; import { + AppMountParameters, CoreSetup, CoreStart, PackageInfo, Plugin, PluginInitializerContext } from '../../../../../../src/core/public'; -import { DataPublicPluginSetup } from '../../../../../../src/plugins/data/public'; +import { DataPublicPluginStart } from '../../../../../../src/plugins/data/public'; import { HomePublicPluginSetup } from '../../../../../../src/plugins/home/public'; import { LicensingPluginSetup } from '../../../../../plugins/licensing/public'; -import { routes } from '../components/app/Main/route_config'; -import { ScrollToTopOnPathChange } from '../components/app/Main/ScrollToTopOnPathChange'; -import { UpdateBreadcrumbs } from '../components/app/Main/UpdateBreadcrumbs'; -import { ApmPluginContext } from '../context/ApmPluginContext'; -import { LicenseProvider } from '../context/LicenseContext'; -import { LoadingIndicatorProvider } from '../context/LoadingIndicatorContext'; -import { LocationProvider } from '../context/LocationContext'; -import { MatchedRouteProvider } from '../context/MatchedRouteContext'; -import { UrlParamsProvider } from '../context/UrlParamsContext'; +import { ApmPluginContextValue } from '../context/ApmPluginContext'; import { createStaticIndexPattern } from '../services/rest/index_pattern'; -import { px, unit, units } from '../style/variables'; -import { history } from '../utils/history'; +import { renderApp } from './application'; import { featureCatalogueEntry } from './featureCatalogueEntry'; import { getConfigFromInjectedMetadata } from './getConfigFromInjectedMetadata'; import { setHelpExtension } from './setHelpExtension'; @@ -40,32 +27,15 @@ import { setReadonlyBadge } from './updateBadge'; export const REACT_APP_ROOT_ID = 'react-apm-root'; -const MainContainer = styled.main` - min-width: ${px(unit * 50)}; - padding: ${px(units.plus)}; - height: 100%; -`; - -const App = () => { - return ( - - - - - {routes.map((route, i) => ( - - ))} - - - ); -}; - export type ApmPluginSetup = void; export type ApmPluginStart = void; export interface ApmPluginSetupDeps { - data: DataPublicPluginSetup; home: HomePublicPluginSetup; +} + +export interface ApmPluginStartDeps { + data: DataPublicPluginStart; licensing: LicensingPluginSetup; } @@ -79,12 +49,6 @@ export interface ConfigSchema { export class ApmPlugin implements Plugin { - // When we switch over from the old platform to new platform the plugins will - // be coming from setup instead of start, since that's where we do - // `core.application.register`. During the transitions we put plugins on an - // instance property so we can use it in start. - setupPlugins: ApmPluginSetupDeps = {} as ApmPluginSetupDeps; - constructor( // @ts-ignore Not using initializerContext now, but will be once NP // migration is complete. @@ -92,15 +56,11 @@ export class ApmPlugin ) {} // Take the DOM element as the constructor, so we can mount the app. - public setup(_core: CoreSetup, plugins: ApmPluginSetupDeps) { - plugins.home.featureCatalogue.register(featureCatalogueEntry); - this.setupPlugins = plugins; + public setup(_coreSetup: CoreSetup, depsSetup: ApmPluginSetupDeps) { + depsSetup.home.featureCatalogue.register(featureCatalogueEntry); } - public start(core: CoreStart) { - const i18nCore = core.i18n; - const plugins = this.setupPlugins; - + public start(coreStart: CoreStart, depsStart: ApmPluginStartDeps) { // Once we're actually an NP plugin we'll get the config from the // initializerContext like: // @@ -118,43 +78,31 @@ export class ApmPlugin const packageInfo = metadata as PackageInfo; // render APM feedback link in global help menu - setHelpExtension(core); - setReadonlyBadge(core); - toggleAppLinkInNav(core, config); + setHelpExtension(coreStart); + setReadonlyBadge(coreStart); + toggleAppLinkInNav(coreStart, config); - const apmPluginContextValue = { + // create static index pattern and store as saved object. Not needed by APM UI but for legacy reasons in Discover, Dashboard etc. + createStaticIndexPattern(coreStart.http).catch(e => { + // eslint-disable-next-line no-console + console.log('Error fetching static index pattern', e); + }); + + const apmPluginContextValue: ApmPluginContextValue = { config, - core, + core: coreStart, packageInfo, - plugins + plugins: depsStart }; - ReactDOM.render( - - - - - - - - - - - - - - - - - , - document.getElementById(REACT_APP_ROOT_ID) - ); + const params: AppMountParameters = { + appBasePath: coreStart.http.basePath.get(), + element: document.getElementById(REACT_APP_ROOT_ID) as HTMLElement + }; - // create static index pattern and store as saved object. Not needed by APM UI but for legacy reasons in Discover, Dashboard etc. - createStaticIndexPattern(core.http).catch(e => { - // eslint-disable-next-line no-console - console.log('Error fetching static index pattern', e); - }); + // Call renderApp directly here in `start`. When when we switch to NP, we'll + // be calling the `mount` method of `core.application.register` in `setup` + renderApp(apmPluginContextValue, params); } public stop() {}