kibana/x-pack/plugins/apm/public/components/routing/app_root.tsx
Rachel Shen 50a4fc4916
[Shared UX] Adoption of Shared UX Route component (#150357)
## Summary

This PR removes all imports of Route from react-router-dom and
'@kbn/kibana-react-plugin/public' and instead imports Route from
@kbn/shared-ux-router.

### Context
Based on
https://github.com/elastic/kibana/issues/132629#issue-1243243678 This PR
executes steps 2 - 4:

> 2. To make the transition easier, we want to re-export other
react-router-dom exports alongside the modified' Route'.
> 3. Solutions should start using that Route component in place of the
one from react-router-dom. I.e. replace all occurrences of import { ...
} from 'react-router-dom' with import { ... } from
'@kbn/shared-ux-router'.
> 4. All manual calls to useExecutionContext are not needed anymore and
should be removed.

### Future PR

Looks like this might be getting worked on in:
https://github.com/elastic/kibana/pull/145863 (thanks!)

> Introduce an ESlint rule that ensures that react-router-dom is not
used directly in Kibana and that imports go through the new
@kbn/shared-ux-router package.

This is tangentially accomplished through
https://github.com/elastic/kibana/pull/150340 but only addresses using
Route through @kbn/kibana-react-plugin/public'


### Checklist

Delete any items that are not applicable to this PR.

- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Tiago Costa <tiagoffcc@hotmail.com>
2023-02-14 19:25:04 +00:00

134 lines
5.4 KiB
TypeScript

/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { APP_WRAPPER_CLASS } from '@kbn/core/public';
import {
KibanaContextProvider,
RedirectAppLinks,
useUiSetting$,
} from '@kbn/kibana-react-plugin/public';
import { Storage } from '@kbn/kibana-utils-plugin/public';
import {
HeaderMenuPortal,
InspectorContextProvider,
} from '@kbn/observability-plugin/public';
import { RouteRenderer, RouterProvider } from '@kbn/typed-react-router-config';
import { euiDarkVars, euiLightVars } from '@kbn/ui-theme';
import React from 'react';
import { Route } from '@kbn/shared-ux-router';
import { DefaultTheme, ThemeProvider } from 'styled-components';
import { AnomalyDetectionJobsContextProvider } from '../../context/anomaly_detection_jobs/anomaly_detection_jobs_context';
import {
ApmPluginContext,
ApmPluginContextValue,
} from '../../context/apm_plugin/apm_plugin_context';
import { useApmPluginContext } from '../../context/apm_plugin/use_apm_plugin_context';
import { BreadcrumbsContextProvider } from '../../context/breadcrumbs/context';
import { LicenseProvider } from '../../context/license/license_context';
import { TimeRangeIdContextProvider } from '../../context/time_range_id/time_range_id_context';
import { UrlParamsProvider } from '../../context/url_params_context/url_params_context';
import { ApmPluginStartDeps } from '../../plugin';
import { ScrollToTopOnPathChange } from '../app/main/scroll_to_top_on_path_change';
import { ApmHeaderActionMenu } from '../shared/apm_header_action_menu';
import { RedirectWithDefaultDateRange } from '../shared/redirect_with_default_date_range';
import { RedirectWithDefaultEnvironment } from '../shared/redirect_with_default_environment';
import { RedirectWithOffset } from '../shared/redirect_with_offset';
import { ApmErrorBoundary } from './apm_error_boundary';
import { apmRouter } from './apm_route_config';
import { RedirectDependenciesToDependenciesInventory } from './home/redirect_dependencies_to_dependencies_inventory';
import { TrackPageview } from './track_pageview';
const storage = new Storage(localStorage);
export function ApmAppRoot({
apmPluginContextValue,
pluginsStart,
}: {
apmPluginContextValue: ApmPluginContextValue;
pluginsStart: ApmPluginStartDeps;
}) {
const { appMountParameters, core } = apmPluginContextValue;
const { history } = appMountParameters;
const i18nCore = core.i18n;
return (
<RedirectAppLinks
application={core.application}
className={APP_WRAPPER_CLASS}
data-test-subj="apmMainContainer"
role="main"
>
<ApmPluginContext.Provider value={apmPluginContextValue}>
<KibanaContextProvider services={{ ...core, ...pluginsStart, storage }}>
<i18nCore.Context>
<TimeRangeIdContextProvider>
<RouterProvider history={history} router={apmRouter as any}>
<ApmErrorBoundary>
<RedirectDependenciesToDependenciesInventory>
<RedirectWithDefaultEnvironment>
<RedirectWithDefaultDateRange>
<RedirectWithOffset>
<TrackPageview>
<BreadcrumbsContextProvider>
<UrlParamsProvider>
<LicenseProvider>
<AnomalyDetectionJobsContextProvider>
<InspectorContextProvider>
<ApmThemeProvider>
<MountApmHeaderActionMenu />
<Route
component={ScrollToTopOnPathChange}
/>
<RouteRenderer />
</ApmThemeProvider>
</InspectorContextProvider>
</AnomalyDetectionJobsContextProvider>
</LicenseProvider>
</UrlParamsProvider>
</BreadcrumbsContextProvider>
</TrackPageview>
</RedirectWithOffset>
</RedirectWithDefaultDateRange>
</RedirectWithDefaultEnvironment>
</RedirectDependenciesToDependenciesInventory>
</ApmErrorBoundary>
</RouterProvider>
</TimeRangeIdContextProvider>
</i18nCore.Context>
</KibanaContextProvider>
</ApmPluginContext.Provider>
</RedirectAppLinks>
);
}
function MountApmHeaderActionMenu() {
const { setHeaderActionMenu, theme$ } =
useApmPluginContext().appMountParameters;
return (
<HeaderMenuPortal setHeaderActionMenu={setHeaderActionMenu} theme$={theme$}>
<ApmHeaderActionMenu />
</HeaderMenuPortal>
);
}
function ApmThemeProvider({ children }: { children: React.ReactNode }) {
const [darkMode] = useUiSetting$<boolean>('theme:darkMode');
return (
<ThemeProvider
theme={(outerTheme?: DefaultTheme) => ({
...outerTheme,
eui: darkMode ? euiDarkVars : euiLightVars,
darkMode,
})}
>
{children}
</ThemeProvider>
);
}