diff --git a/x-pack/legacy/plugins/uptime/public/breadcrumbs.ts b/x-pack/legacy/plugins/uptime/public/breadcrumbs.ts
index ff0dca3887ff2..41bc2aa258807 100644
--- a/x-pack/legacy/plugins/uptime/public/breadcrumbs.ts
+++ b/x-pack/legacy/plugins/uptime/public/breadcrumbs.ts
@@ -3,22 +3,3 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
-
-import { i18n } from '@kbn/i18n';
-import { ChromeBreadcrumb } from 'src/core/public';
-
-const makeOverviewBreadcrumb = (search?: string): ChromeBreadcrumb => ({
- text: i18n.translate('xpack.uptime.breadcrumbs.overviewBreadcrumbText', {
- defaultMessage: 'Uptime',
- }),
- href: `#/${search ? search : ''}`,
-});
-
-export const getOverviewPageBreadcrumbs = (search?: string): ChromeBreadcrumb[] => [
- makeOverviewBreadcrumb(search),
-];
-
-export const getMonitorPageBreadcrumb = (name: string, search?: string): ChromeBreadcrumb[] => [
- makeOverviewBreadcrumb(search),
- { text: name },
-];
diff --git a/x-pack/legacy/plugins/uptime/public/components/connected/pages/page_header_container.tsx b/x-pack/legacy/plugins/uptime/public/components/connected/pages/page_header_container.tsx
deleted file mode 100644
index 9429b87061ff7..0000000000000
--- a/x-pack/legacy/plugins/uptime/public/components/connected/pages/page_header_container.tsx
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * 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 { connect } from 'react-redux';
-import { selectSelectedMonitor } from '../../../state/selectors';
-import { AppState } from '../../../state';
-import { PageHeaderComponent } from '../../../pages/page_header';
-
-const mapStateToProps = (state: AppState) => ({
- monitorStatus: selectSelectedMonitor(state),
-});
-
-export const PageHeader = connect(mapStateToProps, null)(PageHeaderComponent);
diff --git a/x-pack/legacy/plugins/uptime/public/pages/__tests__/__snapshots__/monitor.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/pages/__tests__/__snapshots__/monitor.test.tsx.snap
index 6064caa868bf8..f637af397bbeb 100644
--- a/x-pack/legacy/plugins/uptime/public/pages/__tests__/__snapshots__/monitor.test.tsx.snap
+++ b/x-pack/legacy/plugins/uptime/public/pages/__tests__/__snapshots__/monitor.test.tsx.snap
@@ -51,6 +51,6 @@ exports[`MonitorPage shallow renders expected elements for valid props 1`] = `
}
}
>
-
+
`;
diff --git a/x-pack/legacy/plugins/uptime/public/pages/__tests__/__snapshots__/page_header.test.tsx.snap b/x-pack/legacy/plugins/uptime/public/pages/__tests__/__snapshots__/page_header.test.tsx.snap
index 2563b15eed5d5..58d98af5d6b14 100644
--- a/x-pack/legacy/plugins/uptime/public/pages/__tests__/__snapshots__/page_header.test.tsx.snap
+++ b/x-pack/legacy/plugins/uptime/public/pages/__tests__/__snapshots__/page_header.test.tsx.snap
@@ -1,836 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`PageHeaderComponent mount expected page title for valid monitor route 1`] = `
-
-
-
-
-
-
-
-
-
- https://www.elastic.co
-
-
-
-
-
-
-
-
-
-
-
-
-
- }
- >
-
-
-
-
-
- }
- closePopover={[Function]}
- display="inlineBlock"
- hasArrow={true}
- id="QuickSelectPopover"
- isOpen={false}
- ownFocus={true}
- panelPaddingSize="m"
- >
-
-
-
-
-
-
-
-
-
-
-
-
-
}
- iconType={false}
- isCustom={true}
- startDateControl={
}
- >
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-`;
-
-exports[`PageHeaderComponent renders expected elements for valid props 1`] = `
-Array [
-
-
-
- Overview
-
-
-
-
-
-
-
-
-
-
-
-
-
,
- ,
-]
-`;
-
-exports[`PageHeaderComponent renders expected title for valid monitor route 1`] = `
+exports[`PageHeader shallow renders with breadcrumbs and the date picker: page_header_with_date_picker 1`] = `
Array [
- https://www.elastic.co
+ TestingHeading
- Overview
+ TestingHeading
-
-
-
-
-
-
-
-
-
-
,
,
]
`;
-
-exports[`PageHeaderComponent shallow renders expected elements for valid props 1`] = `
-
-
-
-`;
diff --git a/x-pack/legacy/plugins/uptime/public/pages/__tests__/page_header.test.tsx b/x-pack/legacy/plugins/uptime/public/pages/__tests__/page_header.test.tsx
index 38d074cdb5dba..c1149834b4f59 100644
--- a/x-pack/legacy/plugins/uptime/public/pages/__tests__/page_header.test.tsx
+++ b/x-pack/legacy/plugins/uptime/public/pages/__tests__/page_header.test.tsx
@@ -6,141 +6,74 @@
import React from 'react';
import { Route } from 'react-router-dom';
-import { PageHeaderComponent } from '../page_header';
-import { mountWithRouter, renderWithRouter, shallowWithRouter } from '../../lib';
-import { MONITOR_ROUTE, OVERVIEW_ROUTE } from '../../../common/constants';
-import { Ping } from '../../../common/graphql/types';
-import { createMemoryHistory } from 'history';
+import { PageHeader, makeBaseBreadcrumb } from '../page_header';
+import { mountWithRouter, renderWithRouter } from '../../lib';
+import { OVERVIEW_ROUTE } from '../../../common/constants';
import { ChromeBreadcrumb } from 'kibana/public';
+import { KibanaContextProvider } from '../../../../../../../src/plugins/kibana_react/public';
+import { UptimeUrlParams, getSupportedUrlParams } from '../../lib/helper';
-describe('PageHeaderComponent', () => {
- const monitorStatus: Ping = {
- id: 'elastic-co',
- tcp: { rtt: { connect: { us: 174982 } } },
- http: {
- response: {
- body: {
- bytes: 2092041,
- hash: '5d970606a6be810ae5d37115c4807fdd07ba4c3e407924ee5297e172d2efb3dc',
- },
- status_code: 200,
- },
- rtt: {
- response_header: { us: 340175 },
- write_request: { us: 38 },
- validate: { us: 1797839 },
- content: { us: 1457663 },
- total: { us: 2030012 },
- },
- },
- monitor: {
- ip: '2a04:4e42:3::729',
- status: 'up',
- duration: { us: 2030035 },
- type: 'http',
- id: 'elastic-co',
- name: 'elastic',
- check_group: '2a017afa-4736-11ea-b3d0-acde48001122',
- },
- resolve: { ip: '2a04:4e42:3::729', rtt: { us: 2102 } },
- url: { port: 443, full: 'https://www.elastic.co', scheme: 'https', domain: 'www.elastic.co' },
- ecs: { version: '1.4.0' },
- tls: {
- certificate_not_valid_after: '2020-07-16T03:15:39.000Z',
- rtt: { handshake: { us: 57115 } },
- certificate_not_valid_before: '2019-08-16T01:40:25.000Z',
- },
- observer: {
- geo: { name: 'US-West', location: '37.422994, -122.083666' },
- },
- timestamp: '2020-02-04T10:07:42.142Z',
- };
-
- it('shallow renders expected elements for valid props', () => {
- const component = shallowWithRouter();
- expect(component).toMatchSnapshot();
- });
-
- it('renders expected elements for valid props', () => {
- const component = renderWithRouter();
- expect(component).toMatchSnapshot();
- });
+describe('PageHeader', () => {
+ const simpleBreadcrumbs: ChromeBreadcrumb[] = [
+ { text: 'TestCrumb1', href: '#testHref1' },
+ { text: 'TestCrumb2', href: '#testHref2' },
+ ];
- it('renders expected title for valid overview route', () => {
+ it('shallow renders with breadcrumbs and the date picker', () => {
const component = renderWithRouter(
-
-
-
+
);
- expect(component).toMatchSnapshot();
-
- const titleComponent = component.find('.euiTitle');
- expect(titleComponent.text()).toBe('Overview');
+ expect(component).toMatchSnapshot('page_header_with_date_picker');
});
- it('renders expected title for valid monitor route', () => {
- const history = createMemoryHistory({ initialEntries: ['/monitor/ZWxhc3RpYy1jbw=='] });
-
+ it('shallow renders with breadcrumbs without the date picker', () => {
const component = renderWithRouter(
-
-
- ,
- history
+
);
- expect(component).toMatchSnapshot();
-
- const titleComponent = component.find('.euiTitle');
- expect(titleComponent.text()).toBe('https://www.elastic.co');
+ expect(component).toMatchSnapshot('page_header_no_date_picker');
});
- it('mount expected page title for valid monitor route', () => {
- const history = createMemoryHistory({ initialEntries: ['/monitor/ZWxhc3RpYy1jbw=='] });
-
- const component = mountWithRouter(
-
-
- ,
- history
- );
- expect(component).toMatchSnapshot();
-
- const titleComponent = component.find('.euiTitle');
- expect(titleComponent.text()).toBe('https://www.elastic.co');
- expect(document.title).toBe('Uptime | elastic - Kibana');
- });
-
- it('mount and set expected breadcrumb for monitor route', () => {
- const history = createMemoryHistory({ initialEntries: ['/monitor/ZWxhc3RpYy1jbw=='] });
- let breadcrumbObj: ChromeBreadcrumb[] = [];
- const setBreadcrumb = (breadcrumbs: ChromeBreadcrumb[]) => {
- breadcrumbObj = breadcrumbs;
- };
-
+ it('sets the given breadcrumbs', () => {
+ const [getBreadcrumbs, core] = mockCore();
mountWithRouter(
-
-
- ,
- history
+
+
+
+
+
);
- expect(breadcrumbObj).toStrictEqual([
- { href: '#/?', text: 'Uptime' },
- { text: 'https://www.elastic.co' },
- ]);
- });
-
- it('mount and set expected breadcrumb for overview route', () => {
- let breadcrumbObj: ChromeBreadcrumb[] = [];
- const setBreadcrumb = (breadcrumbs: ChromeBreadcrumb[]) => {
- breadcrumbObj = breadcrumbs;
- };
-
- mountWithRouter(
-
-
-
+ const urlParams: UptimeUrlParams = getSupportedUrlParams({});
+ expect(getBreadcrumbs()).toStrictEqual(
+ [makeBaseBreadcrumb(urlParams)].concat(simpleBreadcrumbs)
);
-
- expect(breadcrumbObj).toStrictEqual([{ href: '#/', text: 'Uptime' }]);
});
});
+
+const mockCore: () => [() => ChromeBreadcrumb[], any] = () => {
+ let breadcrumbObj: ChromeBreadcrumb[] = [];
+ const get = () => {
+ return breadcrumbObj;
+ };
+ const core = {
+ chrome: {
+ setBreadcrumbs: (newBreadcrumbs: ChromeBreadcrumb[]) => {
+ breadcrumbObj = newBreadcrumbs;
+ },
+ },
+ };
+
+ return [get, core];
+};
diff --git a/x-pack/legacy/plugins/uptime/public/pages/monitor.tsx b/x-pack/legacy/plugins/uptime/public/pages/monitor.tsx
index 380cc041ae87e..8c608f57a9592 100644
--- a/x-pack/legacy/plugins/uptime/public/pages/monitor.tsx
+++ b/x-pack/legacy/plugins/uptime/public/pages/monitor.tsx
@@ -5,19 +5,45 @@
*/
import { EuiSpacer } from '@elastic/eui';
-import React, { useContext, useState } from 'react';
+import React, { useContext, useState, useEffect } from 'react';
import { useParams } from 'react-router-dom';
+import { ChromeBreadcrumb } from 'kibana/public';
+import { connect, MapDispatchToPropsFunction, MapStateToPropsParam } from 'react-redux';
import { MonitorCharts, PingList } from '../components/functional';
import { UptimeRefreshContext, UptimeThemeContext } from '../contexts';
import { useUptimeTelemetry, useUrlParams, UptimePage } from '../hooks';
import { useTrackPageview } from '../../../../../plugins/observability/public';
import { MonitorStatusDetails } from '../components/connected';
+import { Ping } from '../../common/graphql/types';
+import { AppState } from '../state';
+import { selectSelectedMonitor } from '../state/selectors';
+import { getSelectedMonitor } from '../state/actions';
+import { PageHeader } from './page_header';
-export const MonitorPage = () => {
+interface StateProps {
+ selectedMonitor: Ping | null;
+}
+
+interface DispatchProps {
+ dispatchGetMonitorStatus: (monitorId: string) => void;
+}
+
+type Props = StateProps & DispatchProps;
+
+export const MonitorPageComponent: React.FC = ({
+ selectedMonitor,
+ dispatchGetMonitorStatus,
+}: Props) => {
// decode 64 base string, it was decoded to make it a valid url, since monitor id can be a url
let { monitorId } = useParams();
monitorId = atob(monitorId || '');
+ useEffect(() => {
+ if (monitorId) {
+ dispatchGetMonitorStatus(monitorId);
+ }
+ }, [dispatchGetMonitorStatus, monitorId]);
+
const [pingListPageCount, setPingListPageCount] = useState(10);
const { colors } = useContext(UptimeThemeContext);
const { refreshApp } = useContext(UptimeRefreshContext);
@@ -39,8 +65,11 @@ export const MonitorPage = () => {
useTrackPageview({ app: 'uptime', path: 'monitor' });
useTrackPageview({ app: 'uptime', path: 'monitor', delay: 15000 });
+ const nameOrId = selectedMonitor?.monitor?.name || selectedMonitor?.monitor?.id || '';
+ const breadcrumbs: ChromeBreadcrumb[] = [{ text: nameOrId }];
return (
<>
+
@@ -65,3 +94,21 @@ export const MonitorPage = () => {
>
);
};
+
+const mapStateToProps: MapStateToPropsParam = state => ({
+ selectedMonitor: selectSelectedMonitor(state),
+});
+
+const mapDispatchToProps: MapDispatchToPropsFunction = (dispatch, own) => {
+ return {
+ dispatchGetMonitorStatus: (monitorId: string) => {
+ dispatch(
+ getSelectedMonitor({
+ monitorId,
+ })
+ );
+ },
+ };
+};
+
+export const MonitorPage = connect(mapStateToProps, mapDispatchToProps)(MonitorPageComponent);
diff --git a/x-pack/legacy/plugins/uptime/public/pages/overview.tsx b/x-pack/legacy/plugins/uptime/public/pages/overview.tsx
index cf3631eda042a..15e31d5e44629 100644
--- a/x-pack/legacy/plugins/uptime/public/pages/overview.tsx
+++ b/x-pack/legacy/plugins/uptime/public/pages/overview.tsx
@@ -7,6 +7,7 @@
import { EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui';
import React, { useContext, useEffect } from 'react';
import styled from 'styled-components';
+import { i18n } from '@kbn/i18n';
import {
EmptyState,
MonitorList,
@@ -20,6 +21,7 @@ import { DataPublicPluginSetup, IIndexPattern } from '../../../../../../src/plug
import { UptimeThemeContext } from '../contexts';
import { FilterGroup, KueryBar } from '../components/connected';
import { useUpdateKueryString } from '../hooks';
+import { PageHeader } from './page_header';
interface OverviewPageProps {
autocomplete: DataPublicPluginSetup['autocomplete'];
@@ -71,8 +73,14 @@ export const OverviewPageComponent = ({ autocomplete, indexPattern, setEsKueryFi
const linkParameters = stringifyUrlParams(params, true);
+ const heading = i18n.translate('xpack.uptime.overviewPage.headerText', {
+ defaultMessage: 'Overview',
+ description: `The text that will be displayed in the app's heading when the Overview page loads.`,
+ });
+
return (
<>
+
diff --git a/x-pack/legacy/plugins/uptime/public/pages/page_header.tsx b/x-pack/legacy/plugins/uptime/public/pages/page_header.tsx
index 5c051c491c6f5..b0fb2d0ed7869 100644
--- a/x-pack/legacy/plugins/uptime/public/pages/page_header.tsx
+++ b/x-pack/legacy/plugins/uptime/public/pages/page_header.tsx
@@ -4,75 +4,63 @@
* you may not use this file except in compliance with the Elastic License.
*/
+import React, { useEffect } from 'react';
+import { ChromeBreadcrumb } from 'kibana/public';
+import { EuiFlexGroup, EuiFlexItem, EuiTitle, EuiSpacer } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
-import React, { useEffect, useState } from 'react';
-import { useRouteMatch } from 'react-router-dom';
-import { EuiTitle, EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui';
import { UptimeDatePicker } from '../components/functional/uptime_date_picker';
-import { getMonitorPageBreadcrumb, getOverviewPageBreadcrumbs } from '../breadcrumbs';
+import { useKibana } from '../../../../../../src/plugins/kibana_react/public';
import { stringifyUrlParams } from '../lib/helper/stringify_url_params';
-import { getTitle } from '../lib/helper/get_title';
-import { UMUpdateBreadcrumbs } from '../lib/lib';
import { useUrlParams } from '../hooks';
-import { MONITOR_ROUTE } from '../../common/constants';
-import { Ping } from '../../common/graphql/types';
+import { UptimeUrlParams } from '../lib/helper';
interface PageHeaderProps {
- monitorStatus?: Ping;
- setBreadcrumbs: UMUpdateBreadcrumbs;
+ headingText: string;
+ breadcrumbs: ChromeBreadcrumb[];
+ datePicker: boolean;
}
-export const PageHeaderComponent = ({ monitorStatus, setBreadcrumbs }: PageHeaderProps) => {
- const monitorPage = useRouteMatch({
- path: MONITOR_ROUTE,
- });
-
- const [getUrlParams] = useUrlParams();
- const { absoluteDateRangeStart, absoluteDateRangeEnd, ...params } = getUrlParams();
-
- const headingText = !monitorPage
- ? i18n.translate('xpack.uptime.overviewPage.headerText', {
- defaultMessage: 'Overview',
- description: `The text that will be displayed in the app's heading when the Overview page loads.`,
- })
- : monitorStatus?.url?.full;
+export const makeBaseBreadcrumb = (params?: UptimeUrlParams): ChromeBreadcrumb => {
+ let href = '#/';
+ if (params) {
+ const crumbParams: Partial = { ...params };
+ // We don't want to encode this values because they are often set to Date.now(), the relative
+ // values in dateRangeStart are better for a URL.
+ delete crumbParams.absoluteDateRangeStart;
+ delete crumbParams.absoluteDateRangeEnd;
+ href += stringifyUrlParams(crumbParams, true);
+ }
+ return {
+ text: i18n.translate('xpack.uptime.breadcrumbs.overviewBreadcrumbText', {
+ defaultMessage: 'Uptime',
+ }),
+ href,
+ };
+};
- const [headerText, setHeaderText] = useState(headingText);
+export const PageHeader = ({ headingText, breadcrumbs, datePicker = true }: PageHeaderProps) => {
+ const setBreadcrumbs = useKibana().services.chrome?.setBreadcrumbs!;
+ const params = useUrlParams()[0]();
useEffect(() => {
- if (monitorPage) {
- setHeaderText(monitorStatus?.url?.full ?? '');
- if (monitorStatus?.monitor) {
- const { name, id } = monitorStatus.monitor;
- document.title = getTitle((name || id) ?? '');
- }
- } else {
- setHeaderText(headingText);
- document.title = getTitle();
- }
- }, [monitorStatus, monitorPage, setHeaderText, headingText]);
+ setBreadcrumbs([makeBaseBreadcrumb(params)].concat(breadcrumbs));
+ }, [breadcrumbs, params, setBreadcrumbs]);
- useEffect(() => {
- if (monitorPage) {
- if (headerText) {
- setBreadcrumbs(getMonitorPageBreadcrumb(headerText, stringifyUrlParams(params, true)));
- }
- } else {
- setBreadcrumbs(getOverviewPageBreadcrumbs());
- }
- }, [headerText, setBreadcrumbs, params, monitorPage]);
+ const datePickerComponent = datePicker ? (
+
+
+
+ ) : null;
return (
<>
- {headerText}
+ {headingText}
-
-
-
+ {datePickerComponent}
>
diff --git a/x-pack/legacy/plugins/uptime/public/uptime_app.tsx b/x-pack/legacy/plugins/uptime/public/uptime_app.tsx
index 66ff5ba7a58ee..427870797a206 100644
--- a/x-pack/legacy/plugins/uptime/public/uptime_app.tsx
+++ b/x-pack/legacy/plugins/uptime/public/uptime_app.tsx
@@ -13,7 +13,7 @@ import { BrowserRouter as Router } from 'react-router-dom';
import { I18nStart, ChromeBreadcrumb, CoreStart } from 'src/core/public';
import { PluginsSetup } from 'ui/new_platform/new_platform';
import { KibanaContextProvider } from '../../../../../src/plugins/kibana_react/public';
-import { UMGraphQLClient, UMUpdateBreadcrumbs, UMUpdateBadge } from './lib/lib';
+import { UMGraphQLClient, UMUpdateBadge } from './lib/lib';
import {
UptimeRefreshContextProvider,
UptimeSettingsContextProvider,
@@ -23,7 +23,6 @@ import { CommonlyUsedRange } from './components/functional/uptime_date_picker';
import { store } from './state';
import { setBasePath } from './state/actions';
import { PageRouter } from './routes';
-import { PageHeader } from './components/connected/pages/page_header_container';
export interface UptimeAppColors {
danger: string;
@@ -47,10 +46,10 @@ export interface UptimeAppProps {
kibanaBreadcrumbs: ChromeBreadcrumb[];
plugins: PluginsSetup;
routerBasename: string;
- setBreadcrumbs: UMUpdateBreadcrumbs;
setBadge: UMUpdateBadge;
renderGlobalHelpControls(): void;
commonlyUsedRanges: CommonlyUsedRange[];
+ setBreadcrumbs: (crumbs: ChromeBreadcrumb[]) => void;
}
const Application = (props: UptimeAppProps) => {
@@ -64,7 +63,6 @@ const Application = (props: UptimeAppProps) => {
plugins,
renderGlobalHelpControls,
routerBasename,
- setBreadcrumbs,
setBadge,
} = props;
@@ -100,7 +98,6 @@ const Application = (props: UptimeAppProps) => {
-