[Uptime] Fix breadcrumb for link back to monitor from waterfall page (#87125)

This commit is contained in:
Shahzad 2021-01-04 19:16:39 +01:00 committed by GitHub
parent d2b9fb3bde
commit 0188b9f7ef
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 148 additions and 24 deletions

View file

@ -0,0 +1,82 @@
/*
* 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 { ChromeBreadcrumb } from 'kibana/public';
import React from 'react';
import { Route } from 'react-router-dom';
import { of } from 'rxjs';
import { MountWithReduxProvider, mountWithRouter } from '../../../../../lib';
import { KibanaContextProvider } from '../../../../../../../../../src/plugins/kibana_react/public';
import { useMonitorBreadcrumb } from '../use_monitor_breadcrumb';
import { OVERVIEW_ROUTE } from '../../../../../../common/constants';
import { Ping } from '../../../../../../common/runtime_types/ping';
import { JourneyState } from '../../../../../state/reducers/journey';
describe('useMonitorBreadcrumbs', () => {
it('sets the given breadcrumbs', () => {
const [getBreadcrumbs, core] = mockCore();
const Component = () => {
useMonitorBreadcrumb({
activeStep: { monitor: { id: 'test-monitor' } } as Ping,
journey: { details: { timestamp: '2021-01-04T11:25:19.104Z' } } as JourneyState,
});
return <>Step Water Fall</>;
};
mountWithRouter(
<MountWithReduxProvider>
<KibanaContextProvider services={{ ...core }}>
<Route path={OVERVIEW_ROUTE}>
<Component />
</Route>
</KibanaContextProvider>
</MountWithReduxProvider>
);
expect(getBreadcrumbs()).toMatchInlineSnapshot(`
Array [
Object {
"href": "/app/uptime",
"onClick": [Function],
"text": "Uptime",
},
Object {
"href": "/app/uptime/monitor/dGVzdC1tb25pdG9y",
"onClick": [Function],
"text": "test-monitor",
},
Object {
"text": "Jan 4, 2021 @ 06:25:19.104",
},
]
`);
});
});
const mockCore: () => [() => ChromeBreadcrumb[], any] = () => {
let breadcrumbObj: ChromeBreadcrumb[] = [];
const get = () => {
return breadcrumbObj;
};
const core = {
application: {
getUrlForApp: () => '/app/uptime',
navigateToUrl: jest.fn(),
},
chrome: {
setBreadcrumbs: (newBreadcrumbs: ChromeBreadcrumb[]) => {
breadcrumbObj = newBreadcrumbs;
},
},
uiSettings: {
get: (key: string) => 'MMM D, YYYY @ HH:mm:ss.SSS',
get$: (key: string) => of('MMM D, YYYY @ HH:mm:ss.SSS'),
},
};
return [get, core];
};

View file

@ -9,12 +9,11 @@ import { i18n } from '@kbn/i18n';
import React, { useEffect, useCallback, useMemo } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { useHistory } from 'react-router-dom';
import moment from 'moment';
import { useBreadcrumbs } from '../../../../hooks/use_breadcrumbs';
import { getJourneySteps } from '../../../../state/actions/journey';
import { journeySelector } from '../../../../state/selectors';
import { useUiSetting$ } from '../../../../../../../../src/plugins/kibana_react/public';
import { StepDetail } from './step_detail';
import { useMonitorBreadcrumb } from './use_monitor_breadcrumb';
export const NO_STEP_DATA = i18n.translate('xpack.uptime.synthetics.stepDetail.noData', {
defaultMessage: 'No data could be found for this step',
@ -48,12 +47,7 @@ export const StepDetailContainer: React.FC<Props> = ({ checkGroup, stepIndex })
};
}, [stepIndex, journey]);
useBreadcrumbs([
...(activeStep?.monitor?.name ? [{ text: activeStep?.monitor?.name }] : []),
...(journey?.details?.timestamp
? [{ text: moment(journey?.details?.timestamp).format(dateFormat) }]
: []),
]);
useMonitorBreadcrumb({ journey, activeStep });
const handleNextStep = useCallback(() => {
history.push(`/journey/${checkGroup}/step/${stepIndex + 1}`);

View file

@ -0,0 +1,38 @@
/*
* 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 moment from 'moment';
import { useBreadcrumbs } from '../../../../hooks/use_breadcrumbs';
import { useKibana, useUiSetting$ } from '../../../../../../../../src/plugins/kibana_react/public';
import { JourneyState } from '../../../../state/reducers/journey';
import { Ping } from '../../../../../common/runtime_types/ping';
import { PLUGIN } from '../../../../../common/constants/plugin';
interface Props {
journey: JourneyState;
activeStep?: Ping;
}
export const useMonitorBreadcrumb = ({ journey, activeStep }: Props) => {
const [dateFormat] = useUiSetting$<string>('dateFormat');
const kibana = useKibana();
const appPath = kibana.services.application?.getUrlForApp(PLUGIN.ID) ?? '';
useBreadcrumbs([
...(activeStep?.monitor
? [
{
text: activeStep?.monitor?.name || activeStep?.monitor.id,
href: `${appPath}/monitor/${btoa(activeStep?.monitor.id)}`,
},
]
: []),
...(journey?.details?.timestamp
? [{ text: moment(journey?.details?.timestamp).format(dateFormat) }]
: []),
]);
};

View file

@ -45,9 +45,7 @@ describe('useBreadcrumbs', () => {
const urlParams: UptimeUrlParams = getSupportedUrlParams({});
expect(JSON.stringify(getBreadcrumbs())).toEqual(
JSON.stringify(
[makeBaseBreadcrumb('/app/uptime', jest.fn(), urlParams)].concat(expectedCrumbs)
)
JSON.stringify([makeBaseBreadcrumb('/app/uptime', urlParams)].concat(expectedCrumbs))
);
});
});

View file

@ -6,7 +6,7 @@
import { ChromeBreadcrumb } from 'kibana/public';
import { i18n } from '@kbn/i18n';
import { useEffect } from 'react';
import { MouseEvent, useEffect } from 'react';
import { EuiBreadcrumb } from '@elastic/eui';
import { UptimeUrlParams } from '../lib/helper';
import { stringifyUrlParams } from '../lib/helper/stringify_url_params';
@ -16,11 +16,26 @@ import { PLUGIN } from '../../common/constants/plugin';
const EMPTY_QUERY = '?';
export const makeBaseBreadcrumb = (
href: string,
navigateToHref?: (url: string) => Promise<void>,
params?: UptimeUrlParams
): EuiBreadcrumb => {
function handleBreadcrumbClick(
breadcrumbs: ChromeBreadcrumb[],
navigateToHref?: (url: string) => Promise<void>
) {
return breadcrumbs.map((bc) => ({
...bc,
...(bc.href
? {
onClick: (event: MouseEvent) => {
if (navigateToHref && bc.href) {
event.preventDefault();
navigateToHref(bc.href);
}
},
}
: {}),
}));
}
export const makeBaseBreadcrumb = (href: string, params?: UptimeUrlParams): EuiBreadcrumb => {
if (params) {
const crumbParams: Partial<UptimeUrlParams> = { ...params };
// We don't want to encode this values because they are often set to Date.now(), the relative
@ -36,12 +51,6 @@ export const makeBaseBreadcrumb = (
defaultMessage: 'Uptime',
}),
href,
onClick: (event) => {
if (href && navigateToHref) {
event.preventDefault();
navigateToHref(href);
}
},
};
};
@ -51,9 +60,12 @@ export const useBreadcrumbs = (extraCrumbs: ChromeBreadcrumb[]) => {
const setBreadcrumbs = kibana.services.chrome?.setBreadcrumbs;
const appPath = kibana.services.application?.getUrlForApp(PLUGIN.ID) ?? '';
const navigate = kibana.services.application?.navigateToUrl;
useEffect(() => {
if (setBreadcrumbs) {
setBreadcrumbs([makeBaseBreadcrumb(appPath, navigate, params)].concat(extraCrumbs));
setBreadcrumbs(
handleBreadcrumbClick([makeBaseBreadcrumb(appPath, params)].concat(extraCrumbs), navigate)
);
}
}, [appPath, extraCrumbs, navigate, params, setBreadcrumbs]);
};