Skip to content

Commit d5fd235

Browse files
smithelasticmachinecauemarcondes
committed
Use platform history (#74328)
Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com> Co-authored-by: cauemarcondes <caue.marcondes@elastic.co>
1 parent f6c23b3 commit d5fd235

67 files changed

Lines changed: 1190 additions & 746 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
7+
import { act } from '@testing-library/react';
8+
import { createMemoryHistory } from 'history';
9+
import { Observable } from 'rxjs';
10+
import { AppMountParameters, CoreStart, HttpSetup } from 'src/core/public';
11+
import { mockApmPluginContextValue } from '../context/ApmPluginContext/MockApmPluginContext';
12+
import { ApmPluginSetupDeps } from '../plugin';
13+
import { createCallApmApi } from '../services/rest/createCallApmApi';
14+
import { renderApp } from './';
15+
import { disableConsoleWarning } from '../utils/testHelpers';
16+
17+
describe('renderApp', () => {
18+
let mockConsole: jest.SpyInstance;
19+
20+
beforeAll(() => {
21+
// The RUM agent logs an unnecessary message here. There's a couple open
22+
// issues need to be fixed to get the ability to turn off all of the logging:
23+
//
24+
// * https://github.com/elastic/apm-agent-rum-js/issues/799
25+
// * https://github.com/elastic/apm-agent-rum-js/issues/861
26+
//
27+
// for now, override `console.warn` to filter those messages out.
28+
mockConsole = disableConsoleWarning('[Elastic APM]');
29+
});
30+
31+
afterAll(() => {
32+
mockConsole.mockRestore();
33+
});
34+
35+
it('renders the app', () => {
36+
const { core, config } = mockApmPluginContextValue;
37+
const plugins = {
38+
licensing: { license$: new Observable() },
39+
triggers_actions_ui: { actionTypeRegistry: {}, alertTypeRegistry: {} },
40+
usageCollection: { reportUiStats: () => {} },
41+
};
42+
const params = {
43+
element: document.createElement('div'),
44+
history: createMemoryHistory(),
45+
};
46+
jest.spyOn(window, 'scrollTo').mockReturnValueOnce(undefined);
47+
createCallApmApi((core.http as unknown) as HttpSetup);
48+
49+
jest
50+
.spyOn(window.console, 'warn')
51+
.mockImplementationOnce((message: string) => {
52+
if (message.startsWith('[Elastic APM')) {
53+
return;
54+
} else {
55+
console.warn(message); // eslint-disable-line no-console
56+
}
57+
});
58+
59+
let unmount: () => void;
60+
61+
act(() => {
62+
unmount = renderApp(
63+
(core as unknown) as CoreStart,
64+
(plugins as unknown) as ApmPluginSetupDeps,
65+
(params as unknown) as AppMountParameters,
66+
config
67+
);
68+
});
69+
70+
expect(() => {
71+
unmount();
72+
}).not.toThrowError();
73+
});
74+
});

x-pack/plugins/apm/public/application/csmApp.tsx

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ import { ApmPluginSetupDeps } from '../plugin';
1616
import {
1717
KibanaContextProvider,
1818
useUiSetting$,
19+
RedirectAppLinks,
1920
} from '../../../../../src/plugins/kibana_react/public';
2021
import { px, units } from '../style/variables';
2122
import { UpdateBreadcrumbs } from '../components/app/Main/UpdateBreadcrumbs';
2223
import { ScrollToTopOnPathChange } from '../components/app/Main/ScrollToTopOnPathChange';
23-
import { history, resetHistory } from '../utils/history';
2424
import 'react-vis/dist/style.css';
2525
import { RumHome } from '../components/app/RumDashboard/RumHome';
2626
import { ConfigSchema } from '../index';
@@ -70,12 +70,12 @@ function CsmApp() {
7070
export function CsmAppRoot({
7171
core,
7272
deps,
73-
routerHistory,
73+
history,
7474
config,
7575
}: {
7676
core: CoreStart;
7777
deps: ApmPluginSetupDeps;
78-
routerHistory: typeof history;
78+
history: AppMountParameters['history'];
7979
config: ConfigSchema;
8080
}) {
8181
const i18nCore = core.i18n;
@@ -86,19 +86,21 @@ export function CsmAppRoot({
8686
plugins,
8787
};
8888
return (
89-
<ApmPluginContext.Provider value={apmPluginContextValue}>
90-
<KibanaContextProvider services={{ ...core, ...plugins }}>
91-
<i18nCore.Context>
92-
<Router history={routerHistory}>
93-
<UrlParamsProvider>
94-
<LoadingIndicatorProvider>
95-
<CsmApp />
96-
</LoadingIndicatorProvider>
97-
</UrlParamsProvider>
98-
</Router>
99-
</i18nCore.Context>
100-
</KibanaContextProvider>
101-
</ApmPluginContext.Provider>
89+
<RedirectAppLinks application={core.application}>
90+
<ApmPluginContext.Provider value={apmPluginContextValue}>
91+
<KibanaContextProvider services={{ ...core, ...plugins }}>
92+
<i18nCore.Context>
93+
<Router history={history}>
94+
<UrlParamsProvider>
95+
<LoadingIndicatorProvider>
96+
<CsmApp />
97+
</LoadingIndicatorProvider>
98+
</UrlParamsProvider>
99+
</Router>
100+
</i18nCore.Context>
101+
</KibanaContextProvider>
102+
</ApmPluginContext.Provider>
103+
</RedirectAppLinks>
102104
);
103105
}
104106

@@ -109,19 +111,13 @@ export function CsmAppRoot({
109111
export const renderApp = (
110112
core: CoreStart,
111113
deps: ApmPluginSetupDeps,
112-
{ element }: AppMountParameters,
114+
{ element, history }: AppMountParameters,
113115
config: ConfigSchema
114116
) => {
115117
createCallApmApi(core.http);
116118

117-
resetHistory();
118119
ReactDOM.render(
119-
<CsmAppRoot
120-
core={core}
121-
deps={deps}
122-
routerHistory={history}
123-
config={config}
124-
/>,
120+
<CsmAppRoot core={core} deps={deps} history={history} config={config} />,
125121
element
126122
);
127123
return () => {

x-pack/plugins/apm/public/application/index.tsx

Lines changed: 54 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -5,36 +5,36 @@
55
*/
66

77
import { ApmRoute } from '@elastic/apm-rum-react';
8+
import euiDarkVars from '@elastic/eui/dist/eui_theme_dark.json';
9+
import euiLightVars from '@elastic/eui/dist/eui_theme_light.json';
810
import React from 'react';
911
import ReactDOM from 'react-dom';
1012
import { Route, Router, Switch } from 'react-router-dom';
11-
import styled, { ThemeProvider, DefaultTheme } from 'styled-components';
12-
import euiDarkVars from '@elastic/eui/dist/eui_theme_dark.json';
13-
import euiLightVars from '@elastic/eui/dist/eui_theme_light.json';
14-
import { CoreStart, AppMountParameters } from '../../../../../src/core/public';
15-
import { ApmPluginSetupDeps } from '../plugin';
13+
import 'react-vis/dist/style.css';
14+
import styled, { DefaultTheme, ThemeProvider } from 'styled-components';
15+
import { ConfigSchema } from '../';
16+
import { AppMountParameters, CoreStart } from '../../../../../src/core/public';
17+
import {
18+
KibanaContextProvider,
19+
RedirectAppLinks,
20+
useUiSetting$,
21+
} from '../../../../../src/plugins/kibana_react/public';
22+
import { AlertsContextProvider } from '../../../triggers_actions_ui/public';
23+
import { routes } from '../components/app/Main/route_config';
24+
import { ScrollToTopOnPathChange } from '../components/app/Main/ScrollToTopOnPathChange';
25+
import { UpdateBreadcrumbs } from '../components/app/Main/UpdateBreadcrumbs';
1626
import { ApmPluginContext } from '../context/ApmPluginContext';
1727
import { LicenseProvider } from '../context/LicenseContext';
1828
import { LoadingIndicatorProvider } from '../context/LoadingIndicatorContext';
1929
import { LocationProvider } from '../context/LocationContext';
2030
import { MatchedRouteProvider } from '../context/MatchedRouteContext';
2131
import { UrlParamsProvider } from '../context/UrlParamsContext';
22-
import { AlertsContextProvider } from '../../../triggers_actions_ui/public';
32+
import { ApmPluginSetupDeps } from '../plugin';
33+
import { createCallApmApi } from '../services/rest/createCallApmApi';
2334
import { createStaticIndexPattern } from '../services/rest/index_pattern';
24-
import {
25-
KibanaContextProvider,
26-
useUiSetting$,
27-
} from '../../../../../src/plugins/kibana_react/public';
28-
import { px, units } from '../style/variables';
29-
import { UpdateBreadcrumbs } from '../components/app/Main/UpdateBreadcrumbs';
30-
import { ScrollToTopOnPathChange } from '../components/app/Main/ScrollToTopOnPathChange';
31-
import { routes } from '../components/app/Main/route_config';
32-
import { history, resetHistory } from '../utils/history';
3335
import { setHelpExtension } from '../setHelpExtension';
36+
import { px, units } from '../style/variables';
3437
import { setReadonlyBadge } from '../updateBadge';
35-
import { createCallApmApi } from '../services/rest/createCallApmApi';
36-
import { ConfigSchema } from '..';
37-
import 'react-vis/dist/style.css';
3838

3939
const MainContainer = styled.div`
4040
padding: ${px(units.plus)};
@@ -68,12 +68,12 @@ function App() {
6868
export function ApmAppRoot({
6969
core,
7070
deps,
71-
routerHistory,
71+
history,
7272
config,
7373
}: {
7474
core: CoreStart;
7575
deps: ApmPluginSetupDeps;
76-
routerHistory: typeof history;
76+
history: AppMountParameters['history'];
7777
config: ConfigSchema;
7878
}) {
7979
const i18nCore = core.i18n;
@@ -84,36 +84,38 @@ export function ApmAppRoot({
8484
plugins,
8585
};
8686
return (
87-
<ApmPluginContext.Provider value={apmPluginContextValue}>
88-
<AlertsContextProvider
89-
value={{
90-
http: core.http,
91-
docLinks: core.docLinks,
92-
capabilities: core.application.capabilities,
93-
toastNotifications: core.notifications.toasts,
94-
actionTypeRegistry: plugins.triggers_actions_ui.actionTypeRegistry,
95-
alertTypeRegistry: plugins.triggers_actions_ui.alertTypeRegistry,
96-
}}
97-
>
98-
<KibanaContextProvider services={{ ...core, ...plugins }}>
99-
<i18nCore.Context>
100-
<Router history={routerHistory}>
101-
<LocationProvider>
102-
<MatchedRouteProvider routes={routes}>
103-
<UrlParamsProvider>
104-
<LoadingIndicatorProvider>
105-
<LicenseProvider>
106-
<App />
107-
</LicenseProvider>
108-
</LoadingIndicatorProvider>
109-
</UrlParamsProvider>
110-
</MatchedRouteProvider>
111-
</LocationProvider>
112-
</Router>
113-
</i18nCore.Context>
114-
</KibanaContextProvider>
115-
</AlertsContextProvider>
116-
</ApmPluginContext.Provider>
87+
<RedirectAppLinks application={core.application}>
88+
<ApmPluginContext.Provider value={apmPluginContextValue}>
89+
<AlertsContextProvider
90+
value={{
91+
http: core.http,
92+
docLinks: core.docLinks,
93+
capabilities: core.application.capabilities,
94+
toastNotifications: core.notifications.toasts,
95+
actionTypeRegistry: plugins.triggers_actions_ui.actionTypeRegistry,
96+
alertTypeRegistry: plugins.triggers_actions_ui.alertTypeRegistry,
97+
}}
98+
>
99+
<KibanaContextProvider services={{ ...core, ...plugins }}>
100+
<i18nCore.Context>
101+
<Router history={history}>
102+
<LocationProvider>
103+
<MatchedRouteProvider routes={routes}>
104+
<UrlParamsProvider>
105+
<LoadingIndicatorProvider>
106+
<LicenseProvider>
107+
<App />
108+
</LicenseProvider>
109+
</LoadingIndicatorProvider>
110+
</UrlParamsProvider>
111+
</MatchedRouteProvider>
112+
</LocationProvider>
113+
</Router>
114+
</i18nCore.Context>
115+
</KibanaContextProvider>
116+
</AlertsContextProvider>
117+
</ApmPluginContext.Provider>
118+
</RedirectAppLinks>
117119
);
118120
}
119121

@@ -124,7 +126,7 @@ export function ApmAppRoot({
124126
export const renderApp = (
125127
core: CoreStart,
126128
deps: ApmPluginSetupDeps,
127-
{ element }: AppMountParameters,
129+
{ element, history }: AppMountParameters,
128130
config: ConfigSchema
129131
) => {
130132
// render APM feedback link in global help menu
@@ -133,21 +135,14 @@ export const renderApp = (
133135

134136
createCallApmApi(core.http);
135137

136-
resetHistory();
137-
138138
// Automatically creates static index pattern and stores as saved object
139139
createStaticIndexPattern().catch((e) => {
140140
// eslint-disable-next-line no-console
141141
console.log('Error creating static index pattern', e);
142142
});
143143

144144
ReactDOM.render(
145-
<ApmAppRoot
146-
core={core}
147-
deps={deps}
148-
routerHistory={history}
149-
config={config}
150-
/>,
145+
<ApmAppRoot core={core} deps={deps} history={history} config={config} />,
151146
element
152147
);
153148
return () => {

x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/index.tsx

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,40 +6,40 @@
66

77
import {
88
EuiButtonEmpty,
9+
EuiIcon,
910
EuiPanel,
1011
EuiSpacer,
1112
EuiTab,
1213
EuiTabs,
1314
EuiTitle,
14-
EuiIcon,
1515
EuiToolTip,
1616
} from '@elastic/eui';
1717
import { i18n } from '@kbn/i18n';
1818
import { Location } from 'history';
19+
import { first } from 'lodash';
1920
import React from 'react';
21+
import { useHistory } from 'react-router-dom';
2022
import styled from 'styled-components';
21-
import { first } from 'lodash';
2223
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
2324
import { ErrorGroupAPIResponse } from '../../../../../server/lib/errors/get_error_group';
2425
import { APMError } from '../../../../../typings/es_schemas/ui/apm_error';
2526
import { IUrlParams } from '../../../../context/UrlParamsContext/types';
2627
import { px, unit, units } from '../../../../style/variables';
28+
import { TransactionDetailLink } from '../../../shared/Links/apm/TransactionDetailLink';
2729
import { DiscoverErrorLink } from '../../../shared/Links/DiscoverLinks/DiscoverErrorLink';
2830
import { fromQuery, toQuery } from '../../../shared/Links/url_helpers';
29-
import { history } from '../../../../utils/history';
3031
import { ErrorMetadata } from '../../../shared/MetadataTable/ErrorMetadata';
3132
import { Stacktrace } from '../../../shared/Stacktrace';
33+
import { Summary } from '../../../shared/Summary';
34+
import { HttpInfoSummaryItem } from '../../../shared/Summary/HttpInfoSummaryItem';
35+
import { UserAgentSummaryItem } from '../../../shared/Summary/UserAgentSummaryItem';
36+
import { TimestampTooltip } from '../../../shared/TimestampTooltip';
3237
import {
3338
ErrorTab,
3439
exceptionStacktraceTab,
3540
getTabs,
3641
logStacktraceTab,
3742
} from './ErrorTabs';
38-
import { Summary } from '../../../shared/Summary';
39-
import { TimestampTooltip } from '../../../shared/TimestampTooltip';
40-
import { HttpInfoSummaryItem } from '../../../shared/Summary/HttpInfoSummaryItem';
41-
import { TransactionDetailLink } from '../../../shared/Links/apm/TransactionDetailLink';
42-
import { UserAgentSummaryItem } from '../../../shared/Summary/UserAgentSummaryItem';
4343
import { ExceptionStacktrace } from './ExceptionStacktrace';
4444

4545
const HeaderContainer = styled.div`
@@ -71,6 +71,7 @@ function getCurrentTab(
7171
}
7272

7373
export function DetailView({ errorGroup, urlParams, location }: Props) {
74+
const history = useHistory();
7475
const { transaction, error, occurrencesCount } = errorGroup;
7576

7677
if (!error) {

0 commit comments

Comments
 (0)