[APM] getInjectedVars shim (#51635)

* [APM] getInjectedVars shim

Set up the APM public NP plugin to expose the config variables on its context,
and replace use of getInjectedVars with that.

Since we're not yet running as an NP plugin, we don't get passed a `pluginInitializerContext`,
so we use a shim in the plugin setup that gets the config values from injected vars for the time being.

Also:

* Move toggle app link in nav shim to plugin setup
* Replace the routes exported from Main/route_config with a function that takes a configuration object
This commit is contained in:
Nathan L Smith 2019-12-02 15:20:50 -06:00 committed by GitHub
parent a46833ec98
commit 0ba5c1e4d2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 350 additions and 251 deletions

View file

@ -43,7 +43,6 @@ export const apm: LegacyPluginInitializer = kibana => {
apmServiceMapEnabled: config.get('xpack.apm.serviceMapEnabled')
};
},
hacks: ['plugins/apm/hacks/toggle_app_link_in_nav'],
savedObjectSchemas: {
'apm-services-telemetry': {
isNamespaceAgnostic: true

View file

@ -7,8 +7,13 @@
import { shallow } from 'enzyme';
import React from 'react';
import { Home } from '../Home';
import * as plugin from '../../../new-platform/plugin';
jest.mock('ui/new_platform');
jest.spyOn(plugin, 'usePlugins').mockReturnValue(({
apm: { config: {} as plugin.ConfigSchema }
} as unknown) as plugin.ApmPluginStartDeps & {
apm: { config: plugin.ConfigSchema };
});
describe('Home component', () => {
it('should render services', () => {

View file

@ -13,7 +13,6 @@ import {
EuiSpacer
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { npStart } from 'ui/new_platform';
import React from 'react';
import { $ElementType } from 'utility-types';
import { ApmHeader } from '../../shared/ApmHeader';
@ -26,46 +25,54 @@ import { EuiTabLink } from '../../shared/EuiTabLink';
import { SettingsLink } from '../../shared/Links/apm/SettingsLink';
import { ServiceMapLink } from '../../shared/Links/apm/ServiceMapLink';
import { ServiceMap } from '../ServiceMap';
import { usePlugins } from '../../../new-platform/plugin';
const homeTabs = [
{
link: (
<ServiceOverviewLink>
{i18n.translate('xpack.apm.home.servicesTabLabel', {
defaultMessage: 'Services'
})}
</ServiceOverviewLink>
),
render: () => <ServiceOverview />,
name: 'services'
},
{
link: (
<TraceOverviewLink>
{i18n.translate('xpack.apm.home.tracesTabLabel', {
defaultMessage: 'Traces'
})}
</TraceOverviewLink>
),
render: () => <TraceOverview />,
name: 'traces'
function getHomeTabs({
apmServiceMapEnabled = false
}: {
apmServiceMapEnabled: boolean;
}) {
const homeTabs = [
{
link: (
<ServiceOverviewLink>
{i18n.translate('xpack.apm.home.servicesTabLabel', {
defaultMessage: 'Services'
})}
</ServiceOverviewLink>
),
render: () => <ServiceOverview />,
name: 'services'
},
{
link: (
<TraceOverviewLink>
{i18n.translate('xpack.apm.home.tracesTabLabel', {
defaultMessage: 'Traces'
})}
</TraceOverviewLink>
),
render: () => <TraceOverview />,
name: 'traces'
}
];
if (apmServiceMapEnabled) {
homeTabs.push({
link: (
<ServiceMapLink>
{i18n.translate('xpack.apm.home.serviceMapTabLabel', {
defaultMessage: 'Service Map'
})}
</ServiceMapLink>
),
render: () => <ServiceMap />,
name: 'service-map'
});
}
];
if (npStart.core.injectedMetadata.getInjectedVar('apmServiceMapEnabled')) {
homeTabs.push({
link: (
<ServiceMapLink>
{i18n.translate('xpack.apm.home.serviceMapTabLabel', {
defaultMessage: 'Service Map'
})}
</ServiceMapLink>
),
render: () => <ServiceMap />,
name: 'service-map'
});
return homeTabs;
}
const SETTINGS_LINK_LABEL = i18n.translate('xpack.apm.settingsLinkLabel', {
defaultMessage: 'Settings'
});
@ -75,6 +82,9 @@ interface Props {
}
export function Home({ tab }: Props) {
const { apm } = usePlugins();
const { apmServiceMapEnabled } = apm.config;
const homeTabs = getHomeTabs({ apmServiceMapEnabled });
const selectedTab = homeTabs.find(
homeTab => homeTab.name === tab
) as $ElementType<typeof homeTabs, number>;

View file

@ -9,8 +9,11 @@ import React from 'react';
import { LegacyCoreStart } from 'src/core/public';
import { useKibanaCore } from '../../../../../observability/public';
import { getAPMHref } from '../../shared/Links/apm/APMLink';
import { Breadcrumb, ProvideBreadcrumbs } from './ProvideBreadcrumbs';
import { routes } from './route_config';
import {
Breadcrumb,
ProvideBreadcrumbs,
BreadcrumbRoute
} from './ProvideBreadcrumbs';
interface Props {
location: Location;
@ -49,7 +52,11 @@ class UpdateBreadcrumbsComponent extends React.Component<Props> {
}
}
export function UpdateBreadcrumbs() {
interface UpdateBreadcrumbsProps {
routes: BreadcrumbRoute[];
}
export function UpdateBreadcrumbs({ routes }: UpdateBreadcrumbsProps) {
const core = useKibanaCore();
return (
<ProvideBreadcrumbs

View file

@ -9,8 +9,9 @@ import React from 'react';
import { MemoryRouter } from 'react-router-dom';
import { UpdateBreadcrumbs } from '../UpdateBreadcrumbs';
import * as kibanaCore from '../../../../../../observability/public/context/kibana_core';
import { getRoutes } from '../route_config';
jest.mock('ui/new_platform');
jest.mock('ui/index_patterns');
const coreMock = {
chrome: {
@ -20,10 +21,12 @@ const coreMock = {
jest.spyOn(kibanaCore, 'useKibanaCore').mockReturnValue(coreMock);
const routes = getRoutes({ apmServiceMapEnabled: true });
function expectBreadcrumbToMatchSnapshot(route, params = '') {
mount(
<MemoryRouter initialEntries={[`${route}?kuery=myKuery&${params}`]}>
<UpdateBreadcrumbs />
<UpdateBreadcrumbs routes={routes} />
</MemoryRouter>
);
expect(coreMock.chrome.setBreadcrumbs).toHaveBeenCalledTimes(1);

View file

@ -7,7 +7,6 @@
import { i18n } from '@kbn/i18n';
import React from 'react';
import { Redirect, RouteComponentProps } from 'react-router-dom';
import { npStart } from 'ui/new_platform';
import { SERVICE_NODE_NAME_MISSING } from '../../../../../common/service_nodes';
import { ErrorGroupDetails } from '../../ErrorGroupDetails';
import { ServiceDetails } from '../../ServiceDetails';
@ -42,172 +41,180 @@ const renderAsRedirectTo = (to: string) => {
);
};
export const routes: BreadcrumbRoute[] = [
{
exact: true,
path: '/',
render: renderAsRedirectTo('/services'),
breadcrumb: 'APM',
name: RouteName.HOME
},
{
exact: true,
path: '/services',
component: () => <Home tab="services" />,
breadcrumb: i18n.translate('xpack.apm.breadcrumb.servicesTitle', {
defaultMessage: 'Services'
}),
name: RouteName.SERVICES
},
{
exact: true,
path: '/traces',
component: () => <Home tab="traces" />,
breadcrumb: i18n.translate('xpack.apm.breadcrumb.tracesTitle', {
defaultMessage: 'Traces'
}),
name: RouteName.TRACES
},
{
exact: true,
path: '/settings',
render: renderAsRedirectTo('/settings/agent-configuration'),
breadcrumb: i18n.translate('xpack.apm.breadcrumb.listSettingsTitle', {
defaultMessage: 'Settings'
}),
name: RouteName.SETTINGS
},
{
exact: true,
path: '/settings/apm-indices',
component: () => (
<Settings>
<ApmIndices />
</Settings>
),
breadcrumb: i18n.translate('xpack.apm.breadcrumb.settings.indicesTitle', {
defaultMessage: 'Indices'
}),
name: RouteName.INDICES
},
{
exact: true,
path: '/settings/agent-configuration',
component: () => (
<Settings>
<AgentConfigurations />
</Settings>
),
breadcrumb: i18n.translate(
'xpack.apm.breadcrumb.settings.agentConfigurationTitle',
{
defaultMessage: 'Agent Configuration'
}
),
name: RouteName.AGENT_CONFIGURATION
},
{
exact: true,
path: '/services/:serviceName',
breadcrumb: ({ match }) => match.params.serviceName,
render: (props: RouteComponentProps<RouteParams>) =>
renderAsRedirectTo(
`/services/${props.match.params.serviceName}/transactions`
)(props),
name: RouteName.SERVICE
},
// errors
{
exact: true,
path: '/services/:serviceName/errors/:groupId',
component: ErrorGroupDetails,
breadcrumb: ({ match }) => match.params.groupId,
name: RouteName.ERROR
},
{
exact: true,
path: '/services/:serviceName/errors',
component: () => <ServiceDetails tab="errors" />,
breadcrumb: i18n.translate('xpack.apm.breadcrumb.errorsTitle', {
defaultMessage: 'Errors'
}),
name: RouteName.ERRORS
},
// transactions
{
exact: true,
path: '/services/:serviceName/transactions',
component: () => <ServiceDetails tab="transactions" />,
breadcrumb: i18n.translate('xpack.apm.breadcrumb.transactionsTitle', {
defaultMessage: 'Transactions'
}),
name: RouteName.TRANSACTIONS
},
// metrics
{
exact: true,
path: '/services/:serviceName/metrics',
component: () => <ServiceDetails tab="metrics" />,
breadcrumb: metricsBreadcrumb,
name: RouteName.METRICS
},
// service nodes, only enabled for java agents for now
{
exact: true,
path: '/services/:serviceName/nodes',
component: () => <ServiceDetails tab="nodes" />,
breadcrumb: i18n.translate('xpack.apm.breadcrumb.nodesTitle', {
defaultMessage: 'JVMs'
}),
name: RouteName.SERVICE_NODES
},
// node metrics
{
exact: true,
path: '/services/:serviceName/nodes/:serviceNodeName/metrics',
component: () => <ServiceNodeMetrics />,
breadcrumb: ({ location }) => {
const { serviceNodeName } = resolveUrlParams(location, {});
if (serviceNodeName === SERVICE_NODE_NAME_MISSING) {
return UNIDENTIFIED_SERVICE_NODES_LABEL;
}
return serviceNodeName || '';
},
name: RouteName.SERVICE_NODE_METRICS
},
{
exact: true,
path: '/services/:serviceName/transactions/view',
component: TransactionDetails,
breadcrumb: ({ location }) => {
const query = toQuery(location.search);
return query.transactionName as string;
},
name: RouteName.TRANSACTION_NAME
}
];
if (npStart.core.injectedMetadata.getInjectedVar('apmServiceMapEnabled')) {
routes.push(
export function getRoutes({
apmServiceMapEnabled
}: {
apmServiceMapEnabled: boolean;
}): BreadcrumbRoute[] {
const routes: BreadcrumbRoute[] = [
{
exact: true,
path: '/service-map',
component: () => <Home tab="service-map" />,
breadcrumb: i18n.translate('xpack.apm.breadcrumb.serviceMapTitle', {
defaultMessage: 'Service Map'
}),
name: RouteName.SERVICE_MAP
path: '/',
render: renderAsRedirectTo('/services'),
breadcrumb: 'APM',
name: RouteName.HOME
},
{
exact: true,
path: '/services/:serviceName/service-map',
component: () => <ServiceDetails tab="service-map" />,
breadcrumb: i18n.translate('xpack.apm.breadcrumb.serviceMapTitle', {
defaultMessage: 'Service Map'
path: '/services',
component: () => <Home tab="services" />,
breadcrumb: i18n.translate('xpack.apm.breadcrumb.servicesTitle', {
defaultMessage: 'Services'
}),
name: RouteName.SINGLE_SERVICE_MAP
name: RouteName.SERVICES
},
{
exact: true,
path: '/traces',
component: () => <Home tab="traces" />,
breadcrumb: i18n.translate('xpack.apm.breadcrumb.tracesTitle', {
defaultMessage: 'Traces'
}),
name: RouteName.TRACES
},
{
exact: true,
path: '/settings',
render: renderAsRedirectTo('/settings/agent-configuration'),
breadcrumb: i18n.translate('xpack.apm.breadcrumb.listSettingsTitle', {
defaultMessage: 'Settings'
}),
name: RouteName.SETTINGS
},
{
exact: true,
path: '/settings/apm-indices',
component: () => (
<Settings>
<ApmIndices />
</Settings>
),
breadcrumb: i18n.translate('xpack.apm.breadcrumb.settings.indicesTitle', {
defaultMessage: 'Indices'
}),
name: RouteName.INDICES
},
{
exact: true,
path: '/settings/agent-configuration',
component: () => (
<Settings>
<AgentConfigurations />
</Settings>
),
breadcrumb: i18n.translate(
'xpack.apm.breadcrumb.settings.agentConfigurationTitle',
{
defaultMessage: 'Agent Configuration'
}
),
name: RouteName.AGENT_CONFIGURATION
},
{
exact: true,
path: '/services/:serviceName',
breadcrumb: ({ match }) => match.params.serviceName,
render: (props: RouteComponentProps<RouteParams>) =>
renderAsRedirectTo(
`/services/${props.match.params.serviceName}/transactions`
)(props),
name: RouteName.SERVICE
},
// errors
{
exact: true,
path: '/services/:serviceName/errors/:groupId',
component: ErrorGroupDetails,
breadcrumb: ({ match }) => match.params.groupId,
name: RouteName.ERROR
},
{
exact: true,
path: '/services/:serviceName/errors',
component: () => <ServiceDetails tab="errors" />,
breadcrumb: i18n.translate('xpack.apm.breadcrumb.errorsTitle', {
defaultMessage: 'Errors'
}),
name: RouteName.ERRORS
},
// transactions
{
exact: true,
path: '/services/:serviceName/transactions',
component: () => <ServiceDetails tab="transactions" />,
breadcrumb: i18n.translate('xpack.apm.breadcrumb.transactionsTitle', {
defaultMessage: 'Transactions'
}),
name: RouteName.TRANSACTIONS
},
// metrics
{
exact: true,
path: '/services/:serviceName/metrics',
component: () => <ServiceDetails tab="metrics" />,
breadcrumb: metricsBreadcrumb,
name: RouteName.METRICS
},
// service nodes, only enabled for java agents for now
{
exact: true,
path: '/services/:serviceName/nodes',
component: () => <ServiceDetails tab="nodes" />,
breadcrumb: i18n.translate('xpack.apm.breadcrumb.nodesTitle', {
defaultMessage: 'JVMs'
}),
name: RouteName.SERVICE_NODES
},
// node metrics
{
exact: true,
path: '/services/:serviceName/nodes/:serviceNodeName/metrics',
component: () => <ServiceNodeMetrics />,
breadcrumb: ({ location }) => {
const { serviceNodeName } = resolveUrlParams(location, {});
if (serviceNodeName === SERVICE_NODE_NAME_MISSING) {
return UNIDENTIFIED_SERVICE_NODES_LABEL;
}
return serviceNodeName || '';
},
name: RouteName.SERVICE_NODE_METRICS
},
{
exact: true,
path: '/services/:serviceName/transactions/view',
component: TransactionDetails,
breadcrumb: ({ location }) => {
const query = toQuery(location.search);
return query.transactionName as string;
},
name: RouteName.TRANSACTION_NAME
}
);
];
if (apmServiceMapEnabled) {
routes.push(
{
exact: true,
path: '/service-map',
component: () => <Home tab="service-map" />,
breadcrumb: i18n.translate('xpack.apm.breadcrumb.serviceMapTitle', {
defaultMessage: 'Service Map'
}),
name: RouteName.SERVICE_MAP
},
{
exact: true,
path: '/services/:serviceName/service-map',
component: () => <ServiceDetails tab="service-map" />,
breadcrumb: i18n.translate('xpack.apm.breadcrumb.serviceMapTitle', {
defaultMessage: 'Service Map'
}),
name: RouteName.SINGLE_SERVICE_MAP
}
);
}
return routes;
}

View file

@ -7,7 +7,6 @@
import { i18n } from '@kbn/i18n';
import React from 'react';
import { EuiTabs, EuiSpacer } from '@elastic/eui';
import { npStart } from 'ui/new_platform';
import { ErrorGroupOverview } from '../ErrorGroupOverview';
import { TransactionOverview } from '../TransactionOverview';
import { ServiceMetrics } from '../ServiceMetrics';
@ -22,6 +21,7 @@ import { ServiceNodeOverview } from '../ServiceNodeOverview';
import { useAgentName } from '../../../hooks/useAgentName';
import { ServiceMap } from '../ServiceMap';
import { ServiceMapLink } from '../../shared/Links/apm/ServiceMapLink';
import { usePlugins } from '../../../new-platform/plugin';
interface Props {
tab: 'transactions' | 'errors' | 'metrics' | 'nodes' | 'service-map';
@ -31,6 +31,8 @@ export function ServiceDetailTabs({ tab }: Props) {
const { urlParams } = useUrlParams();
const { serviceName } = urlParams;
const { agentName } = useAgentName();
const { apm } = usePlugins();
const { apmServiceMapEnabled } = apm.config;
if (!serviceName) {
// this never happens, urlParams type is not accurate enough
@ -105,7 +107,7 @@ export function ServiceDetailTabs({ tab }: Props) {
name: 'service-map'
};
if (npStart.core.injectedMetadata.getInjectedVar('apmServiceMapEnabled')) {
if (apmServiceMapEnabled) {
tabs.push(serviceMapTab);
}

View file

@ -36,6 +36,7 @@ import { IUrlParams } from '../../../../context/UrlParamsContext/types';
import { KibanaLink } from '../../../shared/Links/KibanaLink';
import { createErrorGroupWatch, Schedule } from './createErrorGroupWatch';
import { ElasticDocsLink } from '../../../shared/Links/ElasticDocsLink';
import { PluginsContext } from '../../../../new-platform/plugin';
type ScheduleKey = keyof Schedule;
@ -149,9 +150,13 @@ export class WatcherFlyout extends Component<
this.setState({ slackUrl: event.target.value });
};
public createWatch = () => {
const core = this.context;
public createWatch = ({
apmIndexPatternTitle
}: {
apmIndexPatternTitle: string;
}) => () => {
const { serviceName } = this.props.urlParams;
const core = this.context;
if (!serviceName) {
return;
@ -186,10 +191,6 @@ export class WatcherFlyout extends Component<
unit: 'h'
};
const apmIndexPatternTitle = core.injectedMetadata.getInjectedVar(
'apmIndexPatternTitle'
) as string;
return createErrorGroupWatch({
http: core.http,
emails,
@ -613,20 +614,26 @@ export class WatcherFlyout extends Component<
<EuiFlyoutFooter>
<EuiFlexGroup justifyContent="flexEnd">
<EuiFlexItem grow={false}>
<EuiButton
onClick={this.createWatch}
fill
disabled={
!this.state.actions.email && !this.state.actions.slack
}
>
{i18n.translate(
'xpack.apm.serviceDetails.enableErrorReportsPanel.createWatchButtonLabel',
{
defaultMessage: 'Create watch'
}
)}
</EuiButton>
<PluginsContext.Consumer>
{({ apm }) => {
return (
<EuiButton
onClick={this.createWatch(apm.config)}
fill
disabled={
!this.state.actions.email && !this.state.actions.slack
}
>
{i18n.translate(
'xpack.apm.serviceDetails.enableErrorReportsPanel.createWatchButtonLabel',
{
defaultMessage: 'Create watch'
}
)}
</EuiButton>
);
}}
</PluginsContext.Consumer>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlyoutFooter>

View file

@ -3,16 +3,21 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import React, { useMemo } from 'react';
import React, { useMemo, ReactChild } from 'react';
import { matchPath } from 'react-router-dom';
import { routes } from '../components/app/Main/route_config';
import { useLocation } from '../hooks/useLocation';
import { BreadcrumbRoute } from '../components/app/Main/ProvideBreadcrumbs';
export const MatchedRouteContext = React.createContext<Array<typeof routes[0]>>(
[]
);
export const MatchedRouteContext = React.createContext<BreadcrumbRoute[]>([]);
export const MatchedRouteProvider: React.FC = ({ children }) => {
interface MatchedRouteProviderProps {
children: ReactChild;
routes: BreadcrumbRoute[];
}
export function MatchedRouteProvider({
children,
routes
}: MatchedRouteProviderProps) {
const { pathname } = useLocation();
const contextValue = useMemo(() => {
@ -21,9 +26,9 @@ export const MatchedRouteProvider: React.FC = ({ children }) => {
path: route.path
});
});
}, [pathname]);
}, [pathname, routes]);
return (
<MatchedRouteContext.Provider value={contextValue} children={children} />
);
};
}

View file

@ -0,0 +1,24 @@
/*
* 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 { npStart } from 'ui/new_platform';
import { ConfigSchema } from './plugin';
const { core } = npStart;
export function getConfigFromInjectedMetadata(): ConfigSchema {
const {
apmIndexPatternTitle,
apmServiceMapEnabled,
apmUiEnabled
} = core.injectedMetadata.getInjectedVars();
return {
apmIndexPatternTitle,
apmServiceMapEnabled,
apmUiEnabled
} as ConfigSchema;
}

View file

@ -10,4 +10,4 @@ import { ApmPlugin, ApmPluginSetup, ApmPluginStart } from './plugin';
export const plugin: PluginInitializer<
ApmPluginSetup,
ApmPluginStart
> = _core => new ApmPlugin();
> = pluginInitializerContext => new ApmPlugin(pluginInitializerContext);

View file

@ -13,7 +13,8 @@ import {
CoreStart,
LegacyCoreStart,
Plugin,
CoreSetup
CoreSetup,
PluginInitializerContext
} from '../../../../../../src/core/public';
import { DataPublicPluginStart } from '../../../../../../src/plugins/data/public';
import { KibanaCoreContextProvider } from '../../../observability/public';
@ -24,13 +25,16 @@ import { px, unit, units } from '../style/variables';
import { LoadingIndicatorProvider } from '../context/LoadingIndicatorContext';
import { LicenseProvider } from '../context/LicenseContext';
import { UpdateBreadcrumbs } from '../components/app/Main/UpdateBreadcrumbs';
import { routes } from '../components/app/Main/route_config';
import { getRoutes } from '../components/app/Main/route_config';
import { ScrollToTopOnPathChange } from '../components/app/Main/ScrollToTopOnPathChange';
import { MatchedRouteProvider } from '../context/MatchedRouteContext';
import { createStaticIndexPattern } from '../services/rest/index_pattern';
import { setHelpExtension } from './setHelpExtension';
import { setReadonlyBadge } from './updateBadge';
import { featureCatalogueEntry } from './featureCatalogueEntry';
import { getConfigFromInjectedMetadata } from './getConfigFromInjectedMetadata';
import { toggleAppLinkInNav } from './toggleAppLinkInNav';
import { BreadcrumbRoute } from '../components/app/Main/ProvideBreadcrumbs';
export const REACT_APP_ROOT_ID = 'react-apm-root';
@ -39,10 +43,10 @@ const MainContainer = styled.main`
padding: ${px(units.plus)};
`;
const App = () => {
const App = ({ routes }: { routes: BreadcrumbRoute[] }) => {
return (
<MainContainer data-test-subj="apmMainContainer">
<UpdateBreadcrumbs />
<UpdateBreadcrumbs routes={routes} />
<Route component={ScrollToTopOnPathChange} />
<Switch>
{routes.map((route, i) => (
@ -64,8 +68,17 @@ export interface ApmPluginStartDeps {
data: DataPublicPluginStart;
}
const PluginsContext = createContext({} as ApmPluginStartDeps);
export interface ConfigSchema {
apmIndexPatternTitle: string;
apmServiceMapEnabled: boolean;
apmUiEnabled: boolean;
}
// These are to be used until we switch over all our context handling to
// kibana_react
export const PluginsContext = createContext<
ApmPluginStartDeps & { apm: { config: ConfigSchema } }
>({} as ApmPluginStartDeps & { apm: { config: ConfigSchema } });
export function usePlugins() {
return useContext(PluginsContext);
}
@ -78,6 +91,12 @@ export class ApmPlugin
ApmPluginSetupDeps,
ApmPluginStartDeps
> {
constructor(
// @ts-ignore Not using initializerContext now, but will be once NP
// migration is complete.
private readonly initializerContext: PluginInitializerContext<ConfigSchema>
) {}
// Take the DOM element as the constructor, so we can mount the app.
public setup(_core: CoreSetup, plugins: ApmPluginSetupDeps) {
plugins.home.featureCatalogue.register(featureCatalogueEntry);
@ -85,21 +104,33 @@ export class ApmPlugin
public start(core: CoreStart, plugins: ApmPluginStartDeps) {
const i18nCore = core.i18n;
// Once we're actually an NP plugin we'll get the config from the
// initializerContext like:
//
// const config = this.initializerContext.config.get<ConfigSchema>();
//
// Until then we use a shim to get it from legacy injectedMetadata:
const config = getConfigFromInjectedMetadata();
const pluginsForContext = { ...plugins, apm: { config } };
const routes = getRoutes(config);
// render APM feedback link in global help menu
setHelpExtension(core);
setReadonlyBadge(core);
toggleAppLinkInNav(core, config);
ReactDOM.render(
<KibanaCoreContextProvider core={core as LegacyCoreStart}>
<PluginsContext.Provider value={plugins}>
<PluginsContext.Provider value={pluginsForContext}>
<i18nCore.Context>
<Router history={history}>
<LocationProvider>
<MatchedRouteProvider>
<MatchedRouteProvider routes={routes}>
<UrlParamsProvider>
<LoadingIndicatorProvider>
<LicenseProvider>
<App />
<App routes={routes} />
</LicenseProvider>
</LoadingIndicatorProvider>
</UrlParamsProvider>

View file

@ -4,11 +4,10 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { npStart } from 'ui/new_platform';
import { CoreStart } from 'kibana/public';
const { core } = npStart;
const apmUiEnabled = core.injectedMetadata.getInjectedVar('apmUiEnabled');
if (apmUiEnabled === false) {
core.chrome.navLinks.update('apm', { hidden: true });
export function toggleAppLinkInNav(core: CoreStart, { apmUiEnabled = false }) {
if (apmUiEnabled === false) {
core.chrome.navLinks.update('apm', { hidden: true });
}
}