Skip to content

Commit

Permalink
[Uptime] Fix breadcrumb for link back to monitor from waterfall page (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
shahzad31 authored Jan 4, 2021
1 parent d2b9fb3 commit 0188b9f
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 24 deletions.
Original file line number Diff line number Diff line change
@@ -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];
};
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down Expand Up @@ -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}`);
Expand Down
Original file line number Diff line number Diff line change
@@ -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) }]
: []),
]);
};
Original file line number Diff line number Diff line change
Expand Up @@ -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))
);
});
});
Expand Down
38 changes: 25 additions & 13 deletions x-pack/plugins/uptime/public/hooks/use_breadcrumbs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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
Expand All @@ -36,12 +51,6 @@ export const makeBaseBreadcrumb = (
defaultMessage: 'Uptime',
}),
href,
onClick: (event) => {
if (href && navigateToHref) {
event.preventDefault();
navigateToHref(href);
}
},
};
};

Expand All @@ -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]);
};

0 comments on commit 0188b9f

Please sign in to comment.